From b84ea8aabe5e7ff48617fe0d81e47e8aac69c7d6 Mon Sep 17 00:00:00 2001 From: adonis Date: Mon, 25 May 2026 12:47:04 +0330 Subject: [PATCH] montzar added --- .../Single/SingleOrderController.php | 90 +--- .../Controllers/Site/ReportController.php | 408 ++++++------------ app/Models/Cnt.php | 4 +- app/Services/ConfigService.php | 2 +- .../{LimanService.php => MontzarService.php} | 156 ++++--- 5 files changed, 232 insertions(+), 428 deletions(-) rename app/Services/{LimanService.php => MontzarService.php} (64%) diff --git a/app/Http/Controllers/Single/SingleOrderController.php b/app/Http/Controllers/Single/SingleOrderController.php index 31d2021..338ef3c 100644 --- a/app/Http/Controllers/Single/SingleOrderController.php +++ b/app/Http/Controllers/Single/SingleOrderController.php @@ -23,7 +23,8 @@ use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException; use Illuminate\Support\Facades\Http; use App\Models\Setting; use App\Models\Cnt; -use App\Services\LimanService; +use App\Services\MontzarService; +use App\Services\ConfigService; class SingleOrderController extends Controller @@ -31,27 +32,24 @@ class SingleOrderController extends Controller public function store(Request $request) { $data = $request->all(); + $config = app(ConfigService::class); + $toBool = function ($value) { + return filter_var($value, FILTER_VALIDATE_BOOLEAN); + }; - if ($this->Config('liman_price') == 'true') { - $liman_closed = Cnt::where('key', 'liman_closed')->value('value') == "true"; - $liman_buy = Cnt::where('key', 'liman_open_buy')->value('value') == "false" && $data['direction'] == 1; - $liman_sell = Cnt::where('key', 'liman_open_sell')->value('value') == "false" && $data['direction'] == 2; + if ($toBool($config->Config('montzar_price'))) { + $montzar_closed = $toBool($config->Config('montzar_closed')); + $montzar_buy = !$toBool($config->Config('montzar_open_buy')) && (int) $data['direction'] === 1; + $montzar_sell = !$toBool($config->Config('montzar_open_sell')) && (int) $data['direction'] === 2; - if ($liman_closed || $liman_buy || $liman_sell) { - throw new UnprocessableEntityHttpException('عدم ارائه سرویس.'); - } - } elseif ($this->Config('goldir_price') == 'true') { - $goldir_closed = Cnt::where('key', 'goldir_closed')->first()['value'] == "true"; - $goldir_buy = Cnt::where('key', 'goldir_open_buy')->first()['value'] == "false" && $data['direction'] == 1; - $goldir_sell = Cnt::where('key', 'goldir_open_sell')->first()['value'] == "false" && $data['direction'] == 2; - - if ($goldir_closed || $goldir_buy || $goldir_sell) { + if ($montzar_closed || $montzar_buy || $montzar_sell) { throw new UnprocessableEntityHttpException('عدم ارائه سرویس.'); } } - if($this->Config('close_price') == 'true'){ - if(Cnt::where('key', 'app_closed')->first()['value'] == "true"){ + + if ($toBool($config->Config('close_price'))) { + if (Cnt::where('key', 'app_closed')->value('value') == "true") { throw new UnprocessableEntityHttpException('عدم ارائه سرویس.'); } } @@ -190,7 +188,7 @@ class SingleOrderController extends Controller 'start_at' => now(), ], 1, true, false); $response['1'] = 2; - //send to Goldir + //send to provider $this->sendProviderOrder($data, $wallet_interface, (int) $data['direction']); return $response; } @@ -472,9 +470,9 @@ class SingleOrderController extends Controller private function sendProviderOrder(array &$data, $wallet_interface, int $direction) { - if ($this->Config('liman_price') == "true") { + if ($this->Config('montzar_price') == "true") { try { - return app(LimanService::class)->sendOrder($data); + return app(MontzarService::class)->sendOrder($data); } catch (UnprocessableEntityHttpException $e) { $this->rollbackProviderFailedOrder($data, $wallet_interface, $direction); throw $e; @@ -482,12 +480,12 @@ class SingleOrderController extends Controller $this->rollbackProviderFailedOrder($data, $wallet_interface, $direction); throw new UnprocessableEntityHttpException( - 'خطا در ثبت سفارش نزد لیمان: ' . $e->getMessage() + 'خطا در ثبت سفارش ارائه دهنده: ' . $e->getMessage() ); } } - return $this->sendGoldir($data); + return null; } private function rollbackProviderFailedOrder(array $data, $wallet_interface, int $direction): void @@ -520,56 +518,6 @@ class SingleOrderController extends Controller $order->delete(); } - private function sendGoldir($data) - { - if ($this->Config('send_to_goldir') == "true") { - - $goldir_base_url=$this->Config('goldir_base_url')??'https://gold.ir'; - -// $liman_diff = Cnt::where('key', 'goldir_diff')->value('value'); -// $liman_price = Cnt::where('key', 'goldir_price')->value('value'); - $mazaneh = ($data['direction'] == 1) ? Cnt::where('key', 'goldir_truly_buy_mazaneh')->value('value') : Cnt::where('key', 'goldir_truly_sell_mazaneh')->value('value'); - $cash = Cnt::where('key', 'goldir_price')->value('value') * $data['amount']; - - $response = Http::withToken(Cnt::where('key', 'goldir')->first()['value'])->post($goldir_base_url."/server/customer/order", [ - "mazaneh" => ((int)$mazaneh), - 'amount' => $data['amount'], - 'description' => $this->Config('name_fa') . " - " . auth('customer')->user()->name, - 'direction' => $data['direction'], - 'product_id' => $this->Config('hamkar_product_id'), - 'cash' => $cash, - 'input_mode'=> 'gold' - - ])/*->json()*/ - ; - if (isset($response['message']) && $response['message'] == 'no authorised') { - $cnt = new Cnt(); - $response = Http::withToken($cnt->goldir_login())//$this->ConfigService('liman_token')) - ->post($goldir_base_url."/server/customer/order", [ - "mazaneh" => ((int)$mazaneh), - 'amount' => $data['amount'], - 'description' => $this->Config('name_fa') . " - " . auth('customer')->user()->name, - 'direction' => $data['direction'], - 'product_id' => $this->Config('hamkar_product_id'), - 'cash' => $cash, - 'input_mode'=> 'gold' - ])/*->json()*/ - ; - } - - Cnt::where('key', 'goldir_order_response')->update(['value' => $response /*json_encode($response, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)*/]); - Cnt::where('key', 'last_order_log')->update(['value' => $response]); - if (!isset($response[1]) && !isset($response[1]['id'])) { - throw new UnprocessableEntityHttpException('سفارشات توسط ارائه دهنده بسته شده است.'); - } - - $data['provider_id'] = $response[1]['id']; - return $response; - } -// $data['total_price_goldir'] = ($data['direction'] == 1) ? ($liman_price+$liman_diff) : ($liman_price-$liman_diff) ; - - } - public function storeBackUp(Request $request) { $data = $request->all(); diff --git a/app/Http/Controllers/Site/ReportController.php b/app/Http/Controllers/Site/ReportController.php index f0da1e2..c0b68b8 100644 --- a/app/Http/Controllers/Site/ReportController.php +++ b/app/Http/Controllers/Site/ReportController.php @@ -9,18 +9,17 @@ use App\Models\Cnt; use App\Models\Setting; use App\Models\ConfigStatic; use App\Models\Customer; -use App\Services\LimanService; +use App\Services\MontzarService; use App\Models\Price; use App\Models\PriceCandle; use App\Models\PriceTrigger; use App\Models\Product; use Carbon\Carbon; use Illuminate\Http\Request; -use Illuminate\Support\Arr; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Mail; use Morilog\Jalali\Jalalian; -use App\Http\Controllers\Admin\ProductController; +use App\Services\ConfigService; class ReportController extends Controller @@ -112,18 +111,19 @@ class ReportController extends Controller public function lastPrice() { + $config = app(ConfigService::class); + $closed = false; - $goldir_price = 0; - $liman_price = 0; + $montzar_price = 0; $tgn = 0; $pr_price = 0; $open_buy = true; $open_sell = true; - $liman_open_buy = false; - $liman_open_sell = false; + $montzar_open_buy = false; + $montzar_open_sell = false; $priceSource = null; $priceValue = 0; @@ -132,16 +132,30 @@ class ReportController extends Controller return filter_var($value, FILTER_VALIDATE_BOOLEAN); }; + $zeroResponse = function () { + return [ + 'sell' => 0, + 'buy' => 0, + 'price_last' => 0, + 'price' => 0, + 'main_product' => 0, + 'taban_gohar' => 0, + 'montzar' => 0, + 'closed' => true, + 'time' => now(), + ]; + }; + /* |-------------------------------------------------------------------------- | بستن قیمت طبق منطق قبلی |-------------------------------------------------------------------------- */ - if ($this->Config('close_price') == 'true') { - $startDay = $this->Config('startDay'); + if ($toBool($config->Config('close_price'))) { + $startDay = $config->Config('startDay') ?: '00:00'; [$startHour, $startMinute] = explode(':', $startDay); - $endDay = $this->Config('endDay'); + $endDay = $config->Config('endDay') ?: '23:59'; [$endHour, $endMinute] = explode(':', $endDay); $current = Carbon::now(); @@ -149,27 +163,16 @@ class ReportController extends Controller $end = Carbon::today()->setTime((int) $endHour, (int) $endMinute); if (!$current->between($start, $end)) { - Cnt::where('key', 'app_closed')->update(['value' => "true"]); - Cnt::where('key', 'goldir_closed')->update(['value' => "true"]); - Cnt::where('key', 'liman_closed')->update(['value' => "true"]); + // عمومی: در Cnt بماند + Cnt::where('key', 'app_closed')->update(['value' => 'true']); - return [ - 'sell' => 0, - 'buy' => 0, - 'price_last' => 0, - 'price' => 0, - 'main_product' => 0, - 'taban_gohar' => 0, - 'goldir' => 0, - 'liman' => 0, - 'closed' => true, - 'time' => now()->format('H:i:s'), - ]; + // مربوط به منتزر: settings + $config->UpdateConfig('montzar_closed', 'true'); + + return $zeroResponse(); } - Cnt::where('key', 'app_closed')->update(['value' => "false"]); - Cnt::where('key', 'goldir_closed')->update(['value' => "false"]); - Cnt::where('key', 'liman_closed')->update(['value' => "false"]); + Cnt::where('key', 'app_closed')->update(['value' => 'false']); } /* @@ -179,83 +182,53 @@ class ReportController extends Controller */ $settings = Setting::whereIn('key', [ 'fee_single', - 'goldir_price', 'tabanGohar_price', 'main_product_price', 'buy_fee', 'sell_fee', + 'show_last_price', ])->get(); $settingsMap = $settings->pluck('value', 'key'); - + $show_last_price = $toBool($settingsMap->get('show_last_price', false)); $taban_gohar_price = $settingsMap->get('tabanGohar_price'); - $difference = (float) $settingsMap->get('fee_single', 0); - $gold_ir_price = $settingsMap->get('goldir_price'); $main_product_price = $settingsMap->get('main_product_price'); + $difference = (float) $settingsMap->get('fee_single', 0); $diff_buy = (float) $settingsMap->get('buy_fee', $difference); $diff_sell = (float) $settingsMap->get('sell_fee', $difference); - $liman_price_enabled = $toBool($this->Config('liman_price')); - - \Log::info('LAST_PRICE DEBUG START', [ - 'file' => __FILE__, - 'close_price' => $this->Config('close_price'), - 'liman_price_raw' => $this->Config('liman_price'), - 'liman_price_enabled' => $liman_price_enabled, - 'liman_product_id' => $this->Config('liman_product_id'), - 'liman_base_url' => $this->Config('liman_base_url'), - 'liman_token_exists' => (bool) Setting::where('key', 'liman_token')->value('value'), - ]); + $montzar_price_enabled = $toBool($config->Config('montzar_price')); /* |-------------------------------------------------------------------------- - | Montpar / Liman - اولویت اول + | Montzar - اولویت اول |-------------------------------------------------------------------------- */ - if ($liman_price_enabled && !$closed) { + if ($montzar_price_enabled && !$closed) { try { - $limanBaseUrl = rtrim($this->Config('liman_base_url') ?: 'https://montpar.ir', '/'); - $limanProductId = (int) ($this->Config('liman_product_id') ?: 25); + $montzarBaseUrl = rtrim($config->Config('montzar_base_url') ?: 'https://montpar.ir', '/'); + $montzarProductId = (int) ($config->Config('montzar_product_id') ?: 25); - $liman = app(LimanService::class)->productList(); + $montzar = app(MontzarService::class)->productList(); - \Log::info('PROVIDER FIRST RESPONSE', [ - 'base_url' => $limanBaseUrl, - 'product_id' => $limanProductId, - 'type' => gettype($liman), - 'message' => is_array($liman) ? ($liman['message'] ?? null) : null, - 'available_ids' => is_array($liman) ? collect($liman)->pluck('id')->values()->all() : null, - ]); - - if (isset($liman['message'])) { - throw new \Exception('Provider message: ' . $liman['message']); + if (isset($montzar['message'])) { + throw new \Exception('Provider message: ' . $montzar['message']); } - $collection = collect($liman); - $lpLiman = $collection->firstWhere('id', $limanProductId); + $collection = collect($montzar); + $montzarProduct = $collection->firstWhere('id', $montzarProductId); - \Log::info('PROVIDER PRODUCT PICKED', [ - 'base_url' => $limanBaseUrl, - 'liman_product_id' => $limanProductId, - 'found' => (bool) $lpLiman, - 'has_sub_agent' => $lpLiman && isset($lpLiman['sub_agent']), - 'open_buy' => $lpLiman['open_buy'] ?? null, - 'open_sell' => $lpLiman['open_sell'] ?? null, - 'buy_gram' => $lpLiman['sub_agent']['rate_buy_gram_price'] ?? null, - 'sell_gram' => $lpLiman['sub_agent']['rate_sell_gram_price'] ?? null, - ]); - - if (!$lpLiman) { - throw new \Exception("Provider product not found. product_id={$limanProductId}"); + if (!$montzarProduct) { + throw new \Exception("Provider product not found. product_id={$montzarProductId}"); } - if (!isset($lpLiman['sub_agent'])) { - throw new \Exception("Provider product has no sub_agent. product_id={$limanProductId}"); + if (!isset($montzarProduct['sub_agent'])) { + throw new \Exception("Provider product has no sub_agent. product_id={$montzarProductId}"); } - $buy = (float) ($lpLiman['sub_agent']['rate_buy_gram_price'] ?? 0); - $sell = (float) ($lpLiman['sub_agent']['rate_sell_gram_price'] ?? 0); + $buy = (float) ($montzarProduct['sub_agent']['rate_buy_gram_price'] ?? 0); + $sell = (float) ($montzarProduct['sub_agent']['rate_sell_gram_price'] ?? 0); if ($buy <= 0 || $sell <= 0) { throw new \Exception("Provider invalid gram price. buy={$buy}, sell={$sell}"); @@ -265,160 +238,46 @@ class ReportController extends Controller $customPrice['price'] = ($buy + $sell) / 2; $customPrice['diff'] = ($buy - $sell) / 2; - Cnt::where('key', 'liman_price')->update([ - 'value' => (float) $customPrice['price'] - ]); + $config->UpdateConfig('montzar_price', (float) $customPrice['price']); + $config->UpdateConfig('montzar_diff', (float) $customPrice['diff']); + $config->UpdateConfig('montzar_mazaneh', ((float) $customPrice['price'] * 4.331802)); - Cnt::where('key', 'liman_diff')->update([ - 'value' => (float) $customPrice['diff'] - ]); + $config->UpdateConfig( + 'montzar_truly_buy_mazaneh', + $montzarProduct['sub_agent']['rate_buy_price'] ?? 0 + ); - Cnt::where('key', 'liman_mazaneh')->update([ - 'value' => ((float) $customPrice['price'] * 4.331802) - ]); + $config->UpdateConfig( + 'montzar_truly_sell_mazaneh', + $montzarProduct['sub_agent']['rate_sell_price'] ?? 0 + ); - Cnt::where('key', 'liman_truly_buy_mazaneh')->update([ - 'value' => $lpLiman['sub_agent']['rate_buy_price'] ?? 0 - ]); + $config->UpdateConfig( + 'montzar_last_product_log', + json_encode($montzarProduct, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) + ); - Cnt::where('key', 'liman_truly_sell_mazaneh')->update([ - 'value' => $lpLiman['sub_agent']['rate_sell_price'] ?? 0 - ]); + $montzar_open_sell = $toBool($montzarProduct['open_sell'] ?? false); + $montzar_open_buy = $toBool($montzarProduct['open_buy'] ?? false); - Cnt::where('key', 'log')->update([ - 'value' => json_encode($lpLiman, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) - ]); + $config->UpdateConfig('montzar_open_sell', $montzar_open_sell ? 'true' : 'false'); + $config->UpdateConfig('montzar_open_buy', $montzar_open_buy ? 'true' : 'false'); - $liman_open_sell = $toBool($lpLiman['open_sell'] ?? false); - $liman_open_buy = $toBool($lpLiman['open_buy'] ?? false); - - Cnt::where('key', 'liman_open_sell')->update([ - 'value' => $liman_open_sell ? "true" : "false" - ]); - - Cnt::where('key', 'liman_open_buy')->update([ - 'value' => $liman_open_buy ? "true" : "false" - ]); - - if ($liman_open_sell || $liman_open_buy) { - $liman_price = (int) $customPrice['price']; + if ($montzar_open_sell || $montzar_open_buy) { + $montzar_price = (int) $customPrice['price']; } - Cnt::where('key', 'liman_closed')->update([ - 'value' => $liman_price == 0 ? "true" : "false" - ]); - - \Log::info('PROVIDER PRICE SUCCESS', [ - 'base_url' => $limanBaseUrl, - 'liman_product_id' => $limanProductId, - 'liman_price' => $liman_price, - 'liman_diff' => $customPrice['diff'], - 'open_buy' => $liman_open_buy, - 'open_sell' => $liman_open_sell, - ]); + $config->UpdateConfig('montzar_closed', $montzar_price == 0 ? 'true' : 'false'); } catch (\Throwable $e) { - $liman_price = 0; + $montzar_price = 0; - \Log::error('PROVIDER PRICE ERROR', [ - 'base_url' => $limanBaseUrl ?? null, + \Log::error('MONZAR PRICE ERROR', [ 'message' => $e->getMessage(), - 'liman_product_id' => $limanProductId ?? null, - 'liman_response' => $liman ?? null, + 'montzar_product_id' => $montzarProductId ?? null, + 'montzar_response' => $montzar ?? null, ]); - Cnt::where('key', 'liman_closed')->update([ - 'value' => "true" - ]); - } - } - /* - |-------------------------------------------------------------------------- - | Goldir - |-------------------------------------------------------------------------- - */ - if ($gold_ir_price == 'true' && !$closed) { - try { - $goldir = Http::timeout(7) - ->withOptions([ - 'curl' => [ - CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4, - CURLOPT_TCP_FASTOPEN => 1, - ] - ]) - ->withoutVerifying() - ->withToken(Cnt::where('key', 'goldir')->value('value')) - ->get('https://gold.ir/server/customer/product/list') - ->json(); - - if ((isset($goldir['message']) && $goldir['message'] == 'no authorised') || $goldir == null) { - $cnt = new Cnt(); - - $goldir = Http::timeout(2) - ->withToken($cnt->goldir_login()) - ->get('https://gold.ir/server/customer/product/list') - ->json(); - } - - $collection = collect($goldir); - $lpGoldir = $collection->firstWhere('id', 40); - - if ($lpGoldir && isset($lpGoldir['sub_agent'])) { - $buy = (float) $lpGoldir['sub_agent']['rate_buy_gram_price']; - $sell = (float) $lpGoldir['sub_agent']['rate_sell_gram_price']; - - $customPrice = []; - $customPrice['price'] = (ceil($buy) + ceil($sell)) / 2; - $customPrice['diff'] = (ceil($buy) - ceil($sell)) / 2; - - Cnt::where('key', 'goldir_price')->update([ - 'value' => (float) $customPrice['price'] - ]); - - Cnt::where('key', 'goldir_diff')->update([ - 'value' => (float) $customPrice['diff'] - ]); - - Cnt::where('key', 'goldir_mazaneh')->update([ - 'value' => ((float) $customPrice['price'] * 4.331802) - ]); - - Cnt::where('key', 'goldir_truly_buy_mazaneh')->update([ - 'value' => $lpGoldir['sub_agent']['rate_buy_price'] - ]); - - Cnt::where('key', 'goldir_truly_sell_mazaneh')->update([ - 'value' => $lpGoldir['sub_agent']['rate_sell_price'] - ]); - - Cnt::where('key', 'log')->update([ - 'value' => json_encode($goldir, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) - ]); - - $open_sell = $toBool($lpGoldir['open_sell'] ?? false); - $open_buy = $toBool($lpGoldir['open_buy'] ?? false); - - Cnt::where('key', 'goldir_open_sell')->update([ - 'value' => $open_sell ? "true" : "false" - ]); - - Cnt::where('key', 'goldir_open_buy')->update([ - 'value' => $open_buy ? "true" : "false" - ]); - - if ($open_sell || $open_buy) { - $goldir_price = (int) $customPrice['price']; - } - } - - Cnt::where('key', 'goldir_closed')->update([ - 'value' => $goldir_price == 0 ? "true" : "false" - ]); - } catch (\Throwable $e) { - $goldir_price = 0; - - Cnt::where('key', 'goldir_closed')->update([ - 'value' => "true" - ]); + $config->UpdateConfig('montzar_closed', 'true'); } } @@ -426,10 +285,12 @@ class ReportController extends Controller |-------------------------------------------------------------------------- | Main Product |-------------------------------------------------------------------------- + | عمومی است، پس از Cnt خوانده می‌شود. + |-------------------------------------------------------------------------- */ - if ($main_product_price == 'true' && !$closed) { + if ($toBool($main_product_price) && !$closed) { $main_product_id = Cnt::where('key', 'main_product')->value('value'); - $pr_product = Product::find($main_product_id); + $pr_product = $main_product_id ? Product::find($main_product_id) : null; if ($pr_product) { $pr_price = (float) $pr_product['price'] + (float) $pr_product['price_profit']; @@ -441,13 +302,13 @@ class ReportController extends Controller | Taban Gohar |-------------------------------------------------------------------------- */ - if ($taban_gohar_price == 'true' && !$closed) { + if ($toBool($taban_gohar_price) && !$closed) { try { $taban_gohar = Http::withOptions([ 'curl' => [ CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4, CURLOPT_TCP_FASTOPEN => 1, - ] + ], ]) ->withoutVerifying() ->timeout(2) @@ -464,19 +325,16 @@ class ReportController extends Controller |-------------------------------------------------------------------------- | انتخاب قیمت اصلی | اولویت: - | Liman/Montpar -> Goldir -> Taban Gohar -> Main Product + | Montzar -> Taban Gohar -> Main Product |-------------------------------------------------------------------------- */ - if ($liman_price_enabled && ($liman_price ?? 0) !== 0 && !$closed) { - $priceValue = (int) $liman_price; - $priceSource = 'liman'; - } elseif ($gold_ir_price == 'true' && ($goldir_price ?? 0) !== 0 && !$closed) { - $priceValue = (int) $goldir_price; - $priceSource = 'goldir'; - } elseif ($taban_gohar_price == 'true' && ($tgn ?? 0) !== 0 && !$closed) { + if ($montzar_price_enabled && ($montzar_price ?? 0) !== 0 && !$closed) { + $priceValue = (int) $montzar_price; + $priceSource = 'montzar'; + } elseif ($toBool($taban_gohar_price) && ($tgn ?? 0) !== 0 && !$closed) { $priceValue = $tgn; $priceSource = 'taban_gohar'; - } elseif ($main_product_price == 'true' && ($pr_price ?? 0) !== 0 && !$closed) { + } elseif ($toBool($main_product_price) && ($pr_price ?? 0) !== 0 && !$closed) { $priceValue = $pr_price; $priceSource = 'main_product'; } else { @@ -484,32 +342,39 @@ class ReportController extends Controller $priceSource = null; } - /* - |-------------------------------------------------------------------------- - | اگر هیچ منبعی قیمت نداد، قیمت قبلی دیتابیس را برنگردان - |-------------------------------------------------------------------------- - */ if ($priceValue <= 0) { - \Log::warning('LAST_PRICE NO SOURCE PRICE', [ - 'liman_price' => $liman_price, - 'goldir_price' => $goldir_price, - 'taban_gohar' => $tgn, - 'main_product' => $pr_price, - 'price_source' => $priceSource, - ]); + if (!$show_last_price) { + return [ + 'sell' => 0, + 'buy' => 0, + 'price_last' => 0, + 'price' => 0, + 'main_product' => $pr_price ?? 0, + 'taban_gohar' => $tgn ?? 0, + 'montzar' => $montzar_price ?? 0, + 'closed' => true, + 'time' => now(), + ]; + } - return [ - 'sell' => 0, - 'buy' => 0, - 'price_last' => 0, - 'price' => 0, - 'main_product' => $pr_price ?? 0, - 'taban_gohar' => $tgn ?? 0, - 'goldir' => $goldir_price ?? 0, - 'liman' => $liman_price ?? 0, - 'closed' => true, - 'time' => now(), - ]; + $lastPrice = Price::latest()->first(); + + if (!$lastPrice || (float) $lastPrice->price <= 0) { + return [ + 'sell' => 0, + 'buy' => 0, + 'price_last' => 0, + 'price' => 0, + 'main_product' => $pr_price ?? 0, + 'taban_gohar' => $tgn ?? 0, + 'montzar' => $montzar_price ?? 0, + 'closed' => true, + 'time' => now(), + ]; + } + + $priceValue = (float) $lastPrice->price; + $priceSource = 'database_last'; } /* @@ -546,41 +411,36 @@ class ReportController extends Controller $candle->save(); } else { PriceCandle::create([ - "start" => $priceValue, - "end" => $priceValue, - "high" => $priceValue, - "low" => $priceValue, - "date_at" => date("Y-m-d") + 'start' => $priceValue, + 'end' => $priceValue, + 'high' => $priceValue, + 'low' => $priceValue, + 'date_at' => date('Y-m-d'), ]); } } /* |-------------------------------------------------------------------------- - | محاسبه sell / buy با همان priceValue همین اجرای فعلی + | محاسبه sell / buy |-------------------------------------------------------------------------- */ - if ($priceSource === 'liman') { - $liman_profit = (float) Cnt::where('key', 'liman_diff')->value('value'); + if ($priceSource === 'montzar') { + $montzar_profit = (float) $config->Config('montzar_diff'); - $final_buy_diff = $diff_buy + $liman_profit; - $final_sell_diff = $diff_sell + $liman_profit; + $final_buy_diff = $diff_buy + $montzar_profit; + $final_sell_diff = $diff_sell + $montzar_profit; - $sell = $liman_open_sell + $sell = $montzar_open_sell ? ceil($priceValue - $final_sell_diff) : 0; - $buy = $liman_open_buy + $buy = $montzar_open_buy ? ceil($priceValue + $final_buy_diff) : 0; $priceLast = ceil($priceValue + $final_buy_diff); } else { - if ($priceSource === 'goldir' && $goldir_price !== 0) { - $goldir_profit = (float) Cnt::where('key', 'goldir_diff')->value('value'); - $difference = $goldir_profit; - } - $sell = $open_sell ? ceil($priceValue - $difference) : 0; @@ -599,14 +459,12 @@ class ReportController extends Controller 'price' => $priceValue, 'main_product' => $pr_price ?? 0, 'taban_gohar' => $tgn ?? 0, - 'goldir' => $goldir_price ?? 0, - 'liman' => $liman_price ?? 0, + 'montzar' => $montzar_price ?? 0, 'closed' => false, 'time' => now(), ]; } - public function check() { $service = Http:: diff --git a/app/Models/Cnt.php b/app/Models/Cnt.php index d312a1e..21579b7 100644 --- a/app/Models/Cnt.php +++ b/app/Models/Cnt.php @@ -20,7 +20,7 @@ class Cnt extends Model protected $casts = [ 'value_json'=>'array' ]; - public function goldir_login(){ +/* public function goldir_login(){ $mobile = self::where('key', 'goldir_mobile')->value('value'); $password = self::where('key', 'goldir_password')->value('value'); $goldir_base_url=Controller::Config('goldir_base_url')??'https://gold.ir'; @@ -44,6 +44,6 @@ class Cnt extends Model 'updated_at' => now() ]); return $goldir['access_token']; - } + }*/ } diff --git a/app/Services/ConfigService.php b/app/Services/ConfigService.php index 5f9bcae..b5d6fd6 100644 --- a/app/Services/ConfigService.php +++ b/app/Services/ConfigService.php @@ -13,7 +13,7 @@ class ConfigService public function UpdateConfig($name, $value) { - return Setting::updateOrCreate( + return \App\Models\Setting::updateOrCreate( ['key' => $name], ['value' => $value] ); diff --git a/app/Services/LimanService.php b/app/Services/MontzarService.php similarity index 64% rename from app/Services/LimanService.php rename to app/Services/MontzarService.php index e219b99..69a74f5 100644 --- a/app/Services/LimanService.php +++ b/app/Services/MontzarService.php @@ -6,15 +6,20 @@ use App\Models\Cnt; use App\Models\Order; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Log; +use Illuminate\Support\Facades\Schema; use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException; -class LimanService +class MontzarService { + private function config(): ConfigService + { + return app(ConfigService::class); + } private function baseUrl(): string { return rtrim( - app(ConfigService::class)->Config('liman_base_url') ?: 'https://montpar.ir', + $this->config()->Config('montzar_base_url') ?: 'https://montpar.ir', '/' ); } @@ -23,37 +28,36 @@ class LimanService { return $this->baseUrl() . '/' . ltrim($path, '/'); } - public function liman_login() + + public function montzarLogin(): string { - $config = app(ConfigService::class); + $response = Http::timeout(10) + ->acceptJson() + ->post($this->endpoint('/server/auth/login'), [ + 'mobile' => $this->config()->Config('montzar_mobile'), + 'password' => $this->config()->Config('montzar_password'), + 'provider' => 'customer', + 'type_app' => 'client', + ]) + ->json(); - $mobile = $config->Config('liman_mobile'); - $password = $config->Config('liman_password'); - - $liman = Http::timeout(10)->post($this->endpoint('/server/auth/login'), [ - 'mobile' => $mobile, - 'password' => $password, - 'provider' => 'customer', - 'type_app' => 'client', - ])->json(); - - $token = $liman['access_token'] ?? $liman['token'] ?? null; + $token = $response['access_token'] ?? $response['token'] ?? null; if (!$token) { - throw new \Exception('Liman login failed: ' . json_encode($liman, JSON_UNESCAPED_UNICODE)); + throw new \Exception('Montzar login failed: ' . json_encode($response, JSON_UNESCAPED_UNICODE)); } - $config->UpdateConfig('liman_token', $token); + $this->config()->UpdateConfig('montzar_token', $token); return $token; } public function getToken(): string { - $token = trim((string) app(ConfigService::class)->Config('liman_token')); + $token = trim((string) $this->config()->Config('montzar_token')); if (!$token) { - $token = $this->liman_login(); + $token = $this->montzarLogin(); } return $token; @@ -64,27 +68,29 @@ class LimanService $token = $this->getToken(); $response = Http::timeout(7) + ->acceptJson() ->withOptions([ 'curl' => [ CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4, CURLOPT_TCP_FASTOPEN => 1, - ] + ], ]) ->withToken($token) ->get($this->endpoint('/server/customer/product/list')) ->json(); if ((isset($response['message']) && $response['message'] === 'no authorised') || $response === null) { - $token = $this->liman_login(); + $token = $this->montzarLogin(); $response = Http::timeout(7) + ->acceptJson() ->withToken($token) ->get($this->endpoint('/server/customer/product/list')) ->json(); } if (!is_array($response)) { - throw new \Exception('Provider product list response is not array'); + throw new \Exception('Montzar product list response is not array'); } return $response; @@ -93,35 +99,34 @@ class LimanService public function sendOrder(array &$data) { $payload = $this->makeOrderPayload($data); - $token = $this->getToken(); - $httpResponse = $this->postToLiman( + $httpResponse = $this->postToMontzar( $this->endpoint('/server/customer/order'), $token, $payload ); - $body = $this->decodeLimanHttpBody($httpResponse); + $body = $this->decodeMontzarHttpBody($httpResponse); if (is_array($body) && ($body['message'] ?? null) === 'no authorised') { - $token = $this->liman_login(); + $token = $this->montzarLogin(); - $httpResponse = $this->postToLiman( + $httpResponse = $this->postToMontzar( $this->endpoint('/server/customer/order'), $token, $payload ); - $body = $this->decodeLimanHttpBody($httpResponse); + $body = $this->decodeMontzarHttpBody($httpResponse); } - $this->logLimanOrderResponse($httpResponse, $body); + $this->logMontzarOrderResponse($httpResponse, $body); - $parsed = $this->parseLimanOrderResponse($body, (int) $data['direction']); + $parsed = $this->parseMontzarOrderResponse($body, (int) $data['direction']); if (!$parsed['ok']) { - Log::warning('Liman order rejected', [ + Log::warning('Montzar order rejected', [ 'base_url' => $this->baseUrl(), 'status' => $httpResponse->status(), 'body' => $body, @@ -131,11 +136,11 @@ class LimanService ]); throw new UnprocessableEntityHttpException( - $this->formatLimanErrorMessage($parsed['error'], $httpResponse) + $this->formatMontzarErrorMessage($parsed['error'], $httpResponse) ); } - $this->syncOrderWithLimanResponse($data, $parsed); + $this->syncOrderWithMontzarResponse($data, $parsed); return $body; } @@ -143,13 +148,13 @@ class LimanService private function makeOrderPayload(array $data): array { $mazaneh = ((int) $data['direction'] === 1) - ? Cnt::where('key', 'liman_truly_buy_mazaneh')->value('value') - : Cnt::where('key', 'liman_truly_sell_mazaneh')->value('value'); + ? $this->config()->Config('montzar_truly_buy_mazaneh') + : $this->config()->Config('montzar_truly_sell_mazaneh'); - $limanPrice = (float) Cnt::where('key', 'liman_price')->value('value'); + $montzarPrice = (float) $this->config()->Config('montzar_price'); $cash = (int) round( - $data['total_price'] ?? ($limanPrice * (float) $data['amount']) + $data['total_price'] ?? ($montzarPrice * (float) $data['amount']) ); $customerName = auth('customer')->check() @@ -159,15 +164,15 @@ class LimanService return [ 'mazaneh' => (int) $mazaneh, 'amount' => (float) $data['amount'], - 'description' => app(ConfigService::class)->Config('name_fa') . ' - ' . $customerName, + 'description' => $this->config()->Config('name_fa') . ' - ' . $customerName, 'direction' => (int) $data['direction'], - 'product_id' => (int) (app(ConfigService::class)->Config('liman_product_id') ?: 25), + 'product_id' => (int) ($this->config()->Config('montzar_product_id') ?: 25), 'cash' => $cash, 'input_mode' => 'gold', ]; } - private function postToLiman(string $url, string $token, array $payload) + private function postToMontzar(string $url, string $token, array $payload) { return Http::timeout(15) ->acceptJson() @@ -175,7 +180,7 @@ class LimanService ->post($url, $payload); } - private function decodeLimanHttpBody($httpResponse): ?array + private function decodeMontzarHttpBody($httpResponse): ?array { $body = $httpResponse->json(); @@ -198,25 +203,28 @@ class LimanService return null; } - private function logLimanOrderResponse($httpResponse, $body): void + private function logMontzarOrderResponse($httpResponse, $body): void { try { $value = $body === null ? $httpResponse->body() : json_encode($body, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); - Cnt::where('key', 'liman_order_response')->update(['value' => $value]); + // مربوط به منتزر: settings + $this->config()->UpdateConfig('montzar_order_response', $value); + + // عمومی: اگر در const/Cnt داری همان‌جا بماند Cnt::where('key', 'last_order_log')->update(['value' => $value]); } catch (\Exception $e) { - Log::warning('Could not persist liman order response', [ + Log::warning('Could not persist montzar order response', [ 'error' => $e->getMessage(), ]); } } - private function formatLimanErrorMessage(?string $error, $httpResponse): string + private function formatMontzarErrorMessage(?string $error, $httpResponse): string { - if ($error && $error !== 'پاسخ نامعتبر از سرور لیمان (اتصال یا فرمت JSON)') { + if ($error && $error !== 'پاسخ نامعتبر از سرور منتظر (اتصال یا فرمت JSON)') { return $error; } @@ -224,38 +232,27 @@ class LimanService $raw = trim((string) $httpResponse->body()); if ($raw === '') { - return "خطا در ارتباط با لیمان (HTTP {$status})"; + return "خطا در ارتباط با منتظر (HTTP {$status})"; } if (stripos($raw, ' false, 'provider_id' => null, - 'error' => 'پاسخ نامعتبر از سرور لیمان (اتصال یا فرمت JSON)', + 'error' => 'پاسخ نامعتبر از سرور منتظر (اتصال یا فرمت JSON)', ]; } if (!empty($body['message']) && is_string($body['message'])) { - if ($body['message'] === 'no authorised') { - return [ - 'ok' => false, - 'provider_id' => null, - 'error' => 'no authorised', - ]; - } - return [ 'ok' => false, 'provider_id' => null, @@ -330,20 +327,18 @@ class LimanService return (int) $body['order']['id']; } - if (isset($body[1]) && is_array($body[1])) { - if (!empty($body[1]['id'])) { - return (int) $body[1]['id']; - } + foreach ([1, 2] as $index) { + if (isset($body[$index]) && is_array($body[$index])) { + if (!empty($body[$index]['id'])) { + return (int) $body[$index]['id']; + } - if (!empty($body[1]['order']['id'])) { - return (int) $body[1]['order']['id']; + if (!empty($body[$index]['order']['id'])) { + return (int) $body[$index]['order']['id']; + } } } - if (isset($body[2]) && is_array($body[2]) && !empty($body[2]['id'])) { - return (int) $body[2]['id']; - } - foreach (['buy', 'sell'] as $sideKey) { if (!isset($body[$sideKey]) || !is_array($body[$sideKey])) { continue; @@ -361,14 +356,14 @@ class LimanService return null; } - private function syncOrderWithLimanResponse(array &$data, array $parsed): void + private function syncOrderWithMontzarResponse(array &$data, array $parsed): void { - $limanDiff = (float) Cnt::where('key', 'liman_diff')->value('value'); - $limanPrice = (float) Cnt::where('key', 'liman_price')->value('value'); + $montzarDiff = (float) $this->config()->Config('montzar_diff'); + $montzarPrice = (float) $this->config()->Config('montzar_price'); - $totalPriceLiman = ((int) $data['direction'] === 1) - ? ($limanPrice + $limanDiff) - : ($limanPrice - $limanDiff); + $totalPriceMontzar = ((int) $data['direction'] === 1) + ? ($montzarPrice + $montzarDiff) + : ($montzarPrice - $montzarDiff); $providerOrderId = $parsed['provider_id'] ?? null; @@ -377,11 +372,14 @@ class LimanService $data['order']->provider_id = $providerOrderId; } - $data['order']->total_price_liman = $totalPriceLiman; + if (Schema::hasColumn('orders', 'total_price_montzar')) { + $data['order']->total_price_montzar = $totalPriceMontzar; + } + $data['order']->save(); } - $data['total_price_liman'] = $totalPriceLiman; + $data['total_price_montzar'] = $totalPriceMontzar; if ($providerOrderId !== null) { $data['provider_id'] = $providerOrderId;