From 885ed33e6e948beb8308f5d1130dedce70d8d04b Mon Sep 17 00:00:00 2001 From: adonis Date: Wed, 26 Aug 2026 16:59:27 +0330 Subject: [PATCH] feat(accounting): document colleague trades on configured accounts Post Montzar-covered buy/sell to Zarin/Tahesab/Pargar using montzar_account_* settings, and harden public storage URL/MIME handling for uploads. Co-authored-by: Cursor --- app/Http/Controllers/Admin/FileController.php | 35 +++- .../Controllers/Admin/TahesabController.php | 36 +++- .../Controllers/Admin/ZarinController.php | 44 +++- .../Pargar/PargarInboundController.php | 66 +++++- .../Controllers/PublicStorageController.php | 36 +++- .../Single/SingleOrderController.php | 9 + app/Models/File.php | 15 +- app/Services/ColleagueAccountingService.php | 191 ++++++++++++++++++ app/Services/PargarSyncService.php | 33 ++- database/sql/deploy_settings_const.sql | 26 ++- 10 files changed, 457 insertions(+), 34 deletions(-) create mode 100644 app/Services/ColleagueAccountingService.php diff --git a/app/Http/Controllers/Admin/FileController.php b/app/Http/Controllers/Admin/FileController.php index faa8339..8f3859e 100644 --- a/app/Http/Controllers/Admin/FileController.php +++ b/app/Http/Controllers/Admin/FileController.php @@ -40,9 +40,7 @@ class FileController extends Controller $path = $this->createDir(); $originalName = $uploaded->getClientOriginalName(); - $ext = $uploaded->getClientOriginalExtension() - ?: $uploaded->extension() - ?: 'jpg'; + $ext = $this->resolveUploadExtension($uploaded); $title = $request->input('title') ?: $originalName; $file_name_src = md5(time().$originalName); $file_name = $file_name_src.'.'.$ext; @@ -70,4 +68,35 @@ class FileController extends Controller return response()->json($payload); } + + /** + * پسوند واقعی فایل (MIME)، نه اسم اصلی مرورگر — آپلود بنر WebP است. + */ + private function resolveUploadExtension(\Illuminate\Http\UploadedFile $uploaded): string + { + $mime = strtolower((string) ($uploaded->getMimeType() ?: $uploaded->getClientMimeType())); + $fromMime = match (true) { + str_contains($mime, 'webp') => 'webp', + str_contains($mime, 'png') => 'png', + str_contains($mime, 'jpeg'), str_contains($mime, 'jpg') => 'jpg', + str_contains($mime, 'gif') => 'gif', + str_contains($mime, 'svg') => 'svg', + default => null, + }; + if ($fromMime) { + return $fromMime; + } + + $client = strtolower((string) $uploaded->getClientOriginalExtension()); + if (in_array($client, ['webp', 'png', 'jpg', 'jpeg', 'gif', 'svg'], true)) { + return $client === 'jpeg' ? 'jpg' : $client; + } + + $guessed = strtolower((string) $uploaded->extension()); + if (in_array($guessed, ['webp', 'png', 'jpg', 'jpeg', 'gif', 'svg'], true)) { + return $guessed === 'jpeg' ? 'jpg' : $guessed; + } + + return 'jpg'; + } } diff --git a/app/Http/Controllers/Admin/TahesabController.php b/app/Http/Controllers/Admin/TahesabController.php index 16354de..a052b27 100644 --- a/app/Http/Controllers/Admin/TahesabController.php +++ b/app/Http/Controllers/Admin/TahesabController.php @@ -453,10 +453,25 @@ class TahesabController extends Controller } $customer = Customer::where('id', $data['customer_id'])->first(); + $accountOverride = trim((string) ($data['accounting_account_code'] ?? '')); + $isColleagueLeg = ! empty($data['colleague_leg']) && $accountOverride !== ''; - if ($customer && ($customer->moshtari_code === null)) { - $this->createCustomerInTahesab($customer->id); - $customer = Customer::where('id', $data['customer_id'])->first(); + if (! $isColleagueLeg) { + if ($customer && ($customer->moshtari_code === null)) { + $this->createCustomerInTahesab($customer->id); + $customer = Customer::where('id', $data['customer_id'])->first(); + } + } + + if (! $customer) { + return false; + } + + $hesabCode = $isColleagueLeg + ? (int) $accountOverride + : (int) ($customer->moshtari_code ?? 0); + if ($hesabCode <= 0) { + return false; } $kind = $mapper->resolveKind($product); @@ -490,7 +505,14 @@ class TahesabController extends Controller $action = $isBuy ? 'خرید' : 'فروش'; $kindFa = $mapper->kindLabel($kind); - $sharh = trim($title !== '' ? "{$action} {$title}" : "{$action} {$kindFa}"); + $sharh = trim((string) ($data['sharh_override'] ?? '')); + if ($sharh === '') { + $sharh = trim($title !== '' ? "{$action} {$title}" : "{$action} {$kindFa}"); + } + + $orderId = is_object($data['order'] ?? null) + ? ($data['order']->id ?? null) + : ($data['order']['id'] ?? null); $data['handler'] = 'storeTrade'; if ($existing && empty($existing->data)) { @@ -500,21 +522,21 @@ class TahesabController extends Controller 'customer_id' => $customer->id, 'desc' => $sharh, 'amount' => $mapper->isCountDoc($product) ? $count : $vazn, - 'order_id' => $data['order']['id'] ?? null, + 'order_id' => $orderId, 'date' => $data['pay_at'] ?? Carbon::now(), 'type' => $mapper->syncTypeLabel($product), 'created_at' => Carbon::now(), 'data' => json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT), ]); - if ($mapper->isCountDoc($product) && $title === '') { + if ($mapper->isCountDoc($product) && $title === '' && ! $isColleagueLeg) { $this->sync()->markFailed($tahesab, null, 'نام محصول برای سند تعدادی ته‌حساب خالی است'); return false; } $body = $this->buildBuySaleBody( $kind, - (int) $customer->moshtari_code, + $hesabCode, (int) $year, (int) $month, (int) $day, diff --git a/app/Http/Controllers/Admin/ZarinController.php b/app/Http/Controllers/Admin/ZarinController.php index 669eeec..fdfb120 100644 --- a/app/Http/Controllers/Admin/ZarinController.php +++ b/app/Http/Controllers/Admin/ZarinController.php @@ -1394,29 +1394,49 @@ class ZarinController extends Controller } $customer = Customer::where('id', $data['customer_id'])->first(); + $accountOverride = trim((string) ($data['accounting_account_code'] ?? '')); + $isColleagueLeg = ! empty($data['colleague_leg']) && $accountOverride !== ''; - if ($customer && ($customer->moshtari_code === null)) { - $this->createCustomerInZarin($customer->id); - $customer = Customer::where('id', $data['customer_id'])->first(); + if (! $isColleagueLeg) { + if ($customer && ($customer->moshtari_code === null)) { + $this->createCustomerInZarin($customer->id); + $customer = Customer::where('id', $data['customer_id'])->first(); + } + + if (!$customer || empty($customer->moshtari_code)) { + return false; + } + } elseif (! $customer) { + return false; } - if (!$customer || empty($customer->moshtari_code)) { - return false; + $accountCustomer = $customer; + if ($isColleagueLeg) { + $accountCustomer = clone $customer; + $accountCustomer->moshtari_code = $accountOverride; } $rawAmount = (float) $data['amount']; $count = $mapper->accountingQty($product, $rawAmount, $data); $vazn = $mapper->accountingWeight($product, $rawAmount, $data); $isBuy = (int) ($data['direction'] ?? 0) === 1; - $orderId = $data['order']['id'] ?? ($existing->order_id ?? null); + $orderId = is_object($data['order'] ?? null) + ? ($data['order']->id ?? null) + : ($data['order']['id'] ?? ($existing->order_id ?? null)); $title = $mapper->productTitle($product); $action = $isBuy ? 'خرید' : 'فروش'; - $sharh = trim($title !== '' ? "{$action} {$title}" : "{$action} {$mapper->kindLabel($mapper->resolveKind($product))}"); + $sharh = trim((string) ($data['sharh_override'] ?? '')); + if ($sharh === '') { + $sharh = trim($title !== '' ? "{$action} {$title}" : "{$action} {$mapper->kindLabel($mapper->resolveKind($product))}"); + } $syncAmount = $mapper->isCountDoc($product) ? $count : $vazn; $uidSource = $orderId ?? null; if (!empty($data['line'])) { $uidSource = ($orderId ?? '0') . 'L' . (int) $data['line']; } + if ($isColleagueLeg) { + $uidSource = ($uidSource ?? '0') . 'C'; + } $data['handler'] = 'storeTrade'; if ($existing && empty($existing->data)) { @@ -1440,6 +1460,8 @@ class ZarinController extends Controller ]); } + $uidKind = $isColleagueLeg ? '11' : '10'; + try { if ($mapper->isCountDoc($product)) { $fi = (float) ($data['price'] ?? 0); @@ -1453,25 +1475,25 @@ class ZarinController extends Controller $result = $this->postZarinCountDoc( $zarin, $data, - $customer, + $accountCustomer, $product, $count, $isBuy ? -1 : 1, $fi, $sharh, - $this->zarinUid('10', $uidSource ?? $zarin->id) + $this->zarinUid($uidKind, $uidSource ?? $zarin->id) ); } else { $result = $this->postZarinWeightDoc( $zarin, $data, - $customer, + $accountCustomer, $vazn, $isBuy ? 'f' : 'k', (float) ($data['price'] ?? 0), $sharh, $mapper->jensFelez($product) ?? 0, - $this->zarinUid('10', $uidSource ?? $zarin->id) + $this->zarinUid($uidKind, $uidSource ?? $zarin->id) ); } } catch (\Exception $e) { diff --git a/app/Http/Controllers/Pargar/PargarInboundController.php b/app/Http/Controllers/Pargar/PargarInboundController.php index 0101143..0b71035 100644 --- a/app/Http/Controllers/Pargar/PargarInboundController.php +++ b/app/Http/Controllers/Pargar/PargarInboundController.php @@ -198,6 +198,25 @@ class PargarInboundController extends Controller } } + $colleagueLogs = PargarSyncLog::query() + ->where('type', PargarSyncService::TYPE_ORDER) + ->where('sync_status', PargarSyncService::STATUS_PENDING) + ->where('data', 'like', '%"colleague_leg":true%') + ->orderBy('id') + ->limit(100) + ->get(); + + foreach ($colleagueLogs as $log) { + $order = Order::find((int) ($log->order_id ?? 0)); + if (! $order) { + continue; + } + $payload = $this->orderExportPayload($order, $log); + if ($payload !== null) { + $documents->push($payload); + } + } + return response()->json([ 'state' => 'true', 'msg' => '', @@ -583,12 +602,23 @@ class PargarInboundController extends Controller /** * @return array|null */ - private function orderExportPayload(Order $order): ?array + private function orderExportPayload(Order $order, ?PargarSyncLog $forcedLog = null): ?array { $sync = $this->sync(); - $log = PargarSyncLog::where('order_id', $order->id)->latest('id')->first(); + $log = $forcedLog ?? PargarSyncLog::where('order_id', $order->id) + ->where(function ($q) { + $q->whereNull('data') + ->orWhere('data', 'not like', '%"colleague_leg":true%'); + }) + ->latest('id') + ->first(); $payload = $log ? (json_decode((string) $log->data, true) ?: []) : []; + // اگر لاگ اجباری همکار نیست و لاگ مشتری نبود، سند مشتری نساز + if ($forcedLog === null && $log && ! empty($payload['colleague_leg'])) { + return null; + } + $paymentKind = (string) ($payload['payment_kind'] ?? PargarSyncService::PAYMENT_CASH); if ($paymentKind === PargarSyncService::PAYMENT_OTHER_PRODUCT) { return null; @@ -602,6 +632,8 @@ class PargarInboundController extends Controller $isCustomerBuy = (int) ($order->direction ?? 1) === 1; $customerDirection = (int) ($order->direction ?? 0); $fromCart = (bool) ($payload['from_cart'] ?? $this->isCartOrder($order)); + $isColleagueLeg = ! empty($payload['colleague_leg']); + $colleagueAccountId = trim((string) ($payload['colleague_account_id'] ?? '')); $product = $sync->resolveOrderProduct($order, $payload); $number = (float) ($payload['number'] ?? 0); @@ -609,6 +641,22 @@ class PargarInboundController extends Controller $totalPrice = (float) ($order->total_price ?? $order->payment_amount ?? 0); $unitPrice = (float) ($order->price ?? 0); + if ($isColleagueLeg) { + if (isset($payload['direction'])) { + $isCustomerBuy = (int) $payload['direction'] === 1; + $customerDirection = (int) $payload['direction']; + } + if (isset($payload['total_price'])) { + $totalPrice = (float) $payload['total_price']; + } + if (isset($payload['price'])) { + $unitPrice = (float) $payload['price']; + } + if (isset($payload['amount'])) { + $amount = abs((float) $payload['amount']); + } + } + $isCountBased = $product ? self::isCountBasedProduct(self::productUnitPayload($product)) : false; @@ -660,11 +708,19 @@ class PargarInboundController extends Controller $totalPrice = 0; } + $accountId = $isColleagueLeg && $colleagueAccountId !== '' + ? (int) $colleagueAccountId + : (int) ($customer->pargar_account_id ?? 0); + + $description = $isColleagueLeg + ? (((int) ($payload['direction'] ?? $customerDirection) === 1) ? 'خرید از اپلیکیشن همکار' : 'فروش از اپلیکیشن همکار') + : self::accountingShopTradeDesc($customerDirection, $fromCart); + return [ - 'OrderId' => (string) $order->id, + 'OrderId' => $isColleagueLeg ? ((string) $order->id).'-C' : (string) $order->id, 'OrderType' => $isCustomerBuy ? -1 : 1, 'PriceType' => 1, - 'CustomerAccountId' => (int) ($customer->pargar_account_id ?? 0), + 'CustomerAccountId' => $accountId, 'ItemId' => $itemId, 'ItemName' => $itemName, 'OrderDate' => $order->pay_at @@ -675,7 +731,7 @@ class PargarInboundController extends Controller 'Weight' => $weight, 'Price' => $totalPrice, 'Carat' => 750, - 'Description' => self::accountingShopTradeDesc($customerDirection, $fromCart), + 'Description' => $description, ]; } diff --git a/app/Http/Controllers/PublicStorageController.php b/app/Http/Controllers/PublicStorageController.php index 2a2a44c..4beb766 100644 --- a/app/Http/Controllers/PublicStorageController.php +++ b/app/Http/Controllers/PublicStorageController.php @@ -50,9 +50,37 @@ class PublicStorageController extends Controller */ private function candidatePaths(string $path): array { - return [ - storage_path('app/public/'.$path), - public_path('storage/'.$path), - ]; + $relative = [$path, ...$this->alternateExtensionPaths($path)]; + $full = []; + foreach ($relative as $rel) { + $full[] = storage_path('app/public/'.$rel); + $full[] = storage_path('app/public/storage/'.$rel); + $full[] = public_path('storage/'.$rel); + } + + return $full; + } + + /** + * آپلود ادمین WebP می‌سازد ولی const گاهی همان هش را با .png نگه می‌دارد. + * + * @return list + */ + private function alternateExtensionPaths(string $path): array + { + if (! preg_match('/^(.*)\.([a-z0-9]+)$/i', $path, $matches)) { + return []; + } + + $stem = $matches[1]; + $ext = strtolower($matches[2]); + $out = []; + foreach (['webp', 'png', 'jpg', 'jpeg', 'gif'] as $alt) { + if ($alt !== $ext) { + $out[] = $stem.'.'.$alt; + } + } + + return $out; } } diff --git a/app/Http/Controllers/Single/SingleOrderController.php b/app/Http/Controllers/Single/SingleOrderController.php index 8cd788a..aadf1e2 100644 --- a/app/Http/Controllers/Single/SingleOrderController.php +++ b/app/Http/Controllers/Single/SingleOrderController.php @@ -263,6 +263,15 @@ class SingleOrderController extends Controller report($e); } } + + if (isset($data['order'])) { + try { + app(\App\Services\ColleagueAccountingService::class)->recordCoveredTrade($data); + } catch (\Throwable $e) { + report($e); + } + } + $response['reward'] = $this->give_order_reward($data, $wallet, $wallet_interface); if ((int) $data['direction'] === 1 && $customer) { $referrer = Customer::where('referral_id', $customer->referral_to_id)->first(); diff --git a/app/Models/File.php b/app/Models/File.php index 4e868e1..1510375 100644 --- a/app/Models/File.php +++ b/app/Models/File.php @@ -51,7 +51,9 @@ class File extends Model $trimmed = trim($path); if (preg_match('/^https?:\/\//i', $trimmed)) { - return self::rewriteWrongPublicUrl($trimmed) ?? $trimmed; + $rewritten = self::rewriteWrongPublicUrl($trimmed) ?? $trimmed; + + return self::preferHttpsUrl($rewritten); } $relative = self::normalizeRelativeStoragePath($trimmed); @@ -163,7 +165,16 @@ class File extends Model $base = 'https://'.ltrim($base, '/'); } - return $base; + return self::preferHttpsUrl($base); + } + + private static function preferHttpsUrl(string $url): string + { + if (str_contains($url, 'localhost') || str_contains($url, '127.0.0.1')) { + return $url; + } + + return (string) preg_replace('/^http:\/\//i', 'https://', $url); } private static function baseUrlFromSettings(): string diff --git a/app/Services/ColleagueAccountingService.php b/app/Services/ColleagueAccountingService.php new file mode 100644 index 0000000..e2b9709 --- /dev/null +++ b/app/Services/ColleagueAccountingService.php @@ -0,0 +1,191 @@ + $data + */ + public function recordCoveredTrade(array $data): void + { + if (! $this->config->usesMontzarPricing()) { + return; + } + + $order = $data['order'] ?? null; + if (! $order instanceof Order || ! $order->id) { + return; + } + + if (! $this->orderCoveredByColleague($order, $data)) { + return; + } + + $provider = $this->config->accountingProvider(); + $accountCode = $this->colleagueAccountCode($provider); + if ($accountCode === null) { + return; + } + + if ($this->alreadyQueued($order, $provider)) { + return; + } + + $payload = $this->buildColleaguePayload($data, $order, $accountCode); + + try { + match ($provider) { + ConfigService::ACCOUNTING_ZARIN => app(ZarinController::class)->storeTrade($payload), + ConfigService::ACCOUNTING_TAHESAB => app(TahesabController::class)->storeTrade($payload), + ConfigService::ACCOUNTING_PARGAR => $this->queuePargarColleagueTrade($order, $payload, $accountCode), + default => null, + }; + } catch (\Throwable $e) { + report($e); + } + } + + public function colleagueAccountCode(string $provider): ?string + { + $key = match ($provider) { + ConfigService::ACCOUNTING_ZARIN => 'montzar_account_zarin', + ConfigService::ACCOUNTING_TAHESAB => 'montzar_account_tahesab', + ConfigService::ACCOUNTING_PARGAR => 'montzar_account_pargar', + default => null, + }; + if ($key === null) { + return null; + } + + $code = trim($this->config->getString($key, '')); + if ($code === '' || in_array($code, ['0', '-1'], true)) { + return null; + } + + return $code; + } + + /** + * @param array $data + */ + private function orderCoveredByColleague(Order $order, array $data): bool + { + if (Schema::hasColumn('orders', 'provider_id') && ! empty($order->provider_id)) { + return true; + } + + if (! empty($data['provider_id'])) { + return true; + } + + return Schema::hasColumn('orders', 'total_price_montzar') + && $order->total_price_montzar !== null + && (float) $order->total_price_montzar > 0; + } + + private function alreadyQueued(Order $order, string $provider): bool + { + return match ($provider) { + ConfigService::ACCOUNTING_ZARIN => Zarin::query() + ->where('order_id', $order->id) + ->where('desc', 'like', '%همکار%') + ->exists(), + ConfigService::ACCOUNTING_TAHESAB => Tahesab::query() + ->where('order_id', $order->id) + ->where('desc', 'like', '%همکار%') + ->exists(), + ConfigService::ACCOUNTING_PARGAR => PargarSyncLog::query() + ->where('order_id', $order->id) + ->where('data', 'like', '%"colleague_leg":true%') + ->exists(), + default => true, + }; + } + + /** + * @param array $data + * @return array + */ + private function buildColleaguePayload(array $data, Order $order, string $accountCode): array + { + $amount = abs((float) ($order->amount ?? $data['amount'] ?? 0)); + $montzarUnit = Schema::hasColumn('orders', 'total_price_montzar') + ? (float) ($order->total_price_montzar ?? 0) + : 0.0; + $price = $montzarUnit > 0 + ? $montzarUnit + : (float) ($order->price ?? $data['price'] ?? 0); + $total = $amount * $price; + $direction = (int) ($order->direction ?? $data['direction'] ?? 0); + $action = $direction === 1 ? 'خرید' : 'فروش'; + $sharh = "{$action} از اپلیکیشن همکار"; + + $payload = $data; + $payload['order'] = $order; + $payload['customer_id'] = (int) ($order->customer_id ?? $data['customer_id'] ?? 0); + $payload['amount'] = $amount; + $payload['price'] = $price; + $payload['total_price'] = $total; + $payload['direction'] = $direction; + $payload['product_id'] = $order->product_id ?? ($data['product_id'] ?? null); + $payload['accounting_account_code'] = $accountCode; + $payload['colleague_leg'] = true; + $payload['sharh_override'] = $sharh; + $payload['pay_at'] = $order->pay_at ?? $order->created_at ?? ($data['pay_at'] ?? now()); + + return $payload; + } + + /** + * @param array $payload + */ + private function queuePargarColleagueTrade(Order $order, array $payload, string $accountCode): void + { + if (! $this->config->isPargarAccounting()) { + return; + } + + $direction = (int) ($payload['direction'] ?? 0); + $desc = (string) ($payload['sharh_override'] ?? 'معامله با اپلیکیشن همکار'); + + PargarSyncLog::create([ + 'customer_id' => $order->customer_id, + 'amount' => $payload['amount'] ?? $order->amount, + 'desc' => $desc, + 'order_id' => $order->id, + 'date' => $order->pay_at ?? $order->created_at, + 'type' => PargarSyncService::TYPE_ORDER, + 'sync_status' => PargarSyncService::STATUS_PENDING, + 'data' => json_encode([ + 'handler' => 'exportColleagueOrder', + 'colleague_leg' => true, + 'colleague_account_id' => $accountCode, + 'direction' => $direction, + 'price' => $payload['price'] ?? $order->price, + 'total_price' => $payload['total_price'] ?? $order->total_price, + 'payment_kind' => PargarSyncService::PAYMENT_CASH, + 'product_id' => $order->product_id, + 'from_cart' => false, + ], JSON_UNESCAPED_UNICODE), + ]); + } +} diff --git a/app/Services/PargarSyncService.php b/app/Services/PargarSyncService.php index 1f5503a..1ff4fb6 100644 --- a/app/Services/PargarSyncService.php +++ b/app/Services/PargarSyncService.php @@ -555,6 +555,31 @@ class PargarSyncService continue; } + if (str_ends_with(strtoupper($id), '-C')) { + $baseId = (int) substr($id, 0, -2); + if ($baseId <= 0) { + continue; + } + + $log = PargarSyncLog::query() + ->where('order_id', $baseId) + ->where('type', self::TYPE_ORDER) + ->where('sync_status', self::STATUS_PENDING) + ->where('data', 'like', '%"colleague_leg":true%') + ->latest('id') + ->first(); + + if ($log) { + $this->markSuccess($log, $id, ['OrderId' => $id]); + if ($log->customer_id) { + $customerIds[(int) $log->customer_id] = true; + } + $confirmed++; + } + + continue; + } + $order = Order::find($id); if (! $order) { continue; @@ -563,7 +588,13 @@ class PargarSyncService $order->pargar_confirmed_at = now(); $order->save(); - $log = PargarSyncLog::where('order_id', $order->id)->latest('id')->first(); + $log = PargarSyncLog::where('order_id', $order->id) + ->where(function ($q) { + $q->whereNull('data') + ->orWhere('data', 'not like', '%"colleague_leg":true%'); + }) + ->latest('id') + ->first(); if ($log) { $this->markSuccess($log, (string) $order->id, ['OrderId' => (string) $order->id]); } diff --git a/database/sql/deploy_settings_const.sql b/database/sql/deploy_settings_const.sql index 5d6ae82..2cfc286 100644 --- a/database/sql/deploy_settings_const.sql +++ b/database/sql/deploy_settings_const.sql @@ -281,6 +281,21 @@ INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `de SELECT 'montzar_product_id', '25', 'کد محصول همکار', 1, 1, NULL WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'montzar_product_id' LIMIT 1); +INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`) +SELECT 'montzar_account_zarin', '', 'کد حساب همکار در زرین', 1, 1, + 'کد حساب طرف‌حساب همکار در زرین؛ سند خرید/فروش پوشش‌شده روی همکار روی این حساب ثبت می‌شود.' +WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'montzar_account_zarin' LIMIT 1); + +INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`) +SELECT 'montzar_account_tahesab', '', 'کد حساب همکار در ته‌حساب', 1, 1, + 'کد حساب طرف‌حساب همکار در ته‌حساب؛ سند خرید/فروش پوشش‌شده روی همکار روی این حساب ثبت می‌شود.' +WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'montzar_account_tahesab' LIMIT 1); + +INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`) +SELECT 'montzar_account_pargar', '', 'کد حساب همکار در پرگار', 1, 1, + 'کد حساب طرف‌حساب همکار در پرگار؛ سند خرید/فروش پوشش‌شده روی همکار روی این حساب ثبت می‌شود.' +WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'montzar_account_pargar' LIMIT 1); + INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`) SELECT 'montzar_base_url', 'https://limangold.ir', 'آدرس سرور همکار', 1, 1, NULL WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'montzar_base_url' LIMIT 1); @@ -1301,7 +1316,9 @@ UPDATE `settings` SET `type` = 'text' WHERE `key` IN ( 'server_url', 'key', 'main_product', 'zaarbox_api_url', 'zaarbox_price_key', 'chart_id', 'etehadie_api_url', 'montzar_mobile', 'montzar_password', 'montzar_base_url', 'montzar_token', 'montzar_diff', 'montzar_live_price', 'montzar_mazaneh', - 'montzar_truly_buy_mazaneh', 'montzar_truly_sell_mazaneh', 'startDay', 'endDay', + 'montzar_truly_buy_mazaneh', 'montzar_truly_sell_mazaneh', + 'montzar_account_zarin', 'montzar_account_tahesab', 'montzar_account_pargar', + 'startDay', 'endDay', 'payping_start_url', 'payping_verify_url', 'payping_gateway_items', 'payping_fin_url', 'payping_fin_token', 'tahesab_host', 'tahesab_token', 'tahesab_db', 'pargar_username', 'pargar_password', 'pargar_api_token', @@ -1735,6 +1752,9 @@ UPDATE `settings` SET `description` = 'روشن: تطبیق کد ملی و مو UPDATE `settings` SET `description` = 'شماره موبایل حساب API سرویس همکار قیمت. برای دریافت توکن و لیست محصولات.' WHERE `key` = 'montzar_mobile'; UPDATE `settings` SET `description` = 'رمز عبور حساب API سرویس همکار قیمت. محرمانه نگه دارید.' WHERE `key` = 'montzar_password'; UPDATE `settings` SET `description` = 'شناسه محصول آبشده در API همکار. باید با محصول مرجع در سرویس خارجی یکسان باشد.' WHERE `key` = 'montzar_product_id'; +UPDATE `settings` SET `description` = 'کد حساب طرف‌حساب همکار در زرین؛ سند خرید/فروش پوشش‌شده روی همکار روی این حساب ثبت می‌شود.' WHERE `key` = 'montzar_account_zarin'; +UPDATE `settings` SET `description` = 'کد حساب طرف‌حساب همکار در ته‌حساب؛ سند خرید/فروش پوشش‌شده روی همکار روی این حساب ثبت می‌شود.' WHERE `key` = 'montzar_account_tahesab'; +UPDATE `settings` SET `description` = 'کد حساب طرف‌حساب همکار در پرگار؛ سند خرید/فروش پوشش‌شده روی همکار روی این حساب ثبت می‌شود.' WHERE `key` = 'montzar_account_pargar'; -- [super-admin can_edit=0] -- UPDATE `settings` SET `description` = 'آدرس پایه سرور API همکار (بدون اسلش انتهایی). مثال: https://example.com' WHERE `key` = 'montzar_base_url'; UPDATE `settings` SET `description` = 'توکن دسترسی API همکار. پس از ورود موفق توسط سیستم پر می‌شود؛ دستی ویرایش نکنید.' WHERE `key` = 'montzar_token'; @@ -2060,6 +2080,9 @@ UPDATE `settings` SET `title_fa` = 'باز بودن فروش همکار' WHERE ` UPDATE `settings` SET `title_fa` = 'پاسخ سفارش همکار' WHERE `key` = 'montzar_order_response'; UPDATE `settings` SET `title_fa` = 'رمز API همکار' WHERE `key` = 'montzar_password'; UPDATE `settings` SET `title_fa` = 'کد محصول همکار' WHERE `key` = 'montzar_product_id'; +UPDATE `settings` SET `title_fa` = 'کد حساب همکار در زرین' WHERE `key` = 'montzar_account_zarin'; +UPDATE `settings` SET `title_fa` = 'کد حساب همکار در ته‌حساب' WHERE `key` = 'montzar_account_tahesab'; +UPDATE `settings` SET `title_fa` = 'کد حساب همکار در پرگار' WHERE `key` = 'montzar_account_pargar'; UPDATE `settings` SET `title_fa` = 'توکن همکار (خودکار)' WHERE `key` = 'montzar_token'; UPDATE `settings` SET `title_fa` = 'مظنه خرید همکار' WHERE `key` = 'montzar_truly_buy_mazaneh'; UPDATE `settings` SET `title_fa` = 'مظنه فروش همکار' WHERE `key` = 'montzar_truly_sell_mazaneh'; @@ -2244,6 +2267,7 @@ UPDATE `settings` SET `can_edit` = 1 WHERE `key` IN ( 'min_first_buy', 'min_withdraw', 'min_deposit', 'minimum_sell', 'montzar_mobile', 'montzar_open_buy', 'montzar_open_sell', 'montzar_password', 'montzar_product_id', + 'montzar_account_zarin', 'montzar_account_tahesab', 'montzar_account_pargar', 'open_register', 'referral_id', 'referral_show', 'referral_limit', 'referral_gift_on_first_order', 'referral_gift_buy_from_montzar', 'register_jibit_verify', 'register_referral_bonus_message', 'register_referral_sms_to_referrer',