diff --git a/app/Http/Controllers/Admin/CustomerController.php b/app/Http/Controllers/Admin/CustomerController.php index 6a70fca..1f880c2 100644 --- a/app/Http/Controllers/Admin/CustomerController.php +++ b/app/Http/Controllers/Admin/CustomerController.php @@ -299,14 +299,13 @@ class CustomerController extends SuperController $referrerWallet = Wallet::where('owner', $referrer->id)->first(); if($this->Config('send_to_tahesab') == "true"){ try { - $tahesab = new TahesabController(); - $tahesab->referrerGoldReward( + app(TahesabController::class)->referrerGoldReward( $customer, (float) $gift_for_inviter, 'پاداش بابت معرفی' ); - }catch (\Exception $e){ - return response($e->getMessage(), 500); + } catch (\Exception $e) { + report($e); } } $message = "سلام {$referrer->name} عزیز،\n\n{$gift_for_inviter} گرم طلا بابت معرفی {$customer->name} به حساب شما واریز شد.\nموجودی فعلی: {$referrerWallet->gold} گرم.\n\nاطلاعات بیشتر: $companyurl\n\nبا احترام،\n$companyName"; @@ -348,14 +347,13 @@ class CustomerController extends SuperController $referrerWallet = Wallet::where('owner', $customer->id)->first(); if($this->Config('send_to_tahesab') == "true"){ try { - $tahesab = new TahesabController(); - $tahesab->goldReward([ + app(TahesabController::class)->goldReward([ 'customer_id' => $customer->id, 'value' => $gift_for_invited, 'desc' => 'پاداش بابت ثبت نام', ]); - }catch (\Exception $e){ - return response($e->getMessage(), 500); + } catch (\Exception $e) { + report($e); } } $message = "سلام " . $customer->name . " عزیز،\n\n" . $gift_for_invited . " گرم طلا بابت ثبت نام " . " به حساب شما واریز شد.\n" . "موجودی فعلی: " . $referrerWallet->gold . " گرم.\n\n" . "اطلاعات بیشتر: " . $companyurl . "\n\n" . "با احترام،\n" . $companyName; diff --git a/app/Http/Controllers/Admin/TahesabController.php b/app/Http/Controllers/Admin/TahesabController.php index ba22b6d..a59a563 100644 --- a/app/Http/Controllers/Admin/TahesabController.php +++ b/app/Http/Controllers/Admin/TahesabController.php @@ -9,6 +9,7 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\Http; use App\Models\Tahesab; use App\Models\Customer; +use App\Services\TahesabSyncService; use Morilog\Jalali\Jalalian; use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException; use Hekmatinasser\Verta\Verta; @@ -16,6 +17,45 @@ use Hekmatinasser\Verta\Verta; class TahesabController extends Controller { + protected function sync(): TahesabSyncService + { + return app(TahesabSyncService::class); + } + + public function table(Request $request) + { + $query = Tahesab::with('customer')->orderByDesc('id'); + \App\DB\Te\TableEngine::create($query, $request) + ->initSearch(['desc', 'type']) + ->select(['*']) + ->export($query); + + return response()->json($query); + } + + public function show($id) + { + $tahesab = Tahesab::with('customer')->findOrFail($id); + + return response()->json($tahesab); + } + + public function retrySanad($id) + { + $tahesab = Tahesab::with('customer')->findOrFail($id); + $result = $this->sync()->retry($tahesab); + + return response()->json($result, ($result['ok'] ?? false) ? 200 : 422); + } + + public function registerCustomer($customerId) + { + $customer = Customer::findOrFail($customerId); + $result = $this->sync()->registerCustomer($customer); + + return response()->json($result, ($result['ok'] ?? false) ? 200 : 422); + } + private function tahesabApiUrl(): string { $host = trim((string) $this->Config('tahesab_host')); @@ -32,7 +72,7 @@ class TahesabController extends Controller return $legacy !== '' ? $legacy : ''; } - public function storeTrade($data) + public function storeTrade($data, ?Tahesab $existing = null) { // if ($input instanceof \Illuminate\Http\Request) { // $data = $input->all(); @@ -56,7 +96,7 @@ class TahesabController extends Controller $customer = Customer::where('id', $data['customer_id'])->first(); if ($customer && ($customer->moshtari_code === null)) { - $this->create_user($customer->id); + $this->createCustomerInTahesab($customer->id); $customer = Customer::where('id', $data['customer_id'])->first(); } $date = Verta::instance(Carbon::parse($data['pay_at']))->format('Y-m-d'); @@ -68,7 +108,8 @@ class TahesabController extends Controller ? (int) round((float) $amount * (float) $data['price']) : (int) ($data['total_price'] ?? round((float) $amount * (float) $data['price'])); - $tahesab = Tahesab::create([ + $data['handler'] = 'storeTrade'; + $tahesab = $existing ?? Tahesab::create([ "customer_id" => $customer->id, "desc" => $data['direction'] == 1 ? "خرید آبشده" : "فروش آبشده", "amount" => $amount, @@ -76,6 +117,7 @@ class TahesabController extends Controller "date" => $data['pay_at'], "type" => $data['product']['metal_id'] == 1 ? "طلا" : "نقره", "created_at" => Carbon::now(), + "data" => json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT), ]); try { @@ -110,27 +152,23 @@ class TahesabController extends Controller ] ])->json(); } catch (\Exception $e) { + $this->sync()->markFailed($tahesab, $e->getMessage()); return $e->getMessage(); } - if ($response['OK']) { - Tahesab::where('id', $tahesab->id)->update([ - "sh_factor" => $response['Sh_factor'], - "tahesab_id" => $response['OK'], - "factor_number" => $response['Factor_Number'], - "tah_id" => $response['ID'] ?? null, - "data" => json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT), - "res" => json_encode($response, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT), - ]); + if ($this->sync()->responseOk($response)) { + $this->sync()->markSuccess($tahesab, $response, $data); return $data; } + + $this->sync()->markFailed($tahesab, $response, 'ثبت سند معامله در ته‌حساب ناموفق بود'); return false; } // directon: 0 = daryaft az moshtari // directon: 1 = pardakht be moshtari - public function wallet($data) + public function wallet($data, ?Tahesab $existing = null) { // if ($input instanceof \Illuminate\Http\Request) { @@ -154,16 +192,19 @@ class TahesabController extends Controller $customer = Customer::where('id', $data['customer_id'])->first(); if ($customer && ($customer->moshtari_code === null)) { - $this->create_user($customer->id); + $this->createCustomerInTahesab($customer->id); $customer = Customer::where('id', $data['customer_id'])->first(); } - $tahesab = Tahesab::create([ + $data['handler'] = 'wallet'; + $tahesab = $existing ?? Tahesab::create([ "customer_id" => $customer->id, "desc" => $data['direction'] == 0 ? "شارژ حساب" : "برداشت از حساب", "amount" => $data['value'], "type" => "ريال", "date" => Carbon::now(), "created_at" => Carbon::now(), + "withdraw_id" => $data['withdraw_id'] ?? null, + "data" => json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT), ]); $date = Verta::instance(Carbon::now())->format('Y-m-d'); @@ -200,22 +241,17 @@ class TahesabController extends Controller 'response' => $response ?? null, ]); } catch (\Exception $e) { + $this->sync()->markFailed($tahesab, $e->getMessage()); return $e->getMessage(); } - if ($response['OK']) { - Tahesab::where('id', $tahesab->id)->update([ - "sh_factor" => $response['Sh_factor'], - "tahesab_id" => $response['OK'], - "tah_id" => $response['ID'], - "factor_number" => $response['Factor_Number'], - "data" => json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT), - "res" => json_encode($response, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT), - ]); + if ($this->sync()->responseOk($response)) { + $this->sync()->markSuccess($tahesab, $response, $data); return $data; } -//if bedehi/talab or charge/decharge + $this->sync()->markFailed($tahesab, $response, 'ثبت سند ریالی در ته‌حساب ناموفق بود'); + return false; // if($data['bank'] == true) { // try { // $response = Http::withoutVerifying()->timeout(10)->withHeaders([ @@ -297,7 +333,6 @@ class TahesabController extends Controller // return $data; // } // } - return false; } /** @@ -320,7 +355,7 @@ class TahesabController extends Controller /** * پاداش/هدیه طلایی — سند بدهی وزنی (مثل ثبت دستی «بدهی / بابت معرفی» در ته‌حساب). */ - public function goldReward($data) + public function goldReward($data, ?Tahesab $existing = null) { if (!isset($data['customer_id'], $data['value'])) { return request()->expectsJson() @@ -334,7 +369,7 @@ class TahesabController extends Controller } if ($customer->moshtari_code === null) { - $this->create_user($customer->id); + $this->createCustomerInTahesab($customer->id); $customer = Customer::where('id', $data['customer_id'])->first(); } @@ -344,13 +379,15 @@ class TahesabController extends Controller $date = Verta::instance(Carbon::now())->format('Y-m-d'); [$year, $month, $day] = explode('-', $date); - $tahesab = Tahesab::create([ + $data['handler'] = 'goldReward'; + $tahesab = $existing ?? Tahesab::create([ 'customer_id' => $customer->id, 'desc' => $desc, 'amount' => $amount, 'date' => Carbon::now(), 'type' => 'طلا', 'created_at' => Carbon::now(), + 'data' => json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT), ]); try { @@ -380,27 +417,21 @@ class TahesabController extends Controller ], ])->json(); } catch (\Exception $e) { + $this->sync()->markFailed($tahesab, $e->getMessage()); return $e->getMessage(); } - if ($response['OK']) { - Tahesab::where('id', $tahesab->id)->update([ - 'sh_factor' => $response['Sh_factor'] ?? null, - 'tahesab_id' => $response['OK'], - 'factor_number' => $response['Factor_Number'] ?? null, - 'tah_id' => $response['ID'] ?? null, - 'data' => json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT), - 'res' => json_encode($response, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT), - ]); - + if ($this->sync()->responseOk($response)) { + $this->sync()->markSuccess($tahesab, $response, $data); return $data; } + $this->sync()->markFailed($tahesab, $response, 'ثبت پاداش طلایی در ته‌حساب ناموفق بود'); return false; } // direction: 1 = واریز طلا (خرید)، 0 = برداشت طلا (فروش) - public function walletGold($data) + public function walletGold($data, ?Tahesab $existing = null) { // if ($input instanceof \Illuminate\Http\Request) { // $data = $input->all(); @@ -424,7 +455,7 @@ class TahesabController extends Controller $customer = Customer::where('id', $data['customer_id'])->first(); if ($customer && ($customer->moshtari_code === null)) { - $this->create_user($customer->id); + $this->createCustomerInTahesab($customer->id); $customer = Customer::where('id', $data['customer_id'])->first(); } @@ -435,22 +466,27 @@ class TahesabController extends Controller $buyOrSale = (int) ($data['direction'] ?? 1) === 1 ? 1 : 0; $isDeposit = $buyOrSale === 1; - $tahesab = Tahesab::create([ + $data['handler'] = 'walletGold'; + $tahesab = $existing ?? Tahesab::create([ "customer_id" => $customer->id, "desc" => $isDeposit ? "شارژ کیف پول آبشده" : "برداشت از کیف پول آبشده", "amount" => $amount, "date" => Carbon::now(), "type" => "طلا", "created_at" => Carbon::now(), + "withdraw_id" => $data['withdraw_id'] ?? null, + "data" => json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT), ]); - $prices = app(ReportController::class)->lastPrice(request()); + $pricesResponse = app(ReportController::class)->lastPrice(request()); + $prices = method_exists($pricesResponse, 'getData') ? (array) $pricesResponse->getData(true) : (array) $pricesResponse; - $mazaneh = $isDeposit ? (int) $prices['buy'] : (int) $prices['sell']; + $mazaneh = $isDeposit ? (int) ($prices['buy'] ?? 0) : (int) ($prices['sell'] ?? 0); $mablaghKol = (int) round($mazaneh * $amount); - $sharh = !empty($data['desc']) - ? $data['desc'] - : ($isDeposit ? 'خرید آبشده' : 'فروش آبشده'); + $sharh = !empty($data['note']) + ? $data['note'] + : (!empty($data['desc']) ? $data['desc'] : ($isDeposit ? 'خرید آبشده' : 'فروش آبشده')); + $data['note'] = $sharh; try { $response = Http::withoutVerifying()->timeout(10)->withHeaders([ @@ -484,31 +520,26 @@ class TahesabController extends Controller ] ])->json(); } catch (\Exception $e) { + $this->sync()->markFailed($tahesab, $e->getMessage()); return $e->getMessage(); } - if ($response['OK']) { - Tahesab::where('id', $tahesab->id)->update([ - "sh_factor" => $response['Sh_factor'], - "tahesab_id" => $response['OK'], - "factor_number" => $response['Factor_Number'], - "tah_id" => $response['ID'] ?? null, - "data" => json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT), - "res" => json_encode($response, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT), - ]); + if ($this->sync()->responseOk($response)) { + $this->sync()->markSuccess($tahesab, $response, $data); return $data; } + + $this->sync()->markFailed($tahesab, $response, 'ثبت سند طلایی کیف پول در ته‌حساب ناموفق بود'); return false; } - private function create_user($customer_id) + public function createCustomerInTahesab($customer_id) { - - $customer = Customer::findOrFail($customer_id); + $response = null; - if ($customer && ($customer->moshtari_code == null)) { + if ($customer->moshtari_code == null) { try { $response = Http::withoutVerifying()->timeout(10)->withHeaders([ 'DBName' => $this->Config('tahesab_db'), @@ -527,9 +558,9 @@ class TahesabController extends Controller -1, 0 ] -//{"DoNewMoshtari":["Name", "GroupName", "Tel", "Address", "CodeMeli", "Tarikh_Tavalod", "Moaref", "Code_Moaref", Moshtari_Code, Jens_Felez]} - ]); - if (!empty($response['OK'])) { + ])->json(); + + if ($this->sync()->responseOk($response)) { $customer->moshtari_code = $response['OK']; $customer->save(); return $response['OK']; @@ -537,42 +568,43 @@ class TahesabController extends Controller } catch (\Exception $e) { return $e->getMessage(); } - }else { - if($customer && $customer->birth_date !== null){ - $birth_date = Verta::instance(Carbon::parse($customer->birth_date))->format('Y-m-d'); - } - try { - $response = Http::withoutVerifying()->timeout(10)->withHeaders([ - 'DBName' => $this->Config('tahesab_db'), - 'Content-Type' => 'application/json', - 'Authorization' => "Bearer " . $this->Config('tahesab_token'), - ])->post($this->tahesabApiUrl(), [ - "DoEditMoshtari" => [ - $customer->name, - $this->Config('name_fa'), - $customer->mobile, - "", - $customer->n_code ?? "", - $birth_date ?? "", - "", - "", - (int)$customer->moshtari_code, - 0 // tala - ] -//{"DoEditMoshtari":["Name","GroupName", "Tel", "Address", "CodeMeli", "Tarikh_Tavalod", "Moaref", "Code_Moaref", Moshtari_Code]} - ]); - } catch (\Exception $e) { - return response($e->getMessage(), 500); - } - } - if (empty($response['OK'])) { - return "tahesab api error!!!"; + return 'tahesab api error!!!'; } + $birth_date = ''; + if ($customer->birth_date !== null) { + $birth_date = Verta::instance(Carbon::parse($customer->birth_date))->format('Y-m-d'); + } + + try { + $response = Http::withoutVerifying()->timeout(10)->withHeaders([ + 'DBName' => $this->Config('tahesab_db'), + 'Content-Type' => 'application/json', + 'Authorization' => "Bearer " . $this->Config('tahesab_token'), + ])->post($this->tahesabApiUrl(), [ + "DoEditMoshtari" => [ + $customer->name, + $this->Config('name_fa'), + $customer->mobile, + "", + $customer->n_code ?? "", + $birth_date, + "", + "", + (int)$customer->moshtari_code, + 0 + ] + ])->json(); + } catch (\Exception $e) { + return $e->getMessage(); + } + + if (! $this->sync()->responseOk($response)) { + return 'tahesab api error!!!'; + } return true; - } public function healthCheck() diff --git a/app/Http/Controllers/Admin/WalletController.php b/app/Http/Controllers/Admin/WalletController.php index e2c9718..f86f31f 100644 --- a/app/Http/Controllers/Admin/WalletController.php +++ b/app/Http/Controllers/Admin/WalletController.php @@ -127,10 +127,10 @@ class WalletController extends Controller if($this->Config('send_to_tahesab') == "true"){ try { $data['direction'] = $deposit ? 0 : 1; - $tahesab = new TahesabController(); - $tahesab->wallet($data); - }catch (\Exception $e){ - return response($e->getMessage(), 500); + $data['withdraw_id'] = $Withdraw->id; + app(TahesabController::class)->wallet($data); + } catch (\Exception $e) { + report($e); } } @@ -196,10 +196,10 @@ class WalletController extends Controller if($this->Config('send_to_tahesab') == "true"){ try { $data['direction'] = $deposit ? 1 : 0; - $tahesab = new TahesabController(); - $tahesab->walletGold($data); - }catch (\Exception $e){ - return response($e->getMessage(), 500); + $data['withdraw_id'] = $Withdraw->id; + app(TahesabController::class)->walletGold($data); + } catch (\Exception $e) { + report($e); } } //send sms to users and customer @@ -328,10 +328,10 @@ class WalletController extends Controller if ($this->Config('send_to_tahesab') == 'true') { try { $data['direction'] = $deposit ? 1 : 0; - $tahesab = new TahesabController(); - $tahesab->walletGold($data); + $data['withdraw_id'] = $Withdraw->id; + app(TahesabController::class)->walletGold($data); } catch (\Exception $e) { - return response($e->getMessage(), 500); + report($e); } } @@ -517,6 +517,33 @@ class WalletController extends Controller ->select([ '*', Withdraw::$SELECT_STS_STR, Withdraw::$SELECT_DAJ ])->export($records); + + if ($this->Config('send_to_tahesab') === 'true' && isset($records['rows']) && is_array($records['rows'])) { + $withdrawIds = collect($records['rows'])->pluck('id')->filter()->values()->all(); + if ($withdrawIds !== []) { + $failedByWithdraw = \App\Models\Tahesab::query() + ->whereIn('withdraw_id', $withdrawIds) + ->where(function ($query) { + $query->whereNull('tahesab_id'); + if (\Illuminate\Support\Facades\Schema::hasColumn('tahesab', 'sync_status')) { + $query->orWhere('sync_status', \App\Services\TahesabSyncService::STATUS_FAILED); + } + }) + ->orderByDesc('id') + ->get() + ->unique('withdraw_id') + ->keyBy('withdraw_id'); + + foreach ($records['rows'] as &$row) { + $tahesab = $failedByWithdraw->get($row['id'] ?? null); + if ($tahesab) { + $row['tahesab_failed_id'] = $tahesab->id; + } + } + unset($row); + } + } + return response()->json($records); } diff --git a/app/Http/Controllers/Customer/CustomerController.php b/app/Http/Controllers/Customer/CustomerController.php index 4b67058..cdb4b7b 100644 --- a/app/Http/Controllers/Customer/CustomerController.php +++ b/app/Http/Controllers/Customer/CustomerController.php @@ -257,14 +257,13 @@ class CustomerController extends Controller $referrerWallet = Wallet::where('owner', $referrer->id)->first(); if($this->Config('send_to_tahesab') == "true"){ try { - $tahesab = new TahesabController(); - $tahesab->referrerGoldReward( + app(TahesabController::class)->referrerGoldReward( $customer, (float) $gift_for_inviter, 'پاداش بابت معرفی' ); - }catch (\Exception $e){ - return response($e->getMessage(), 500); + } catch (\Exception $e) { + report($e); } } $message = "سلام {$referrer->name} عزیز،\n\n{$gift_for_inviter} گرم طلا بابت معرفی {$customer->name} به حساب شما واریز شد.\nموجودی فعلی: {$referrerWallet->gold} گرم.\n\nاطلاعات بیشتر: $companyurl\n\nبا احترام،\n$companyName"; @@ -306,14 +305,13 @@ class CustomerController extends Controller $referrerWallet = Wallet::where('owner', $customer->id)->first(); if($this->Config('send_to_tahesab') == "true"){ try { - $tahesab = new TahesabController(); - $tahesab->goldReward([ + app(TahesabController::class)->goldReward([ 'customer_id' => $customer->id, 'value' => $gift_for_invited, 'desc' => 'پاداش بابت ثبت نام', ]); - }catch (\Exception $e){ - return response($e->getMessage(), 500); + } catch (\Exception $e) { + report($e); } } $message = "سلام " . $customer->name . " عزیز،\n\n" . $gift_for_invited . " گرم طلا بابت ثبت نام " . " به حساب شما واریز شد.\n" . "موجودی فعلی: " . $referrerWallet->gold . " گرم.\n\n" . "اطلاعات بیشتر: " . $companyurl . "\n\n" . "با احترام،\n" . $companyName; diff --git a/app/Http/Controllers/Customer/WalletController.php b/app/Http/Controllers/Customer/WalletController.php index 4236508..883b825 100644 --- a/app/Http/Controllers/Customer/WalletController.php +++ b/app/Http/Controllers/Customer/WalletController.php @@ -234,18 +234,21 @@ class WalletController extends Controller $userName = $customer->name; // User's name $withdrawAmount = $data['value']; // amount if($this->Config('send_to_tahesab') == "true") { - $tahesab = new TahesabController(); - $result = $tahesab->wallet([ - "customer_id" => auth('customer')->id(), - "value" => $data['value'], - "direction" => 1, - ]); + try { + $result = app(TahesabController::class)->wallet([ + "customer_id" => auth('customer')->id(), + "value" => $data['value'], + "direction" => 1, + ]); - \Log::info('Tahesab withdraw result', [ - 'customer_id' => auth('customer')->id(), - 'value' => $data['value'], - 'result' => $result, - ]); + \Log::info('Tahesab withdraw result', [ + 'customer_id' => auth('customer')->id(), + 'value' => $data['value'], + 'result' => $result, + ]); + } catch (\Exception $e) { + report($e); + } } $companyName = $this->Config('name_fa'); // Company name from configuration $message = "کاربر $userName با شماره موبایل $userMobile درخواست برداشت مبلغ " . number_format($withdrawAmount) . " ریال را دارد. با تشکر، $companyName"; diff --git a/app/Http/Controllers/Single/SingleOrderController.php b/app/Http/Controllers/Single/SingleOrderController.php index c91244f..bbe51ec 100644 --- a/app/Http/Controllers/Single/SingleOrderController.php +++ b/app/Http/Controllers/Single/SingleOrderController.php @@ -200,10 +200,9 @@ class SingleOrderController extends Controller } if ($config->getString('send_to_tahesab', 'false') === 'true') { try { - $tahesab = new TahesabController(); - $data['tahesab'] = $tahesab->storeTrade($data); + $data['tahesab'] = app(TahesabController::class)->storeTrade($data); } catch (\Exception $e) { - return response($e->getMessage(), 500); + report($e); } } // $response['reward'] = $this->give_order_reward($data, $wallet, $wallet_interface); diff --git a/app/Models/Tahesab.php b/app/Models/Tahesab.php index 2db8a36..a4b25a7 100644 --- a/app/Models/Tahesab.php +++ b/app/Models/Tahesab.php @@ -26,10 +26,11 @@ class Tahesab extends Model 'tah_id', 'type', 'data', - + 'sync_status', + 'sync_log', + 'withdraw_id', ]; - static $STS = [ 1 => 'باز', 2 => 'موفق', diff --git a/app/Services/TahesabSyncService.php b/app/Services/TahesabSyncService.php new file mode 100644 index 0000000..269fc05 --- /dev/null +++ b/app/Services/TahesabSyncService.php @@ -0,0 +1,157 @@ + $response['Sh_factor'] ?? null, + 'tahesab_id' => $response['OK'], + 'factor_number' => $response['Factor_Number'] ?? null, + 'tah_id' => $response['ID'] ?? null, + 'res' => json_encode($response, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT), + 'sync_status' => self::STATUS_SUCCESS, + 'sync_log' => null, + ]; + + if ($payload !== null) { + $update['data'] = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); + } + + if ($this->hasSyncColumns()) { + Tahesab::where('id', $tahesab->id)->update($update); + } else { + unset($update['sync_status'], $update['sync_log']); + Tahesab::where('id', $tahesab->id)->update($update); + } + } + + public function markFailed(Tahesab $tahesab, mixed $response = null, ?string $extra = null): void + { + $update = [ + 'res' => is_array($response) + ? json_encode($response, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) + : (is_string($response) ? $response : null), + ]; + + if ($this->hasSyncColumns()) { + $update['sync_status'] = self::STATUS_FAILED; + $update['sync_log'] = $this->buildLog($response, $extra); + } + + Tahesab::where('id', $tahesab->id)->update($update); + } + + public function isFailed(Tahesab $tahesab): bool + { + if ($this->hasSyncColumns()) { + return ($tahesab->sync_status ?? null) === self::STATUS_FAILED + || (empty($tahesab->tahesab_id) && ($tahesab->sync_status ?? null) !== self::STATUS_SUCCESS); + } + + return empty($tahesab->tahesab_id); + } + + public function registerCustomer(Customer $customer): array + { + $controller = app(TahesabController::class); + $result = $controller->createCustomerInTahesab($customer->id); + + if (is_string($result) && str_contains($result, 'error')) { + return ['ok' => false, 'message' => $result]; + } + + $customer->refresh(); + + if (empty($customer->moshtari_code)) { + return ['ok' => false, 'message' => 'ثبت مشتری در ته‌حساب ناموفق بود']; + } + + return [ + 'ok' => true, + 'message' => 'مشتری با موفقیت در ته‌حساب ثبت شد', + 'moshtari_code' => $customer->moshtari_code, + ]; + } + + public function retry(Tahesab $tahesab): array + { + if (! $this->isFailed($tahesab) && ! empty($tahesab->tahesab_id)) { + return ['ok' => false, 'message' => 'این سند قبلاً در ته‌حساب ثبت شده است']; + } + + $payload = json_decode((string) $tahesab->data, true) ?: []; + $handler = $payload['handler'] ?? $this->inferHandler($tahesab); + $controller = app(TahesabController::class); + + $result = match ($handler) { + 'wallet' => $controller->wallet(array_merge($payload, ['_retry_tahesab_id' => $tahesab->id]), $tahesab), + 'walletGold' => $controller->walletGold(array_merge($payload, ['_retry_tahesab_id' => $tahesab->id]), $tahesab), + 'storeTrade' => $controller->storeTrade(array_merge($payload, ['_retry_tahesab_id' => $tahesab->id]), $tahesab), + 'goldReward' => $controller->goldReward(array_merge($payload, ['_retry_tahesab_id' => $tahesab->id]), $tahesab), + default => false, + }; + + $tahesab->refresh(); + + if ($result !== false && ! empty($tahesab->tahesab_id)) { + return ['ok' => true, 'message' => 'سند با موفقیت در ته‌حساب ثبت شد', 'tahesab' => $tahesab]; + } + + return [ + 'ok' => false, + 'message' => $tahesab->sync_log ?: 'ارسال مجدد به ته‌حساب ناموفق بود', + 'tahesab' => $tahesab, + ]; + } + + private function inferHandler(Tahesab $tahesab): string + { + if ($tahesab->order_id) { + return 'storeTrade'; + } + + if ($tahesab->type === 'ريال') { + return 'wallet'; + } + + $desc = (string) $tahesab->desc; + + if (str_contains($desc, 'شارژ کیف') || str_contains($desc, 'برداشت از کیف')) { + return 'walletGold'; + } + + return 'goldReward'; + } + + private function hasSyncColumns(): bool + { + return Schema::hasTable('tahesab') && Schema::hasColumn('tahesab', 'sync_status'); + } +} diff --git a/database/migrations/2026_06_25_000002_add_sync_columns_to_tahesab_table.php b/database/migrations/2026_06_25_000002_add_sync_columns_to_tahesab_table.php new file mode 100644 index 0000000..cc8f6d5 --- /dev/null +++ b/database/migrations/2026_06_25_000002_add_sync_columns_to_tahesab_table.php @@ -0,0 +1,42 @@ +string('sync_status', 20)->default('pending')->after('type'); + } + if (! Schema::hasColumn('tahesab', 'sync_log')) { + $table->text('sync_log')->nullable()->after('sync_status'); + } + if (! Schema::hasColumn('tahesab', 'withdraw_id')) { + $table->unsignedBigInteger('withdraw_id')->nullable()->after('order_id'); + } + }); + } + + public function down(): void + { + if (! Schema::hasTable('tahesab')) { + return; + } + + Schema::table('tahesab', function (Blueprint $table) { + foreach (['sync_status', 'sync_log', 'withdraw_id'] as $column) { + if (Schema::hasColumn('tahesab', $column)) { + $table->dropColumn($column); + } + } + }); + } +}; diff --git a/database/sql/fix_tahesab_sync_columns.sql b/database/sql/fix_tahesab_sync_columns.sql new file mode 100644 index 0000000..6868822 --- /dev/null +++ b/database/sql/fix_tahesab_sync_columns.sql @@ -0,0 +1,12 @@ +-- Manual fix when php artisan migrate does not apply (e.g. baseline already registered). +-- Adds sync tracking columns to tahesab table. + +ALTER TABLE `tahesab` + ADD COLUMN IF NOT EXISTS `sync_status` VARCHAR(20) NOT NULL DEFAULT 'pending' AFTER `type`, + ADD COLUMN IF NOT EXISTS `sync_log` TEXT NULL AFTER `sync_status`, + ADD COLUMN IF NOT EXISTS `withdraw_id` BIGINT UNSIGNED NULL AFTER `order_id`; + +-- MySQL < 8.0.12 does not support IF NOT EXISTS on ADD COLUMN; use these instead if the above fails: +-- ALTER TABLE `tahesab` ADD COLUMN `sync_status` VARCHAR(20) NOT NULL DEFAULT 'pending' AFTER `type`; +-- ALTER TABLE `tahesab` ADD COLUMN `sync_log` TEXT NULL AFTER `sync_status`; +-- ALTER TABLE `tahesab` ADD COLUMN `withdraw_id` BIGINT UNSIGNED NULL AFTER `order_id`; diff --git a/routes/admin.php b/routes/admin.php index 201a319..eb5ffd9 100644 --- a/routes/admin.php +++ b/routes/admin.php @@ -151,6 +151,10 @@ Route::middleware('auth:user')->group(function (){ Route::post('account/sts', [BankAccountController::class, 'changeSts']); Route::post('wallet/tahesab', [TahesabController::class, 'wallet']); + Route::post('tahesab/table', [TahesabController::class, 'table']); + Route::get('tahesab/{id}', [TahesabController::class, 'show']); + Route::post('tahesab/{id}/retry', [TahesabController::class, 'retrySanad']); + Route::post('customer/{id}/tahesab/register', [TahesabController::class, 'registerCustomer']); Route::get('test', function () { $data = [ @@ -159,13 +163,7 @@ Route::middleware('auth:user')->group(function (){ "note" => "test", "direction" => "0" ]; - $tahesab = new TahesabController(); - try { - $tahesab->wallet($data); - - }catch (Exception $e) { - dd($e->getMessage()); - } + app(TahesabController::class)->wallet($data); return "OK"; } );