fix(tahesab): register unlinked customers before sending documents
File cache cannot use Cache::lock, so docs for customers without a code always failed. Register first, put the customer name on the sanad, and surface the real error. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1004,21 +1004,22 @@ class TahesabController extends Controller
|
||||
$isColleagueLeg = ! empty($data['colleague_leg']) && $accountOverride !== '';
|
||||
|
||||
if (! $isColleagueLeg) {
|
||||
if ($customer && ($customer->moshtari_code === null)) {
|
||||
$this->createCustomerInTahesab($customer->id);
|
||||
$customer = Customer::where('id', $data['customer_id'])->first();
|
||||
$ensured = $this->ensureCustomerHasTahesabCode($customer);
|
||||
if (! ($ensured['ok'] ?? false)) {
|
||||
return $ensured['message'] ?? 'مشتری کد تهحساب ندارد';
|
||||
}
|
||||
$customer = $ensured['customer'];
|
||||
}
|
||||
|
||||
if (! $customer) {
|
||||
return false;
|
||||
return 'مشتری سند پیدا نشد';
|
||||
}
|
||||
|
||||
$hesabCode = $isColleagueLeg
|
||||
? (int) $accountOverride
|
||||
: (int) ($customer->moshtari_code ?? 0);
|
||||
if ($hesabCode <= 0) {
|
||||
return false;
|
||||
return 'مشتری کد تهحساب ندارد';
|
||||
}
|
||||
|
||||
$kind = $mapper->resolveKind($product);
|
||||
@@ -1056,6 +1057,7 @@ class TahesabController extends Controller
|
||||
if ($sharh === '') {
|
||||
$sharh = trim($title !== '' ? "{$action} {$title}" : "{$action} {$kindFa}");
|
||||
}
|
||||
$sharh = $this->sharhWithCustomer($sharh, $customer);
|
||||
|
||||
$orderId = is_object($data['order'] ?? null)
|
||||
? ($data['order']->id ?? null)
|
||||
@@ -1138,14 +1140,17 @@ class TahesabController extends Controller
|
||||
// throw new UnprocessableEntityHttpException("Auth needed");
|
||||
// }
|
||||
$customer = Customer::where('id', $data['customer_id'])->first();
|
||||
|
||||
if ($customer && ($customer->moshtari_code === null)) {
|
||||
$this->createCustomerInTahesab($customer->id);
|
||||
$customer = Customer::where('id', $data['customer_id'])->first();
|
||||
$ensured = $this->ensureCustomerHasTahesabCode($customer);
|
||||
if (! ($ensured['ok'] ?? false)) {
|
||||
return $ensured['message'] ?? 'مشتری کد تهحساب ندارد';
|
||||
}
|
||||
$customer = $ensured['customer'];
|
||||
$data['handler'] = 'wallet';
|
||||
$isDeposit = (int) ($data['direction'] ?? 0) === 0;
|
||||
$sharh = self::accountingWalletDesc($isDeposit, $data['note'] ?? null);
|
||||
$sharh = $this->sharhWithCustomer(
|
||||
self::accountingWalletDesc($isDeposit, $data['note'] ?? null),
|
||||
$customer
|
||||
);
|
||||
$tahesab = $existing ?? Tahesab::create([
|
||||
"customer_id" => $customer->id,
|
||||
"desc" => $sharh,
|
||||
@@ -1327,17 +1332,17 @@ class TahesabController extends Controller
|
||||
}
|
||||
|
||||
$customer = Customer::where('id', $data['customer_id'])->first();
|
||||
if (!$customer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($customer->moshtari_code === null) {
|
||||
$this->createCustomerInTahesab($customer->id);
|
||||
$customer = Customer::where('id', $data['customer_id'])->first();
|
||||
$ensured = $this->ensureCustomerHasTahesabCode($customer);
|
||||
if (! ($ensured['ok'] ?? false)) {
|
||||
return $ensured['message'] ?? 'مشتری کد تهحساب ندارد';
|
||||
}
|
||||
$customer = $ensured['customer'];
|
||||
|
||||
$amount = abs((float) $data['value']);
|
||||
$desc = !empty($data['desc']) ? (string) $data['desc'] : 'پاداش';
|
||||
$desc = $this->sharhWithCustomer(
|
||||
! empty($data['desc']) ? (string) $data['desc'] : 'پاداش',
|
||||
$customer
|
||||
);
|
||||
|
||||
$data['handler'] = 'goldReward';
|
||||
$tahesab = $existing ?? Tahesab::create([
|
||||
@@ -1432,11 +1437,11 @@ class TahesabController extends Controller
|
||||
}
|
||||
|
||||
$customer = Customer::where('id', $data['customer_id'])->first();
|
||||
|
||||
if ($customer && ($customer->moshtari_code === null)) {
|
||||
$this->createCustomerInTahesab($customer->id);
|
||||
$customer = Customer::where('id', $data['customer_id'])->first();
|
||||
$ensured = $this->ensureCustomerHasTahesabCode($customer);
|
||||
if (! ($ensured['ok'] ?? false)) {
|
||||
return $ensured['message'] ?? 'مشتری کد تهحساب ندارد';
|
||||
}
|
||||
$customer = $ensured['customer'];
|
||||
|
||||
$kind = $mapper->resolveKind($product);
|
||||
$rawValue = (float) $data['value'];
|
||||
@@ -1447,9 +1452,12 @@ class TahesabController extends Controller
|
||||
$isDeposit = (int) ($data['direction'] ?? 1) === 1;
|
||||
$isVorood = $isDeposit ? 1 : 0;
|
||||
|
||||
$sharh = self::accountingWalletDesc(
|
||||
$isDeposit,
|
||||
!empty($data['note']) ? (string) $data['note'] : (!empty($data['desc']) ? (string) $data['desc'] : null)
|
||||
$sharh = $this->sharhWithCustomer(
|
||||
self::accountingWalletDesc(
|
||||
$isDeposit,
|
||||
! empty($data['note']) ? (string) $data['note'] : (! empty($data['desc']) ? (string) $data['desc'] : null)
|
||||
),
|
||||
$customer
|
||||
);
|
||||
$data['note'] = $sharh;
|
||||
$data['handler'] = 'walletGold';
|
||||
@@ -1643,18 +1651,49 @@ class TahesabController extends Controller
|
||||
];
|
||||
}
|
||||
|
||||
private function ensureCustomerHasTahesabCode(?Customer $customer): array
|
||||
{
|
||||
if (! $customer) {
|
||||
return ['ok' => false, 'message' => 'مشتری سند پیدا نشد'];
|
||||
}
|
||||
if ((int) ($customer->moshtari_code ?? 0) > 0) {
|
||||
return ['ok' => true, 'customer' => $customer];
|
||||
}
|
||||
|
||||
$reg = $this->createCustomerInTahesab($customer->id);
|
||||
$customer->refresh();
|
||||
if ((int) ($customer->moshtari_code ?? 0) > 0) {
|
||||
return ['ok' => true, 'customer' => $customer];
|
||||
}
|
||||
|
||||
$message = is_string($reg) && $reg !== ''
|
||||
? $reg
|
||||
: 'ثبت مشتری در تهحساب ناموفق بود';
|
||||
|
||||
return ['ok' => false, 'message' => $message];
|
||||
}
|
||||
|
||||
private function sharhWithCustomer(string $sharh, Customer $customer): string
|
||||
{
|
||||
$name = trim((string) ($customer->name ?? ''));
|
||||
if ($name === '' || str_contains($sharh, $name)) {
|
||||
return $sharh;
|
||||
}
|
||||
|
||||
return trim($sharh.' — '.$name);
|
||||
}
|
||||
|
||||
public function createCustomerInTahesab($customer_id)
|
||||
{
|
||||
$customer = Customer::findOrFail($customer_id);
|
||||
$response = null;
|
||||
|
||||
if ($customer->moshtari_code == null) {
|
||||
$lock = Cache::lock('tahesab:register-customer:'.$customer->id, 30);
|
||||
|
||||
if (! $lock->get()) {
|
||||
if ((int) ($customer->moshtari_code ?? 0) <= 0) {
|
||||
$lockKey = 'tahesab:register-customer:'.$customer->id;
|
||||
if (! Cache::add($lockKey, 1, 30)) {
|
||||
$customer->refresh();
|
||||
|
||||
if ($customer->moshtari_code != null) {
|
||||
if ((int) ($customer->moshtari_code ?? 0) > 0) {
|
||||
return $customer->moshtari_code;
|
||||
}
|
||||
|
||||
@@ -1664,7 +1703,7 @@ class TahesabController extends Controller
|
||||
try {
|
||||
$customer->refresh();
|
||||
|
||||
if ($customer->moshtari_code != null) {
|
||||
if ((int) ($customer->moshtari_code ?? 0) > 0) {
|
||||
return $customer->moshtari_code;
|
||||
}
|
||||
|
||||
@@ -1697,9 +1736,11 @@ class TahesabController extends Controller
|
||||
return $e->getMessage();
|
||||
}
|
||||
|
||||
return 'tahesab api error!!!';
|
||||
return is_array($response)
|
||||
? ($this->sync()->buildLog($response, 'ثبت مشتری در تهحساب ناموفق بود') ?: 'ثبت مشتری در تهحساب ناموفق بود')
|
||||
: 'ثبت مشتری در تهحساب ناموفق بود';
|
||||
} finally {
|
||||
$lock->release();
|
||||
Cache::forget($lockKey);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -436,14 +436,10 @@ class TahesabSyncService
|
||||
return $this->retry($row);
|
||||
}
|
||||
if ($type === 'withdraw') {
|
||||
$ok = $this->backfillWithdraw($controller, $id);
|
||||
|
||||
return ['ok' => $ok, 'message' => $ok ? 'سند شارژ/برداشت ثبت شد' : 'ارسال شارژ/برداشت ناموفق بود'];
|
||||
return $this->backfillWithdraw($controller, $id);
|
||||
}
|
||||
if ($type === 'order') {
|
||||
$ok = $this->backfillOrder($controller, $id);
|
||||
|
||||
return ['ok' => $ok, 'message' => $ok ? 'سند سفارش ثبت شد' : 'ارسال سفارش ناموفق بود'];
|
||||
return $this->backfillOrder($controller, $id);
|
||||
}
|
||||
|
||||
return ['ok' => false, 'message' => 'نوع نامعتبر است'];
|
||||
@@ -506,12 +502,12 @@ class TahesabSyncService
|
||||
foreach ($this->missingWithdrawIds(max(0, $limit - $used), $customerId) as $withdrawId) {
|
||||
$used++;
|
||||
try {
|
||||
$ok = $this->backfillWithdraw($controller, (int) $withdrawId);
|
||||
if ($ok) {
|
||||
$sent = $this->backfillWithdraw($controller, (int) $withdrawId);
|
||||
if ($sent['ok'] ?? false) {
|
||||
$backfilledWithdraws++;
|
||||
} else {
|
||||
$failed++;
|
||||
$errors[] = 'شارژ/برداشت #'.$withdrawId.': ارسال به تهحساب ناموفق';
|
||||
$errors[] = 'شارژ/برداشت #'.$withdrawId.': '.($sent['message'] ?? 'ارسال به تهحساب ناموفق');
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
$failed++;
|
||||
@@ -523,12 +519,12 @@ class TahesabSyncService
|
||||
foreach ($this->missingOrderIds(max(0, $limit - $used), $customerId) as $orderId) {
|
||||
$used++;
|
||||
try {
|
||||
$ok = $this->backfillOrder($controller, (int) $orderId);
|
||||
if ($ok) {
|
||||
$sent = $this->backfillOrder($controller, (int) $orderId);
|
||||
if ($sent['ok'] ?? false) {
|
||||
$backfilledOrders++;
|
||||
} else {
|
||||
$failed++;
|
||||
$errors[] = 'سفارش #'.$orderId.': ارسال به تهحساب ناموفق';
|
||||
$errors[] = 'سفارش #'.$orderId.': '.($sent['message'] ?? 'ارسال به تهحساب ناموفق');
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
$failed++;
|
||||
@@ -643,48 +639,64 @@ class TahesabSyncService
|
||||
return $query;
|
||||
}
|
||||
|
||||
private function backfillWithdraw(TahesabController $controller, int $withdrawId): bool
|
||||
private function outcomeFromController($result, string $okMessage, string $failMessage): array
|
||||
{
|
||||
if (is_array($result)) {
|
||||
return ['ok' => true, 'message' => $okMessage];
|
||||
}
|
||||
if (is_string($result) && $result !== '') {
|
||||
return ['ok' => false, 'message' => $result];
|
||||
}
|
||||
|
||||
return ['ok' => false, 'message' => $failMessage];
|
||||
}
|
||||
|
||||
private function backfillWithdraw(TahesabController $controller, int $withdrawId): array
|
||||
{
|
||||
$withdraw = \App\Models\Withdraw::query()->find($withdrawId);
|
||||
if (! $withdraw || ! $withdraw->customer_id) {
|
||||
return false;
|
||||
return ['ok' => false, 'message' => 'شارژ بدون مشتری است'];
|
||||
}
|
||||
|
||||
$cash = (float) ($withdraw->cash ?? 0);
|
||||
$gold = (float) ($withdraw->gold ?? 0);
|
||||
|
||||
if (abs($cash) > 1e-9) {
|
||||
$result = $controller->wallet([
|
||||
'customer_id' => (int) $withdraw->customer_id,
|
||||
'value' => abs($cash),
|
||||
'direction' => $cash >= 0 ? 0 : 1,
|
||||
'withdraw_id' => $withdrawId,
|
||||
'note' => $withdraw->note,
|
||||
]);
|
||||
|
||||
return $result !== false;
|
||||
return $this->outcomeFromController(
|
||||
$controller->wallet([
|
||||
'customer_id' => (int) $withdraw->customer_id,
|
||||
'value' => abs($cash),
|
||||
'direction' => $cash >= 0 ? 0 : 1,
|
||||
'withdraw_id' => $withdrawId,
|
||||
'note' => $withdraw->note,
|
||||
]),
|
||||
'سند شارژ/برداشت ثبت شد',
|
||||
'ارسال شارژ/برداشت ناموفق بود'
|
||||
);
|
||||
}
|
||||
|
||||
if (abs($gold) > 1e-9) {
|
||||
$result = $controller->walletGold([
|
||||
'customer_id' => (int) $withdraw->customer_id,
|
||||
'value' => abs($gold),
|
||||
'direction' => $gold >= 0 ? 1 : 0,
|
||||
'withdraw_id' => $withdrawId,
|
||||
'note' => $withdraw->note,
|
||||
]);
|
||||
|
||||
return $result !== false;
|
||||
return $this->outcomeFromController(
|
||||
$controller->walletGold([
|
||||
'customer_id' => (int) $withdraw->customer_id,
|
||||
'value' => abs($gold),
|
||||
'direction' => $gold >= 0 ? 1 : 0,
|
||||
'withdraw_id' => $withdrawId,
|
||||
'note' => $withdraw->note,
|
||||
]),
|
||||
'سند شارژ/برداشت ثبت شد',
|
||||
'ارسال شارژ/برداشت ناموفق بود'
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
return ['ok' => false, 'message' => 'مبلغ شارژ صفر است'];
|
||||
}
|
||||
|
||||
private function backfillOrder(TahesabController $controller, int $orderId): bool
|
||||
private function backfillOrder(TahesabController $controller, int $orderId): array
|
||||
{
|
||||
$order = \App\Models\Order::query()->with('product')->find($orderId);
|
||||
if (! $order || ! $order->customer_id) {
|
||||
return false;
|
||||
return ['ok' => false, 'message' => 'سفارش بدون مشتری است'];
|
||||
}
|
||||
|
||||
$product = $order->product;
|
||||
@@ -708,9 +720,11 @@ class TahesabSyncService
|
||||
'order' => ['id' => $orderId, 'product_id' => $order->product_id],
|
||||
];
|
||||
|
||||
$result = $controller->storeTrade($payload);
|
||||
|
||||
return $result !== false;
|
||||
return $this->outcomeFromController(
|
||||
$controller->storeTrade($payload),
|
||||
'سند سفارش ثبت شد',
|
||||
'ارسال سفارش ناموفق بود'
|
||||
);
|
||||
}
|
||||
|
||||
public function ensureLocalTable(): bool
|
||||
|
||||
Reference in New Issue
Block a user