Files
boursecu_server/app/Http/Controllers/Admin/TahesabController.php
T

902 lines
36 KiB
PHP
Raw Normal View History

2026-01-24 14:03:11 +00:00
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Http\Controllers\Site\ReportController;
2026-01-24 14:03:11 +00:00
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
2026-06-27 22:10:29 +03:30
use Illuminate\Support\Facades\Cache;
2026-01-24 14:03:11 +00:00
use App\Models\Tahesab;
use App\Models\Customer;
2026-06-25 22:20:40 +03:30
use App\Services\TahesabSyncService;
2026-02-08 08:02:11 +00:00
use Morilog\Jalali\Jalalian;
2026-01-24 14:03:11 +00:00
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
use Hekmatinasser\Verta\Verta;
class TahesabController extends Controller
{
2026-06-25 22:20:40 +03:30
protected function sync(): TahesabSyncService
{
return app(TahesabSyncService::class);
}
2026-06-25 22:24:46 +03:30
private function lastPriceData(): array
{
$response = app(ReportController::class)->lastPrice(request());
if (is_array($response)) {
return $response;
}
if (is_object($response) && method_exists($response, 'getData')) {
return (array) $response->getData(true);
}
return (array) $response;
}
2026-06-25 22:20:40 +03:30
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);
}
/** همه مشتریان ته‌حساب را از API می‌گیرد و برمی‌گرداند (Code => [Code,Name,Tel]) */
private function fetchAllTahesabCustomers(): array
{
try {
$response = Http::withoutVerifying()->timeout(30)->withHeaders([
'DBName' => $this->Config('tahesab_db'),
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . $this->Config('tahesab_token'),
])->post($this->tahesabApiUrl(), [
'DoListMoshtari' => [1, 999999],
])->json();
if (! is_array($response)) return [];
return $response;
} catch (\Exception $e) {
return [];
}
}
public function customerSyncStatus(Request $request): \Illuminate\Http\JsonResponse
{
// مشتریان پنل
$panelTotal = Customer::whereNull('deleted_at')->count();
$panelRegistered = Customer::whereNull('deleted_at')->whereNotNull('moshtari_code')->count();
$panelOnly = $panelTotal - $panelRegistered;
$panelOnlyQuery = Customer::whereNull('deleted_at')->whereNull('moshtari_code')
->select('id', 'name', 'mobile', 'created_at');
if ($search = $request->input('search')) {
$panelOnlyQuery->where(function ($q) use ($search) {
$q->where('name', 'like', "%{$search}%")
->orWhere('mobile', 'like', "%{$search}%");
});
}
$panelOnlyList = $panelOnlyQuery->orderBy('id')->paginate(20);
// مشتریان ته‌حساب — فقط وقتی include_tahesab=true ارسال شده (چون کند است)
$tahesabTotal = null;
$tahesabOnlyCount = null;
$tahesabOnlyResult = ['data' => [], 'total' => 0, 'current_page' => 1, 'last_page' => 1];
if ($request->boolean('include_tahesab')) {
$tahesabCustomers = $this->fetchAllTahesabCustomers();
$tahesabTotal = count($tahesabCustomers);
// موبایل‌های پنل بدون صفر ابتدایی
$panelMobiles = Customer::whereNull('deleted_at')
->whereNotNull('mobile')
->pluck('mobile')
->mapWithKeys(fn ($m) => [ltrim((string) $m, '0') => true])
->toArray();
2026-06-29 00:41:42 +03:30
// کدهای مشتریِ قبلاً ثبت‌شده در پنل (برای جلوگیری از تکرار)
$panelCodes = Customer::whereNull('deleted_at')
->whereNotNull('moshtari_code')
->pluck('moshtari_code')
->mapWithKeys(fn ($c) => [(string) $c => true])
->toArray();
$tahesabOnlyList = [];
foreach ($tahesabCustomers as $item) {
if (! is_array($item)) continue;
2026-06-29 00:41:42 +03:30
$code = $item['Code'] ?? null;
if ($code !== null && isset($panelCodes[(string) $code])) continue;
$tel = ltrim((string) ($item['Tel'] ?? ''), '0');
if ($tel && isset($panelMobiles[$tel])) continue;
$tahesabOnlyList[] = [
'code' => $item['Code'] ?? null,
'name' => $item['Name'] ?? '',
'tel' => $item['Tel'] ?? '',
'gid' => $item['GID'] ?? null,
'group' => $item['GoroupName'] ?? '',
];
}
$tahesabOnlyCount = count($tahesabOnlyList);
// همه رو برمی‌گردونیم — frontend خودش paginate می‌کنه
$tahesabOnlyResult = [
'data' => array_values($tahesabOnlyList),
'total' => $tahesabOnlyCount,
'current_page' => 1,
'last_page' => 1,
];
}
return response()->json([
'panel_total' => $panelTotal,
'panel_registered' => $panelRegistered,
'panel_only' => $panelOnly,
'tahesab_total' => $tahesabTotal,
'tahesab_only_count' => $tahesabOnlyCount,
'panel_only_list' => $panelOnlyList,
'tahesab_only_list' => $tahesabOnlyResult,
]);
}
public function syncPanelToTahesab(): \Illuminate\Http\JsonResponse
{
$customers = Customer::whereNull('deleted_at')
->whereNull('moshtari_code')
->select('id', 'name', 'mobile')
->get();
$success = 0;
$failed = 0;
$errors = [];
foreach ($customers as $customer) {
$result = $this->sync()->registerCustomer($customer);
if ($result['ok'] ?? false) {
$success++;
} else {
$failed++;
$errors[] = ['name' => $customer->name, 'mobile' => $customer->mobile, 'error' => $result['message'] ?? ''];
}
}
return response()->json([
'ok' => true,
'success' => $success,
'failed' => $failed,
'errors' => $errors,
]);
}
public function importFromTahesab(Request $request): \Illuminate\Http\JsonResponse
{
$validated = $request->validate([
'customers' => 'required|array',
'customers.*.code' => 'required|integer',
'customers.*.name' => 'required|string',
'customers.*.tel' => 'nullable|string',
]);
$success = 0;
$failed = 0;
$errors = [];
foreach ($validated['customers'] as $item) {
2026-06-29 00:48:23 +03:30
// ستون mobile در دیتابیس NOT NULL است؛ پس برای تلفن خالی رشتهٔ خالی می‌گذاریم نه null
2026-06-29 00:41:42 +03:30
$tel = trim((string) ($item['tel'] ?? ''));
2026-06-29 00:48:23 +03:30
$mobile = $tel !== '' ? '0' . ltrim($tel, '0') : '';
2026-06-29 00:41:42 +03:30
// اگر مشتری با همین کد قبلاً ثبت شده، عملیات موفق در نظر گرفته می‌شود (idempotent)
if (Customer::whereNull('deleted_at')->where('moshtari_code', $item['code'])->exists()) {
$success++;
continue;
}
// کد معرف یکتا
$characters = '0123456789abcdefghijklmnopqrstuvwxyz';
do {
$referralId = '';
for ($i = 0; $i < 4; $i++) {
$referralId .= $characters[random_int(0, strlen($characters) - 1)];
}
} while (Customer::where('referral_id', $referralId)->exists());
try {
$customer = Customer::create([
'name' => trim($item['name']),
'fname' => trim($item['name']),
2026-06-29 00:48:23 +03:30
'mobile' => $mobile,
'active' => true,
'moshtari_code' => $item['code'],
'referral_id' => $referralId,
'type' => 2,
]);
$success++;
2026-06-28 23:41:01 +03:30
} catch (\Throwable $e) {
$failed++;
2026-06-28 23:41:01 +03:30
$msg = $e->getMessage();
if ($e instanceof \Illuminate\Database\QueryException && (int) ($e->errorInfo[1] ?? 0) === 1062) {
$msg = 'این مشتری از قبل در پنل ثبت شده است';
}
$errors[] = ['name' => $item['name'], 'code' => $item['code'], 'error' => $msg];
}
}
return response()->json([
'ok' => true,
'success' => $success,
'failed' => $failed,
'errors' => $errors,
]);
}
2026-06-25 22:20:40 +03:30
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);
}
2026-06-14 11:06:00 +03:30
private function tahesabApiUrl(): string
{
$host = trim((string) $this->Config('tahesab_host'));
$port = trim((string) $this->Config('tahesab_port'));
if ($host !== '' && $port !== '') {
$host = rtrim(preg_replace('#^https?://#i', '', $host), '/');
2026-06-26 21:57:37 +03:30
return 'httpS://' . $host . ':' . $port . '/';
2026-06-14 11:06:00 +03:30
}
$legacy = trim((string) env('TAHESAB', ''));
return $legacy !== '' ? $legacy : '';
}
2026-01-24 14:03:11 +00:00
2026-06-25 22:20:40 +03:30
public function storeTrade($data, ?Tahesab $existing = null)
2026-01-24 14:03:11 +00:00
{
// اگر payload خالی است اما Tahesab موجود و order_id دارد، از Order بازسازی کن
if (empty($data['customer_id']) && $existing && $existing->order_id) {
$order = \App\Models\Order::find($existing->order_id);
if ($order) {
$data = array_merge($data, [
'customer_id' => $existing->customer_id,
'amount' => $existing->amount,
'direction' => $order->direction,
'price' => $order->price,
'total_price' => $order->total_price,
'pay_at' => $existing->date,
'product' => ['metal_id' => $existing->type === 'طلا' ? 1 : 2],
'order' => ['id' => $existing->order_id],
]);
}
}
2026-01-24 14:03:11 +00:00
if (!isset($data['customer_id']) || !isset($data['amount'])) {
2026-01-24 14:03:11 +00:00
return request()->expectsJson()
? response()->json(['error' => 'Data missing: customer_id or amount'], 422)
2026-01-24 14:03:11 +00:00
: false;
}
// $customer = auth()->user();
// if (!$customer) {
// throw new UnprocessableEntityHttpException("Auth needed");
// }
$customer = Customer::where('id', $data['customer_id'])->first();
if ($customer && ($customer->moshtari_code === null)) {
2026-06-25 22:20:40 +03:30
$this->createCustomerInTahesab($customer->id);
2026-03-14 09:57:15 +03:30
$customer = Customer::where('id', $data['customer_id'])->first();
2026-01-24 14:03:11 +00:00
}
$date = Verta::instance(Carbon::parse($data['pay_at']))->format('Y-m-d');
[$year, $month, $day] = explode('-', $date);
2026-02-08 08:02:11 +00:00
2026-01-24 14:03:11 +00:00
$amount = $data['amount'];
2026-06-07 14:30:26 +03:30
$isBuy = (int) ($data['direction'] ?? 0) === 1;
$mablaghKol = $isBuy
? (int) round((float) $amount * (float) $data['price'])
: (int) ($data['total_price'] ?? round((float) $amount * (float) $data['price']));
2026-01-24 14:03:11 +00:00
2026-06-25 22:20:40 +03:30
$data['handler'] = 'storeTrade';
if ($existing && empty($existing->data)) {
$existing->update(['data' => json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)]);
}
2026-06-25 22:20:40 +03:30
$tahesab = $existing ?? Tahesab::create([
2026-01-24 14:03:11 +00:00
"customer_id" => $customer->id,
"desc" => $data['direction'] == 1 ? "خرید آبشده" : "فروش آبشده",
"amount" => $amount,
"order_id" => $data['order']['id'] ?? null,
2026-01-24 14:03:11 +00:00
"date" => $data['pay_at'],
"type" => $data['product']['metal_id'] == 1 ? "طلا" : "نقره",
"created_at" => Carbon::now(),
2026-06-25 22:20:40 +03:30
"data" => json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT),
2026-01-24 14:03:11 +00:00
]);
try {
$response = Http::withoutVerifying()->timeout(10)->withHeaders([
'DBName' => $this->Config('tahesab_db'),
'Content-Type' => 'application/json',
'Authorization' => "Bearer " . $this->Config('tahesab_token'),
2026-06-14 11:06:00 +03:30
])->post($this->tahesabApiUrl(), [
2026-01-24 14:03:11 +00:00
"DoNewSanadBuySaleGOLD" => [
1,//Sabte_Kol_Or_Movaghat_1_0
(int)$customer->moshtari_code, //Moshtari_Code
-1, //Factor_Number
1, //Radif_Number
(int)$year, //Shamsi_Year
(int)$month, //Shamsi_Month
(int)$day, //Shamsi_Day
(float)$amount, //Vazn
$data['product']['metal_id'] == 1 ? 750 : "", //Ayar
0,
"",
2026-04-13 13:06:38 +00:00
$data['direction'] == 1 ? 1 : 0, //BuyOrSale_0_1
2026-01-24 14:03:11 +00:00
(int)$data['price'], //Mazaneh
1, //MazanehIsMesghalOrGeram_0_1
1, //IsMotefaregheOrAbshode_0_1
2026-06-07 14:30:26 +03:30
$mablaghKol, //MablaghKol — خرید: وزن خالص × قیمت (بعد از کارمزد)
2026-04-13 13:06:38 +00:00
$data['direction'] == 1 ? "خرید آبشده" : "فروش آبشده", //sharh
2026-06-07 14:30:26 +03:30
-1, //Factor_Code — خودکار
-1, //HavalehBe_Mcode
-1, //MultiRadif
2026-01-24 14:03:11 +00:00
$data['product']['metal_id'] == 1 ? 0 : 2, //Jens_Felez
(string)Verta::instance($data['pay_at']),
]
])->json();
2026-06-07 14:30:26 +03:30
} catch (\Exception $e) {
2026-06-25 22:20:40 +03:30
$this->sync()->markFailed($tahesab, $e->getMessage());
2026-01-24 14:03:11 +00:00
return $e->getMessage();
}
2026-06-25 22:20:40 +03:30
if ($this->sync()->responseOk($response)) {
$this->sync()->markSuccess($tahesab, $response, $data);
2026-01-24 14:03:11 +00:00
return $data;
}
2026-06-25 22:20:40 +03:30
$this->sync()->markFailed($tahesab, $response, 'ثبت سند معامله در ته‌حساب ناموفق بود');
2026-01-24 14:03:11 +00:00
return false;
}
// directon: 0 = daryaft az moshtari
// directon: 1 = pardakht be moshtari
2026-06-25 22:20:40 +03:30
public function wallet($data, ?Tahesab $existing = null)
2026-01-24 14:03:11 +00:00
{
if (empty($data['customer_id']) && $existing) {
$data = array_merge($data, [
'customer_id' => $existing->customer_id,
'value' => $existing->amount,
'direction' => str_contains((string) $existing->desc, 'برداشت') ? 1 : 0,
'withdraw_id' => $existing->withdraw_id,
]);
}
2026-01-24 14:03:11 +00:00
if (!isset($data['customer_id']) || !isset($data['value'])) {
return request()->expectsJson()
? response()->json(['error' => 'Data missing: customer_id or value'], 422)
: false;
}
// $customer = auth()->user();
// if (!$customer) {
// throw new UnprocessableEntityHttpException("Auth needed");
// }
$customer = Customer::where('id', $data['customer_id'])->first();
2026-03-14 09:57:15 +03:30
if ($customer && ($customer->moshtari_code === null)) {
2026-06-25 22:20:40 +03:30
$this->createCustomerInTahesab($customer->id);
2026-03-14 09:57:15 +03:30
$customer = Customer::where('id', $data['customer_id'])->first();
2026-01-24 14:03:11 +00:00
}
2026-06-25 22:20:40 +03:30
$data['handler'] = 'wallet';
$tahesab = $existing ?? Tahesab::create([
2026-01-24 14:03:11 +00:00
"customer_id" => $customer->id,
"desc" => $data['direction'] == 0 ? "شارژ حساب" : "برداشت از حساب",
"amount" => $data['value'],
"type" => "ريال",
2026-01-24 14:03:11 +00:00
"date" => Carbon::now(),
"created_at" => Carbon::now(),
2026-06-25 22:20:40 +03:30
"withdraw_id" => $data['withdraw_id'] ?? null,
"data" => json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT),
2026-01-24 14:03:11 +00:00
]);
if ($existing && empty($existing->data)) {
$existing->update(['data' => json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)]);
}
$dateSource = ($existing !== null && !empty($existing->date)) ? Carbon::parse($existing->date) : Carbon::now();
$date = Verta::instance($dateSource)->format('Y-m-d');
[$year, $month, $day] = explode('-', $date);
2026-01-24 14:03:11 +00:00
try {
$response = Http::withoutVerifying()->timeout(10)->withHeaders([
'DBName' => $this->Config('tahesab_db'),
'Content-Type' => 'application/json',
'Authorization' => "Bearer " . $this->Config('tahesab_token'),
2026-06-14 11:06:00 +03:30
])->post($this->tahesabApiUrl(), [
2026-01-24 14:03:11 +00:00
"DoNewSanadVKHBank" => [
1,//Sabte_Kol_Or_Movaghat_1_0
$customer->moshtari_code,//Moshtari_Code
-1,//Factor_Number
1,//Radif_Number
2026-03-14 12:46:09 +00:00
(int)$year,//Shamsi_Year
(int)$month,//Shamsi_Month
(int)$day,//Shamsi_Day
(int)$data['direction'],//IsDayaftAzMoshtariOrPardakhtBeMoshtari_0_1
2026-01-24 14:03:11 +00:00
(int)$data['value'],//Mablagh
$data['direction'] == 0 ? "شارژ حساب" : "برداشت از حساب",//Sharh
2026-04-06 09:04:56 +00:00
(string)$this->Config('tahesab_bank_account'), //Name_Bank
2026-01-24 14:03:11 +00:00
"$tahesab->id",//Code_Rahgiri
-1,//Factor_Code
-1,
//MultiRadif
]
2026-03-14 16:21:42 +00:00
])->json();
2026-05-29 21:28:50 +03:30
\Log::info('Tahesab wallet response', [
'data' => $data,
'response' => $response ?? null,
]);
2026-01-24 14:03:11 +00:00
} catch (\Exception $e) {
2026-06-25 22:20:40 +03:30
$this->sync()->markFailed($tahesab, $e->getMessage());
2026-01-24 14:03:11 +00:00
return $e->getMessage();
}
2026-06-25 22:20:40 +03:30
if ($this->sync()->responseOk($response)) {
$this->sync()->markSuccess($tahesab, $response, $data);
2026-01-24 14:03:11 +00:00
return $data;
}
2026-06-25 22:20:40 +03:30
$this->sync()->markFailed($tahesab, $response, 'ثبت سند ریالی در ته‌حساب ناموفق بود');
return false;
// if($data['bank'] == true) {
// try {
// $response = Http::withoutVerifying()->timeout(10)->withHeaders([
2026-05-24 13:56:33 +03:30
// 'DBName' => $this->ConfigService('tahesab_db'),
// 'Content-Type' => 'application/json',
2026-05-24 13:56:33 +03:30
// 'Authorization' => "Bearer " . $this->ConfigService('tahesab_token'),
2026-06-14 11:06:00 +03:30
// ])->post($this->tahesabApiUrl(), [
// "DoNewSanadVKHBank" => [
// 1,//Sabte_Kol_Or_Movaghat_1_0
// $customer->moshtari_code,//Moshtari_Code
// -1,//Factor_Number
// 1,//Radif_Number
// (int)$year,//Shamsi_Year
// (int)$month,//Shamsi_Month
// (int)$day,//Shamsi_Day
// (int)$data['direction'],//IsDayaftAzMoshtariOrPardakhtBeMoshtari_0_1
// (int)$data['value'],//Mablagh
// $data['direction'] == 0 ? "شارژ حساب" : "برداشت از حساب",//Sharh
2026-05-24 13:56:33 +03:30
// (string)$this->ConfigService('tahesab_bank_account'), //Name_Bank
// "$tahesab->id",//Code_Rahgiri
// -1,//Factor_Code
// -1,
// //MultiRadif
// ]
// ])->json();
// } catch (\Exception $e) {
// 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),
// ]);
//
// return $data;
// }
// }else{
// try {
// $response = Http::withoutVerifying()->timeout(10)->withHeaders([
2026-05-24 13:56:33 +03:30
// 'DBName' => $this->ConfigService('tahesab_db'),
// 'Content-Type' => 'application/json',
2026-05-24 13:56:33 +03:30
// 'Authorization' => "Bearer " . $this->ConfigService('tahesab_token'),
2026-06-14 11:06:00 +03:30
// ])->post($this->tahesabApiUrl(), [
// "DoNewSanadTalabBedehi" => [
// 1,//Sabte_Kol_Or_Movaghat_1_0,
// $customer->moshtari_code,//Moshtari_Code
// -1,//Factor_Number
// 1,//Radif_Number
// (int)$year,//Shamsi_Year
// (int)$month,//Shamsi_Month
// (int)$day,//Shamsi_Day
// $data['value'] < 0 ? 0 : 1,//IsBedehiOrTalab_0_1,
// (int)abs($data['value']),//Mablagh
// $data['value'] < 0 ? "بدهکار" : "بستانکار",//Sharh
// $data['note'],//"Baabat",
// 0,//Vazn,
// -1,//Factor_Code
// -1,//HavalehBe_Mcode,
// null,//MultiRadif
// 0,//Jens_Felez,
// "ArzName"
// ]
// ])->json();
// } catch (\Exception $e) {
// return $e->getMessage();
// }
// if ($response['OK']) {
// Tahesab::where('id', $tahesab->id)->update([
// "sh_factor" => $response['Sh_factor'],
// "tahesab_id" => $response['OK'],
// "data" => json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT),
// "res" => json_encode($response, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT),
// ]);
//
// return $data;
// }
// }
2026-01-24 14:03:11 +00:00
}
2026-03-14 09:57:15 +03:30
2026-06-07 18:27:04 +03:30
/**
* پاداش معرفی — همیشه روی حساب معرف (نه کاربر تازه‌ثبت‌نام‌شده).
*/
public function referrerGoldReward(Customer $invitedCustomer, float $gold, string $desc = 'پاداش بابت معرفی')
{
$referrer = $invitedCustomer->referrer();
if (!$referrer) {
return false;
}
return $this->goldReward([
'customer_id' => $referrer->id,
'value' => $gold,
'desc' => $desc,
]);
}
2026-06-07 14:30:26 +03:30
/**
* پاداش/هدیه طلایی — سند بدهی وزنی (مثل ثبت دستی «بدهی / بابت معرفی» در ته‌حساب).
*/
2026-06-25 22:20:40 +03:30
public function goldReward($data, ?Tahesab $existing = null)
2026-06-07 14:30:26 +03:30
{
if (empty($data['customer_id']) && $existing) {
$data = array_merge($data, [
'customer_id' => $existing->customer_id,
'value' => $existing->amount,
'desc' => $existing->desc,
]);
}
2026-06-07 14:30:26 +03:30
if (!isset($data['customer_id'], $data['value'])) {
return request()->expectsJson()
? response()->json(['error' => 'Data missing: customer_id or value'], 422)
: false;
}
$customer = Customer::where('id', $data['customer_id'])->first();
if (!$customer) {
return false;
}
if ($customer->moshtari_code === null) {
2026-06-25 22:20:40 +03:30
$this->createCustomerInTahesab($customer->id);
2026-06-07 14:30:26 +03:30
$customer = Customer::where('id', $data['customer_id'])->first();
}
$amount = abs((float) $data['value']);
$desc = !empty($data['desc']) ? (string) $data['desc'] : 'پاداش';
2026-06-25 22:20:40 +03:30
$data['handler'] = 'goldReward';
$tahesab = $existing ?? Tahesab::create([
2026-06-07 14:30:26 +03:30
'customer_id' => $customer->id,
'desc' => $desc,
'amount' => $amount,
'date' => Carbon::now(),
'type' => 'طلا',
'created_at' => Carbon::now(),
2026-06-25 22:20:40 +03:30
'data' => json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT),
2026-06-07 14:30:26 +03:30
]);
if ($existing && empty($existing->data)) {
$existing->update(['data' => json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)]);
}
$dateSource = ($existing !== null && !empty($existing->date)) ? Carbon::parse($existing->date) : Carbon::now();
$date = Verta::instance($dateSource)->format('Y-m-d');
[$year, $month, $day] = explode('-', $date);
2026-06-07 14:30:26 +03:30
try {
$response = Http::withoutVerifying()->timeout(10)->withHeaders([
'DBName' => $this->Config('tahesab_db'),
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . $this->Config('tahesab_token'),
2026-06-14 11:06:00 +03:30
])->post($this->tahesabApiUrl(), [
2026-06-07 14:30:26 +03:30
'DoNewSanadTalabBedehi' => [
1, // Sabte_Kol
(int) $customer->moshtari_code,
-1, // Factor_Number
1, // Radif_Number
(int) $year,
(int) $month,
(int) $day,
0, // IsBedehiOrTalab — بدهی (فروشگاه به مشتری طلا بدهکار است)
0, // MablaghKol — بدون مبلغ ریالی
$desc,
$desc, // Baabat
(float) $amount,
-1, // Factor_Code
-1, // HavalehBe_Mcode
-1, // MultiRadif
0, // Jens_Felez — طلا
'IRR',
],
])->json();
} catch (\Exception $e) {
2026-06-25 22:20:40 +03:30
$this->sync()->markFailed($tahesab, $e->getMessage());
2026-06-07 14:30:26 +03:30
return $e->getMessage();
}
2026-06-25 22:20:40 +03:30
if ($this->sync()->responseOk($response)) {
$this->sync()->markSuccess($tahesab, $response, $data);
2026-06-07 14:30:26 +03:30
return $data;
}
2026-06-25 22:20:40 +03:30
$this->sync()->markFailed($tahesab, $response, 'ثبت پاداش طلایی در ته‌حساب ناموفق بود');
2026-06-07 14:30:26 +03:30
return false;
}
// direction: 1 = واریز طلا (خرید)، 0 = برداشت طلا (فروش)
2026-06-25 22:20:40 +03:30
public function walletGold($data, ?Tahesab $existing = null)
{
if (empty($data['customer_id']) && $existing) {
$data = array_merge($data, [
'customer_id' => $existing->customer_id,
'value' => $existing->amount,
'direction' => str_contains((string) $existing->desc, 'برداشت') ? 0 : 1,
'withdraw_id' => $existing->withdraw_id,
]);
}
if (!isset($data['customer_id'], $data['value'])) {
return request()->expectsJson()
? response()->json(['error' => 'Data missing: customer_id or value'], 422)
: false;
}
$customer = Customer::where('id', $data['customer_id'])->first();
if ($customer && ($customer->moshtari_code === null)) {
2026-06-25 22:20:40 +03:30
$this->createCustomerInTahesab($customer->id);
$customer = Customer::where('id', $data['customer_id'])->first();
}
$amount = abs($data['value']);
2026-06-07 14:30:26 +03:30
$buyOrSale = (int) ($data['direction'] ?? 1) === 1 ? 1 : 0;
$isDeposit = $buyOrSale === 1;
2026-06-25 22:20:40 +03:30
$data['handler'] = 'walletGold';
$tahesab = $existing ?? Tahesab::create([
"customer_id" => $customer->id,
2026-06-07 14:30:26 +03:30
"desc" => $isDeposit ? "شارژ کیف پول آبشده" : "برداشت از کیف پول آبشده",
"amount" => $amount,
"date" => Carbon::now(),
"type" => "طلا",
"created_at" => Carbon::now(),
2026-06-25 22:20:40 +03:30
"withdraw_id" => $data['withdraw_id'] ?? null,
"data" => json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT),
]);
if ($existing && empty($existing->data)) {
$existing->update(['data' => json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)]);
}
$dateSource = ($existing !== null && !empty($existing->date)) ? Carbon::parse($existing->date) : Carbon::now();
$date = Verta::instance($dateSource)->format('Y-m-d');
[$year, $month, $day] = explode('-', $date);
2026-06-25 22:24:46 +03:30
$prices = $this->lastPriceData();
2026-06-21 13:17:57 +03:30
2026-06-25 22:20:40 +03:30
$mazaneh = $isDeposit ? (int) ($prices['buy'] ?? 0) : (int) ($prices['sell'] ?? 0);
2026-06-07 14:30:26 +03:30
$mablaghKol = (int) round($mazaneh * $amount);
2026-06-25 22:20:40 +03:30
$sharh = !empty($data['note'])
? $data['note']
: (!empty($data['desc']) ? $data['desc'] : ($isDeposit ? 'خرید آبشده' : 'فروش آبشده'));
$data['note'] = $sharh;
2026-06-07 14:30:26 +03:30
try {
$response = Http::withoutVerifying()->timeout(10)->withHeaders([
'DBName' => $this->Config('tahesab_db'),
'Content-Type' => 'application/json',
'Authorization' => "Bearer " . $this->Config('tahesab_token'),
2026-06-14 11:06:00 +03:30
])->post($this->tahesabApiUrl(), [
"DoNewSanadBuySaleGOLD" => [
1,//Sabte_Kol_Or_Movaghat_1_0
(int)$customer->moshtari_code, //Moshtari_Code
-1, //Factor_Number
1, //Radif_Number
(int)$year, //Shamsi_Year
(int)$month, //Shamsi_Month
(int)$day, //Shamsi_Day
(float)$amount, //Vazn
750, //Ayar
0,
"",
2026-06-07 14:30:26 +03:30
$buyOrSale, //BuyOrSale_0_1 — 1=خرید، 0=فروش
$mazaneh, //Mazaneh
1, //MazanehIsMesghalOrGeram_0_1
1, //IsMotefaregheOrAbshode_0_1
2026-06-07 14:30:26 +03:30
$mablaghKol, //MablaghKol
$sharh,//Sharh
-1, //Factor_Code — خودکار
-1, //HavalehBe_Mcode
-1, //MultiRadif
0, //Jens_Felez
(string)$date,
]
2026-03-14 16:21:42 +00:00
])->json();
2026-06-07 14:30:26 +03:30
} catch (\Exception $e) {
2026-06-25 22:20:40 +03:30
$this->sync()->markFailed($tahesab, $e->getMessage());
return $e->getMessage();
}
2026-03-14 16:21:42 +00:00
2026-06-25 22:20:40 +03:30
if ($this->sync()->responseOk($response)) {
$this->sync()->markSuccess($tahesab, $response, $data);
return $data;
}
2026-06-25 22:20:40 +03:30
$this->sync()->markFailed($tahesab, $response, 'ثبت سند طلایی کیف پول در ته‌حساب ناموفق بود');
return false;
}
2026-06-25 22:20:40 +03:30
public function createCustomerInTahesab($customer_id)
2026-03-14 09:57:15 +03:30
{
$customer = Customer::findOrFail($customer_id);
2026-06-25 22:20:40 +03:30
$response = null;
2026-03-14 09:57:15 +03:30
2026-06-25 22:20:40 +03:30
if ($customer->moshtari_code == null) {
2026-06-27 22:10:29 +03:30
$lock = Cache::lock('tahesab:register-customer:'.$customer->id, 30);
2026-06-25 22:20:40 +03:30
2026-06-27 22:10:29 +03:30
if (! $lock->get()) {
$customer->refresh();
if ($customer->moshtari_code != null) {
return $customer->moshtari_code;
2026-03-14 09:57:15 +03:30
}
2026-06-27 22:10:29 +03:30
return 'ثبت مشتری در ته‌حساب در حال انجام است';
2026-03-14 09:57:15 +03:30
}
2026-06-27 22:10:29 +03:30
try {
$customer->refresh();
if ($customer->moshtari_code != null) {
return $customer->moshtari_code;
}
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(), [
"DoNewMoshtari" => [
(string)$customer->name,
$this->Config('name_fa'),
(string)$customer->mobile,
"",
"",
"",
"",
"",
-1,
0
]
])->json();
if ($this->sync()->responseOk($response)) {
$customer->moshtari_code = $response['OK'];
$customer->save();
return $response['OK'];
}
} catch (\Exception $e) {
return $e->getMessage();
}
return 'tahesab api error!!!';
} finally {
$lock->release();
}
2026-03-14 09:57:15 +03:30
}
2026-06-25 22:20:40 +03:30
$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!!!';
}
2026-03-14 09:57:15 +03:30
return true;
}
public function healthCheck()
{
$tahesab = Http::withoutVerifying()->withHeaders([
'Content-Type' => 'application/json',
'DBName' => $this->Config('tahesab_db'),
'Authorization' => "Bearer " . $this->Config('tahesab_token'),
2026-06-14 11:06:00 +03:30
])->post($this->tahesabApiUrl(), [
"CheckHealth" => []
])->json();
return $tahesab;
// if($tahesab['Api_Status'] === "OK" && $tahesab['DB_Status'] === "OK"){
// return true;
// }else{
// return false;
// }
}
public function sanadList()
{
$tahesab = Http::withoutVerifying()->withHeaders([
'Content-Type' => 'application/json',
'DBName' => $this->Config('tahesab_db'),
'Authorization' => "Bearer " . $this->Config('tahesab_token'),
2026-06-14 11:06:00 +03:30
])->post($this->tahesabApiUrl(), [
"DoListAsnad" => [
10, /*Count_Last,*/
"", /*Moshtari_Code,*/
"", /*"AzTarikhShamsi"*/
(string)Verta::instance(Carbon::now()->format('Y-m-d')), /*"TaTarikhShamsi"*/
"", /*"FilterNoSanad"*/
0, /*Jens_Felez*/
]
])->json();
return $tahesab;
}
2026-01-24 14:03:11 +00:00
}