fix pargar bug
This commit is contained in:
@@ -8,13 +8,11 @@ use App\Models\Cart;
|
||||
use App\Models\Customer;
|
||||
use App\Models\Order;
|
||||
use App\Models\PargarSyncLog;
|
||||
use App\Models\Product;
|
||||
use App\Services\ConfigService;
|
||||
use App\Services\PargarSyncService;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Morilog\Jalali\Jalalian;
|
||||
use Rooyesh\Wallet\interfaces\TransactionInterface;
|
||||
use Rooyesh\Wallet\interfaces\WalletInterface;
|
||||
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
|
||||
|
||||
@@ -164,44 +162,41 @@ class PargarInboundController extends Controller
|
||||
|
||||
public function listOrders(Request $request)
|
||||
{
|
||||
$documents = collect();
|
||||
|
||||
$orders = Order::query()
|
||||
->where('sts', 2)
|
||||
->whereNull('pargar_confirmed_at')
|
||||
->limit(100)
|
||||
->get();
|
||||
|
||||
$documents = $orders->map(function (Order $order) {
|
||||
$customer = Customer::find((int) ($order->customer_id ?? 0));
|
||||
foreach ($orders as $order) {
|
||||
$payload = $this->orderExportPayload($order);
|
||||
if ($payload === null) {
|
||||
continue;
|
||||
}
|
||||
$documents->push($payload);
|
||||
}
|
||||
|
||||
// direction اپ: 1=خرید مشتری، 2=فروش مشتری
|
||||
// OrderType پرگار از دید فروشگاه است: خرید مشتری = فروش فروشگاه (-1)، فروش مشتری = خرید فروشگاه (1)
|
||||
$isCustomerBuy = (int) ($order->direction ?? 1) === 1;
|
||||
$customerDirection = (int) ($order->direction ?? 0);
|
||||
$walletLogs = PargarSyncLog::query()
|
||||
->whereIn('type', [PargarSyncService::TYPE_WALLET_CASH, PargarSyncService::TYPE_WALLET_GOLD])
|
||||
->where('sync_status', PargarSyncService::STATUS_PENDING)
|
||||
->orderBy('id')
|
||||
->limit(100)
|
||||
->get();
|
||||
|
||||
return [
|
||||
'OrderId' => (string) $order->id,
|
||||
'OrderType' => $isCustomerBuy ? -1 : 1,
|
||||
'PriceType' => 1,
|
||||
'CustomerAccountId' => (int) ($customer->pargar_account_id ?? 0),
|
||||
'ItemId' => 11,
|
||||
'ItemName' => $this->pargarItemName($order),
|
||||
'OrderDate' => $order->pay_at
|
||||
? Jalalian::fromDateTime($order->pay_at)->format('Y/m/d-H:i:s')
|
||||
: Jalalian::fromDateTime($order->created_at)->format('Y/m/d-H:i:s'),
|
||||
'Fee' => (float) ($order->price ?? 0),
|
||||
'Count' => 1,
|
||||
'Weight' => (float) ($order->amount ?? 0),
|
||||
'Price' => (float) ($order->total_price ?? 0),
|
||||
'Carat' => 750,
|
||||
'Description' => self::accountingShopTradeDesc($customerDirection, $this->isCartOrder($order)),
|
||||
];
|
||||
})->values();
|
||||
foreach ($walletLogs as $log) {
|
||||
$payload = $this->walletExportPayload($log);
|
||||
if ($payload !== null) {
|
||||
$documents->push($payload);
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'state' => 'true',
|
||||
'msg' => '',
|
||||
'data' => [
|
||||
'documents' => $documents,
|
||||
'documents' => $documents->values(),
|
||||
'duplicated' => 'false',
|
||||
'result' => 'OK',
|
||||
],
|
||||
@@ -242,7 +237,7 @@ class PargarInboundController extends Controller
|
||||
PargarSyncLog::create([
|
||||
'customer_id' => $customer?->id,
|
||||
'desc' => 'دریافت اسناد از پرگار',
|
||||
'type' => 'document',
|
||||
'type' => PargarSyncService::TYPE_DOCUMENT,
|
||||
'sync_status' => PargarSyncService::STATUS_SUCCESS,
|
||||
'pargar_ref' => $accountId,
|
||||
'data' => json_encode($data, JSON_UNESCAPED_UNICODE),
|
||||
@@ -272,33 +267,35 @@ class PargarInboundController extends Controller
|
||||
$goldInv = isset($data['GoldInv']) ? (float) str_replace('/', '.', (string) $data['GoldInv']) : 0;
|
||||
$rialInv = isset($data['RialInv']) ? (float) str_replace('/', '.', (string) $data['RialInv']) : 0;
|
||||
|
||||
// خواندن و نوشتن روی همان کیف اصلی مشتری — نه first() تصادفی
|
||||
// فقط مقایسه برای لاگ — اپ source of truth است؛ کیف را از مانده پرگار عوض نکن
|
||||
$ownerType = (int) ($customer->type ?? 2);
|
||||
$walletInterface = new WalletInterface($customer->id, $ownerType);
|
||||
$wallet = $walletInterface->wallet;
|
||||
|
||||
$goldDiff = $goldInv - (float) ($wallet->gold ?? 0);
|
||||
$rialDiff = $rialInv - (float) ($wallet->cash ?? 0);
|
||||
$appGold = (float) ($wallet->gold ?? 0);
|
||||
$appCash = (float) ($wallet->cash ?? 0);
|
||||
$goldDiff = $goldInv - $appGold;
|
||||
$rialDiff = $rialInv - $appCash;
|
||||
$hasDiff = abs($goldDiff) >= 0.01 || abs($rialDiff) >= 1;
|
||||
|
||||
if (abs($goldDiff) >= 0.01 || abs($rialDiff) >= 1) {
|
||||
new TransactionInterface($walletInterface, [
|
||||
'cash' => $rialDiff,
|
||||
'gold' => $goldDiff,
|
||||
'title' => 'تعدیل حسابداری پرگار',
|
||||
'expire_at' => now(),
|
||||
'active' => true,
|
||||
'start_at' => now(),
|
||||
], 22, $goldDiff > 0, $rialDiff > 0);
|
||||
}
|
||||
$desc = $hasDiff
|
||||
? 'اختلاف مانده پرگار با اپ — کیف اپ دست نخورده'
|
||||
: 'دریافت مانده از پرگار — بدون اختلاف';
|
||||
|
||||
PargarSyncLog::create([
|
||||
'customer_id' => $customer->id,
|
||||
'desc' => 'دریافت مانده از پرگار',
|
||||
'type' => 'mande',
|
||||
'desc' => $desc,
|
||||
'type' => PargarSyncService::TYPE_MANDE,
|
||||
'amount' => $goldInv,
|
||||
'sync_status' => PargarSyncService::STATUS_SUCCESS,
|
||||
'pargar_ref' => $accountId,
|
||||
'data' => json_encode($data, JSON_UNESCAPED_UNICODE),
|
||||
'data' => json_encode(array_merge($data, [
|
||||
'app_gold' => $appGold,
|
||||
'app_cash' => $appCash,
|
||||
'gold_diff' => $goldDiff,
|
||||
'rial_diff' => $rialDiff,
|
||||
'wallet_adjusted' => false,
|
||||
]), JSON_UNESCAPED_UNICODE),
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
@@ -495,4 +492,162 @@ class PargarInboundController extends Controller
|
||||
->whereIn('desc', ['سبد خرید', 'فروش سبد به مشتری'])
|
||||
->exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>|null
|
||||
*/
|
||||
private function orderExportPayload(Order $order): ?array
|
||||
{
|
||||
$sync = $this->sync();
|
||||
$log = PargarSyncLog::where('order_id', $order->id)->latest('id')->first();
|
||||
$payload = $log ? (json_decode((string) $log->data, true) ?: []) : [];
|
||||
|
||||
$paymentKind = (string) ($payload['payment_kind'] ?? PargarSyncService::PAYMENT_CASH);
|
||||
if ($paymentKind === PargarSyncService::PAYMENT_OTHER_PRODUCT) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($log && is_string($log->pargar_ref) && str_starts_with($log->pargar_ref, 'skip:')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$customer = Customer::find((int) ($order->customer_id ?? 0));
|
||||
$isCustomerBuy = (int) ($order->direction ?? 1) === 1;
|
||||
$customerDirection = (int) ($order->direction ?? 0);
|
||||
$fromCart = (bool) ($payload['from_cart'] ?? $this->isCartOrder($order));
|
||||
|
||||
$product = $sync->resolveOrderProduct($order, $payload);
|
||||
$number = (float) ($payload['number'] ?? 0);
|
||||
$amount = (float) ($order->amount ?? 0);
|
||||
$totalPrice = (float) ($order->total_price ?? $order->payment_amount ?? 0);
|
||||
$unitPrice = (float) ($order->price ?? 0);
|
||||
|
||||
$isCountBased = $product
|
||||
? self::isCountBasedProduct(self::productUnitPayload($product))
|
||||
: false;
|
||||
|
||||
$count = 1;
|
||||
$weight = $amount;
|
||||
if ($isCountBased && $number > 0) {
|
||||
$count = max(1, (int) round($number));
|
||||
$weight = $amount;
|
||||
} elseif ($number > 0 && abs($number - $amount) > 0.0001) {
|
||||
$count = max(1, (int) round($number));
|
||||
}
|
||||
|
||||
$itemId = $sync->pargarItemIdGold();
|
||||
$itemName = $this->pargarItemName($order);
|
||||
if ($product && trim((string) $product->title) !== '') {
|
||||
$itemName = trim((string) $product->title);
|
||||
}
|
||||
|
||||
$tradedProductId = (int) ($payload['product_id'] ?? $order->product_id ?? 0);
|
||||
$tradesMainGold = $tradedProductId <= 0
|
||||
|| app(ConfigService::class)->isMainWalletProduct($tradedProductId);
|
||||
|
||||
// اثر مانده از روش پرداخت؛ وزن طلا فقط وقتی کالای معامله یا پرداخت به کیف اصلی مربوط است
|
||||
if ($paymentKind === PargarSyncService::PAYMENT_CASH) {
|
||||
if ($tradesMainGold) {
|
||||
// خرید/فروش آبشده کیفاصلی با نقدی: وزن + مبلغ
|
||||
$itemId = $sync->pargarItemIdGold();
|
||||
} else {
|
||||
// محصول غیر اصلی با پرداخت نقدی: فقط ریال
|
||||
$rialItemId = $sync->pargarItemIdRial();
|
||||
$itemId = $rialItemId > 0 ? $rialItemId : $sync->pargarItemIdGold();
|
||||
$weight = 0;
|
||||
$count = 1;
|
||||
}
|
||||
} elseif ($paymentKind === PargarSyncService::PAYMENT_MAIN_GOLD) {
|
||||
$itemId = $sync->pargarItemIdGold();
|
||||
$itemName = $sync->mainWalletGoldItemName();
|
||||
$paymentGold = (float) ($payload['payment_gold'] ?? $amount);
|
||||
$weight = abs($paymentGold);
|
||||
$totalPrice = 0;
|
||||
}
|
||||
|
||||
return [
|
||||
'OrderId' => (string) $order->id,
|
||||
'OrderType' => $isCustomerBuy ? -1 : 1,
|
||||
'PriceType' => 1,
|
||||
'CustomerAccountId' => (int) ($customer->pargar_account_id ?? 0),
|
||||
'ItemId' => $itemId,
|
||||
'ItemName' => $itemName,
|
||||
'OrderDate' => $order->pay_at
|
||||
? Jalalian::fromDateTime($order->pay_at)->format('Y/m/d-H:i:s')
|
||||
: Jalalian::fromDateTime($order->created_at)->format('Y/m/d-H:i:s'),
|
||||
'Fee' => $unitPrice,
|
||||
'Count' => $count,
|
||||
'Weight' => $weight,
|
||||
'Price' => $totalPrice,
|
||||
'Carat' => 750,
|
||||
'Description' => self::accountingShopTradeDesc($customerDirection, $fromCart),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>|null
|
||||
*/
|
||||
private function walletExportPayload(PargarSyncLog $log): ?array
|
||||
{
|
||||
$sync = $this->sync();
|
||||
$payload = json_decode((string) $log->data, true) ?: [];
|
||||
$kind = (string) ($payload['kind'] ?? ($log->type === PargarSyncService::TYPE_WALLET_GOLD ? 'gold' : 'cash'));
|
||||
$signed = (float) ($payload['signed_amount'] ?? $log->amount ?? 0);
|
||||
if (abs($signed) < ($kind === 'cash' ? 1 : 0.01)) {
|
||||
$signed = (float) ($log->amount ?? 0);
|
||||
// اگر علامت نبود، از desc حدس بزن — پیشفرض واریز مثبت
|
||||
if (! isset($payload['signed_amount']) && is_string($log->desc) && str_contains($log->desc, 'برداشت')) {
|
||||
$signed = -abs($signed);
|
||||
} elseif (! isset($payload['signed_amount'])) {
|
||||
$signed = abs($signed);
|
||||
}
|
||||
}
|
||||
|
||||
$customer = Customer::find((int) ($log->customer_id ?? 0));
|
||||
$withdrawId = (int) ($log->withdraw_id ?? 0);
|
||||
$orderId = $withdrawId > 0 ? 'W-' . $withdrawId : 'WLOG-' . $log->id;
|
||||
|
||||
$isDeposit = $signed >= 0;
|
||||
// OrderType از دید فروشگاه: واریز به مشتری = فروشگاه بدهکار؟ قرارداد قبلی خرید مشتری = -1
|
||||
// واریز ریالی مشتری ≈ افزایش بدهی فروشگاه به مشتری از نظر حساب → مشابه خرید نیست؛
|
||||
// برای واریز: OrderType=1 (ورود وجه به حساب مشتری در پرگار بسته به نرمافزار)
|
||||
// همراستا با آذین: اسناد کیف را با OrderType بر اساس علامت میفرستیم
|
||||
$orderType = $isDeposit ? 1 : -1;
|
||||
|
||||
if ($kind === 'gold') {
|
||||
return [
|
||||
'OrderId' => $orderId,
|
||||
'OrderType' => $orderType,
|
||||
'PriceType' => 1,
|
||||
'CustomerAccountId' => (int) ($customer->pargar_account_id ?? 0),
|
||||
'ItemId' => $sync->pargarItemIdGold(),
|
||||
'ItemName' => $sync->mainWalletGoldItemName(),
|
||||
'OrderDate' => Jalalian::fromDateTime($log->date ?? $log->created_at)->format('Y/m/d-H:i:s'),
|
||||
'Fee' => 0,
|
||||
'Count' => 1,
|
||||
'Weight' => abs($signed),
|
||||
'Price' => 0,
|
||||
'Carat' => 750,
|
||||
'Description' => $isDeposit ? 'شارژ طلای کیف اصلی' : 'برداشت طلای کیف اصلی',
|
||||
];
|
||||
}
|
||||
|
||||
$rialItemId = $sync->pargarItemIdRial();
|
||||
|
||||
return [
|
||||
'OrderId' => $orderId,
|
||||
'OrderType' => $orderType,
|
||||
'PriceType' => 1,
|
||||
'CustomerAccountId' => (int) ($customer->pargar_account_id ?? 0),
|
||||
'ItemId' => $rialItemId > 0 ? $rialItemId : $sync->pargarItemIdGold(),
|
||||
'ItemName' => $isDeposit ? 'واریز ریالی' : 'برداشت ریالی',
|
||||
'OrderDate' => Jalalian::fromDateTime($log->date ?? $log->created_at)->format('Y/m/d-H:i:s'),
|
||||
'Fee' => 0,
|
||||
'Count' => 1,
|
||||
'Weight' => 0,
|
||||
'Price' => abs($signed),
|
||||
'Carat' => 750,
|
||||
'Description' => $isDeposit ? 'واریز ریالی' : 'برداشت ریالی',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user