fix pargar bug
This commit is contained in:
@@ -5,6 +5,7 @@ namespace App\Services;
|
||||
use App\Models\Customer;
|
||||
use App\Models\Order;
|
||||
use App\Models\PargarSyncLog;
|
||||
use App\Models\Product;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
@@ -14,6 +15,17 @@ class PargarSyncService
|
||||
public const STATUS_SUCCESS = 'success';
|
||||
public const STATUS_FAILED = 'failed';
|
||||
|
||||
public const TYPE_CUSTOMER = 'customer';
|
||||
public const TYPE_ORDER = 'order';
|
||||
public const TYPE_MANDE = 'mande';
|
||||
public const TYPE_DOCUMENT = 'document';
|
||||
public const TYPE_WALLET_CASH = 'wallet_cash';
|
||||
public const TYPE_WALLET_GOLD = 'wallet_gold';
|
||||
|
||||
public const PAYMENT_CASH = 'cash';
|
||||
public const PAYMENT_MAIN_GOLD = 'main_gold';
|
||||
public const PAYMENT_OTHER_PRODUCT = 'other_product';
|
||||
|
||||
public function buildLog(mixed $response = null, ?string $extra = null): string
|
||||
{
|
||||
$parts = array_filter([
|
||||
@@ -93,7 +105,7 @@ class PargarSyncService
|
||||
{
|
||||
$existing = PargarSyncLog::query()
|
||||
->where('customer_id', $customer->id)
|
||||
->where('type', 'customer')
|
||||
->where('type', self::TYPE_CUSTOMER)
|
||||
->where('sync_status', self::STATUS_PENDING)
|
||||
->latest('id')
|
||||
->first();
|
||||
@@ -105,7 +117,7 @@ class PargarSyncService
|
||||
return PargarSyncLog::create([
|
||||
'customer_id' => $customer->id,
|
||||
'desc' => 'در انتظار دریافت توسط پرگار',
|
||||
'type' => 'customer',
|
||||
'type' => self::TYPE_CUSTOMER,
|
||||
'sync_status' => self::STATUS_PENDING,
|
||||
'data' => json_encode(['handler' => 'exportCustomer'], JSON_UNESCAPED_UNICODE),
|
||||
]);
|
||||
@@ -132,7 +144,84 @@ class PargarSyncService
|
||||
];
|
||||
}
|
||||
|
||||
public function recordTrade(?Order $order, bool $fromCart = false): ?PargarSyncLog
|
||||
/**
|
||||
* صف سند کیف برای سینک مانده پرگار با اپ.
|
||||
*
|
||||
* @param 'cash'|'gold' $kind
|
||||
* @param array{withdraw_id?:int|null,note?:string|null,product_id?:int|null,source?:string|null} $meta
|
||||
*/
|
||||
public function queueWalletDocument(
|
||||
Customer $customer,
|
||||
string $kind,
|
||||
float $signedAmount,
|
||||
array $meta = []
|
||||
): ?PargarSyncLog {
|
||||
if (! $this->isSyncEnabled() || ! $this->hasSyncTable()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (abs($signedAmount) < ($kind === 'cash' ? 1 : 0.01)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($kind === 'gold') {
|
||||
$productId = (int) ($meta['product_id'] ?? 0);
|
||||
if ($productId > 0 && ! app(ConfigService::class)->isMainWalletProduct($productId)) {
|
||||
return null;
|
||||
}
|
||||
} elseif ($kind !== 'cash') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$withdrawId = isset($meta['withdraw_id']) ? (int) $meta['withdraw_id'] : null;
|
||||
$type = $kind === 'cash' ? self::TYPE_WALLET_CASH : self::TYPE_WALLET_GOLD;
|
||||
|
||||
if ($withdrawId) {
|
||||
$existing = PargarSyncLog::query()
|
||||
->where('withdraw_id', $withdrawId)
|
||||
->where('type', $type)
|
||||
->latest('id')
|
||||
->first();
|
||||
if ($existing) {
|
||||
return $existing;
|
||||
}
|
||||
}
|
||||
|
||||
$isDeposit = $signedAmount > 0;
|
||||
if ($kind === 'cash') {
|
||||
$desc = $isDeposit ? 'واریز ریالی — ارسال به پرگار' : 'برداشت ریالی — ارسال به پرگار';
|
||||
} else {
|
||||
$desc = $isDeposit ? 'شارژ طلای کیف اصلی — ارسال به پرگار' : 'برداشت طلای کیف اصلی — ارسال به پرگار';
|
||||
}
|
||||
|
||||
return PargarSyncLog::create([
|
||||
'customer_id' => $customer->id,
|
||||
'amount' => abs($signedAmount),
|
||||
'desc' => $desc,
|
||||
'withdraw_id' => $withdrawId,
|
||||
'date' => now(),
|
||||
'type' => $type,
|
||||
'sync_status' => self::STATUS_PENDING,
|
||||
'data' => json_encode([
|
||||
'handler' => 'exportWallet',
|
||||
'kind' => $kind,
|
||||
'signed_amount' => $signedAmount,
|
||||
'note' => $meta['note'] ?? null,
|
||||
'product_id' => $meta['product_id'] ?? null,
|
||||
'source' => $meta['source'] ?? null,
|
||||
], JSON_UNESCAPED_UNICODE),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{
|
||||
* payment_kind?: string,
|
||||
* payment_product_id?: int|null,
|
||||
* product_id?: int|null,
|
||||
* number?: float|null
|
||||
* } $context
|
||||
*/
|
||||
public function recordTrade(?Order $order, bool $fromCart = false, array $context = []): ?PargarSyncLog
|
||||
{
|
||||
if (! $order || ! $order->id || ! $this->isSyncEnabled()) {
|
||||
return null;
|
||||
@@ -146,29 +235,123 @@ class PargarSyncService
|
||||
$direction = (int) ($order->direction ?? 0);
|
||||
$desc = \App\Http\Controllers\Controller::accountingShopTradeDesc($direction, $fromCart);
|
||||
|
||||
$paymentKind = $context['payment_kind']
|
||||
?? $this->inferPaymentKindFromContext($context);
|
||||
|
||||
$payload = [
|
||||
'handler' => 'exportOrder',
|
||||
'direction' => $direction,
|
||||
'price' => $order->price,
|
||||
'total_price' => $order->total_price,
|
||||
'payment_kind' => $paymentKind,
|
||||
'payment_product_id' => $context['payment_product_id'] ?? null,
|
||||
'product_id' => $context['product_id'] ?? $order->product_id ?? null,
|
||||
'number' => $context['number'] ?? null,
|
||||
'payment_gold' => $context['payment_gold'] ?? null,
|
||||
'from_cart' => $fromCart,
|
||||
];
|
||||
|
||||
// تهاتر بین دو محصول غیر اصلی — روی ریال/طلای پرگار اثر ندارد
|
||||
if ($paymentKind === self::PAYMENT_OTHER_PRODUCT) {
|
||||
$order->pargar_confirmed_at = now();
|
||||
$order->save();
|
||||
|
||||
return PargarSyncLog::create([
|
||||
'customer_id' => $order->customer_id,
|
||||
'amount' => $order->amount,
|
||||
'desc' => $desc . ' (تهاتر محصول — بدون سند ریال/طلای پرگار)',
|
||||
'order_id' => $order->id,
|
||||
'date' => $order->pay_at ?? $order->created_at,
|
||||
'type' => self::TYPE_ORDER,
|
||||
'sync_status' => self::STATUS_SUCCESS,
|
||||
'pargar_ref' => 'skip:barter',
|
||||
'data' => json_encode($payload, JSON_UNESCAPED_UNICODE),
|
||||
]);
|
||||
}
|
||||
|
||||
return PargarSyncLog::create([
|
||||
'customer_id' => $order->customer_id,
|
||||
'amount' => $order->amount,
|
||||
'desc' => $desc,
|
||||
'order_id' => $order->id,
|
||||
'date' => $order->pay_at ?? $order->created_at,
|
||||
'type' => 'order',
|
||||
'type' => self::TYPE_ORDER,
|
||||
'sync_status' => self::STATUS_PENDING,
|
||||
'data' => json_encode([
|
||||
'handler' => 'exportOrder',
|
||||
'direction' => $direction,
|
||||
'price' => $order->price,
|
||||
'total_price' => $order->total_price,
|
||||
], JSON_UNESCAPED_UNICODE),
|
||||
'data' => json_encode($payload, JSON_UNESCAPED_UNICODE),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{payment_kind?: string, payment_product_id?: int|null} $context
|
||||
*/
|
||||
public function inferPaymentKindFromContext(array $context): string
|
||||
{
|
||||
if (! empty($context['payment_kind'])) {
|
||||
return (string) $context['payment_kind'];
|
||||
}
|
||||
|
||||
$paymentProductId = (int) ($context['payment_product_id'] ?? 0);
|
||||
if ($paymentProductId <= 0) {
|
||||
return self::PAYMENT_CASH;
|
||||
}
|
||||
|
||||
return app(ConfigService::class)->isMainWalletProduct($paymentProductId)
|
||||
? self::PAYMENT_MAIN_GOLD
|
||||
: self::PAYMENT_OTHER_PRODUCT;
|
||||
}
|
||||
|
||||
public function confirmOrders(array $orderIds): array
|
||||
{
|
||||
$confirmed = 0;
|
||||
|
||||
foreach ($orderIds as $orderId) {
|
||||
$order = Order::find($orderId);
|
||||
$id = trim((string) $orderId);
|
||||
if ($id === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (str_starts_with(strtoupper($id), 'W-')) {
|
||||
$withdrawId = (int) substr($id, 2);
|
||||
if ($withdrawId <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$log = PargarSyncLog::query()
|
||||
->where('withdraw_id', $withdrawId)
|
||||
->whereIn('type', [self::TYPE_WALLET_CASH, self::TYPE_WALLET_GOLD])
|
||||
->where('sync_status', self::STATUS_PENDING)
|
||||
->latest('id')
|
||||
->first();
|
||||
|
||||
if ($log) {
|
||||
$this->markSuccess($log, $id, ['OrderId' => $id]);
|
||||
$confirmed++;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (str_starts_with(strtoupper($id), 'WLOG-')) {
|
||||
$logId = (int) substr($id, 5);
|
||||
if ($logId <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$log = PargarSyncLog::query()
|
||||
->where('id', $logId)
|
||||
->whereIn('type', [self::TYPE_WALLET_CASH, self::TYPE_WALLET_GOLD])
|
||||
->where('sync_status', self::STATUS_PENDING)
|
||||
->first();
|
||||
|
||||
if ($log) {
|
||||
$this->markSuccess($log, $id, ['OrderId' => $id]);
|
||||
$confirmed++;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$order = Order::find($id);
|
||||
if (! $order) {
|
||||
continue;
|
||||
}
|
||||
@@ -227,6 +410,21 @@ class PargarSyncService
|
||||
];
|
||||
}
|
||||
|
||||
if ($handler === 'exportWallet') {
|
||||
PargarSyncLog::where('id', $log->id)->update([
|
||||
'sync_status' => self::STATUS_PENDING,
|
||||
'sync_log' => null,
|
||||
'pargar_ref' => null,
|
||||
]);
|
||||
$log->refresh();
|
||||
|
||||
return [
|
||||
'ok' => true,
|
||||
'message' => 'سند کیف دوباره در صف ارسال به پرگار قرار گرفت',
|
||||
'pargar' => $log,
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'ok' => false,
|
||||
'message' => $log->sync_log ?: 'ارسال مجدد به پرگار ناموفق بود',
|
||||
@@ -240,11 +438,15 @@ class PargarSyncService
|
||||
return 'exportOrder';
|
||||
}
|
||||
|
||||
if ($log->type === 'customer') {
|
||||
if ($log->type === self::TYPE_CUSTOMER) {
|
||||
return 'exportCustomer';
|
||||
}
|
||||
|
||||
if ($log->type === 'mande') {
|
||||
if (in_array($log->type, [self::TYPE_WALLET_CASH, self::TYPE_WALLET_GOLD], true)) {
|
||||
return 'exportWallet';
|
||||
}
|
||||
|
||||
if ($log->type === self::TYPE_MANDE) {
|
||||
return 'importMande';
|
||||
}
|
||||
|
||||
@@ -264,4 +466,37 @@ class PargarSyncService
|
||||
{
|
||||
return Schema::hasTable('pargar_sync_logs');
|
||||
}
|
||||
|
||||
public function pargarItemIdRial(): int
|
||||
{
|
||||
$raw = trim(app(ConfigService::class)->getString('pargar_item_id_rial', '0'));
|
||||
|
||||
return max(0, (int) $raw);
|
||||
}
|
||||
|
||||
public function pargarItemIdGold(): int
|
||||
{
|
||||
$raw = trim(app(ConfigService::class)->getString('pargar_item_id_gold', '11'));
|
||||
$id = (int) $raw;
|
||||
|
||||
return $id > 0 ? $id : 11;
|
||||
}
|
||||
|
||||
public function mainWalletGoldItemName(): string
|
||||
{
|
||||
$product = app(ConfigService::class)->mainWalletRepresentativeProduct();
|
||||
$title = trim((string) ($product?->title ?? ''));
|
||||
|
||||
return $title !== '' ? $title : 'آبشده';
|
||||
}
|
||||
|
||||
public function resolveOrderProduct(?Order $order, ?array $payload = null): ?Product
|
||||
{
|
||||
$productId = (int) ($payload['product_id'] ?? $order?->product_id ?? 0);
|
||||
if ($productId <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Product::find($productId);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user