feat(accounting): document colleague trades on configured accounts

Post Montzar-covered buy/sell to Zarin/Tahesab/Pargar using montzar_account_* settings, and harden public storage URL/MIME handling for uploads.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-26 16:59:27 +03:30
co-authored by Cursor
parent ad78545ebd
commit 885ed33e6e
10 changed files with 457 additions and 34 deletions
@@ -198,6 +198,25 @@ class PargarInboundController extends Controller
}
}
$colleagueLogs = PargarSyncLog::query()
->where('type', PargarSyncService::TYPE_ORDER)
->where('sync_status', PargarSyncService::STATUS_PENDING)
->where('data', 'like', '%"colleague_leg":true%')
->orderBy('id')
->limit(100)
->get();
foreach ($colleagueLogs as $log) {
$order = Order::find((int) ($log->order_id ?? 0));
if (! $order) {
continue;
}
$payload = $this->orderExportPayload($order, $log);
if ($payload !== null) {
$documents->push($payload);
}
}
return response()->json([
'state' => 'true',
'msg' => '',
@@ -583,12 +602,23 @@ class PargarInboundController extends Controller
/**
* @return array<string, mixed>|null
*/
private function orderExportPayload(Order $order): ?array
private function orderExportPayload(Order $order, ?PargarSyncLog $forcedLog = null): ?array
{
$sync = $this->sync();
$log = PargarSyncLog::where('order_id', $order->id)->latest('id')->first();
$log = $forcedLog ?? PargarSyncLog::where('order_id', $order->id)
->where(function ($q) {
$q->whereNull('data')
->orWhere('data', 'not like', '%"colleague_leg":true%');
})
->latest('id')
->first();
$payload = $log ? (json_decode((string) $log->data, true) ?: []) : [];
// اگر لاگ اجباری همکار نیست و لاگ مشتری نبود، سند مشتری نساز
if ($forcedLog === null && $log && ! empty($payload['colleague_leg'])) {
return null;
}
$paymentKind = (string) ($payload['payment_kind'] ?? PargarSyncService::PAYMENT_CASH);
if ($paymentKind === PargarSyncService::PAYMENT_OTHER_PRODUCT) {
return null;
@@ -602,6 +632,8 @@ class PargarInboundController extends Controller
$isCustomerBuy = (int) ($order->direction ?? 1) === 1;
$customerDirection = (int) ($order->direction ?? 0);
$fromCart = (bool) ($payload['from_cart'] ?? $this->isCartOrder($order));
$isColleagueLeg = ! empty($payload['colleague_leg']);
$colleagueAccountId = trim((string) ($payload['colleague_account_id'] ?? ''));
$product = $sync->resolveOrderProduct($order, $payload);
$number = (float) ($payload['number'] ?? 0);
@@ -609,6 +641,22 @@ class PargarInboundController extends Controller
$totalPrice = (float) ($order->total_price ?? $order->payment_amount ?? 0);
$unitPrice = (float) ($order->price ?? 0);
if ($isColleagueLeg) {
if (isset($payload['direction'])) {
$isCustomerBuy = (int) $payload['direction'] === 1;
$customerDirection = (int) $payload['direction'];
}
if (isset($payload['total_price'])) {
$totalPrice = (float) $payload['total_price'];
}
if (isset($payload['price'])) {
$unitPrice = (float) $payload['price'];
}
if (isset($payload['amount'])) {
$amount = abs((float) $payload['amount']);
}
}
$isCountBased = $product
? self::isCountBasedProduct(self::productUnitPayload($product))
: false;
@@ -660,11 +708,19 @@ class PargarInboundController extends Controller
$totalPrice = 0;
}
$accountId = $isColleagueLeg && $colleagueAccountId !== ''
? (int) $colleagueAccountId
: (int) ($customer->pargar_account_id ?? 0);
$description = $isColleagueLeg
? (((int) ($payload['direction'] ?? $customerDirection) === 1) ? 'خرید از اپلیکیشن همکار' : 'فروش از اپلیکیشن همکار')
: self::accountingShopTradeDesc($customerDirection, $fromCart);
return [
'OrderId' => (string) $order->id,
'OrderId' => $isColleagueLeg ? ((string) $order->id).'-C' : (string) $order->id,
'OrderType' => $isCustomerBuy ? -1 : 1,
'PriceType' => 1,
'CustomerAccountId' => (int) ($customer->pargar_account_id ?? 0),
'CustomerAccountId' => $accountId,
'ItemId' => $itemId,
'ItemName' => $itemName,
'OrderDate' => $order->pay_at
@@ -675,7 +731,7 @@ class PargarInboundController extends Controller
'Weight' => $weight,
'Price' => $totalPrice,
'Carat' => 750,
'Description' => self::accountingShopTradeDesc($customerDirection, $fromCart),
'Description' => $description,
];
}