From 10a510529df3cfe3dacce0cd158fa482774d5a32 Mon Sep 17 00:00:00 2001 From: adonis Date: Mon, 20 Jul 2026 21:29:30 +0330 Subject: [PATCH] added banning for when amount is under 0 --- .../Controllers/Customer/CartController.php | 1 + .../Single/SingleOrderController.php | 2 ++ app/Services/ConfigService.php | 30 +++++++++++++++++++ database/sql/deploy_settings_const.sql | 15 ++++++++++ 4 files changed, 48 insertions(+) diff --git a/app/Http/Controllers/Customer/CartController.php b/app/Http/Controllers/Customer/CartController.php index eddf3b8..150a4ab 100644 --- a/app/Http/Controllers/Customer/CartController.php +++ b/app/Http/Controllers/Customer/CartController.php @@ -421,6 +421,7 @@ class CartController extends Controller } app(ConfigService::class)->assertProductTradingOpen($product); + app(ConfigService::class)->assertMainGoldZeroBeforeOtherProductBuy($wallet_interface->wallet, $product); $qty = (int) $item->quantity; diff --git a/app/Http/Controllers/Single/SingleOrderController.php b/app/Http/Controllers/Single/SingleOrderController.php index f6384ce..1b7d3c0 100644 --- a/app/Http/Controllers/Single/SingleOrderController.php +++ b/app/Http/Controllers/Single/SingleOrderController.php @@ -118,6 +118,8 @@ class SingleOrderController extends Controller // Check if the user wants to buy if ($data['direction'] == 1) { + $config->assertMainGoldZeroBeforeOtherProductBuy($wallet, $data['product']); + $data['service_charge_percentage'] = isset($data['fee_free']) && $data['fee_free'] === true ? 0 : ($data['product']['percent_fee_buy']) * $data['number']; $data['price_original'] = $this->resolveProductUnitBasePrice($data['product']); $this->applyCashPriceDiff($config, $data['product'], 1, $data, (float) $data['price_original']); diff --git a/app/Services/ConfigService.php b/app/Services/ConfigService.php index b9e9feb..39bc9a2 100644 --- a/app/Services/ConfigService.php +++ b/app/Services/ConfigService.php @@ -695,6 +695,36 @@ class ConfigService } } + /** + * سوییچ require_zero_main_gold_before_other_buy (پیش‌فرض true). + * اگر مانده طلای کیف اصلی صفر یا زیر صفر باشد (منفی)، خرید محصول خارج از کیف اصلی + * تا صفر شدن بدهی مسدود است. معامله خودِ محصولات main_wallet_products همیشه مجاز است. + * + * @param object|null $mainWallet کیف اصلی (product_id=null) با فیلد gold + */ + public function assertMainGoldZeroBeforeOtherProductBuy(?object $mainWallet, Product $product): void + { + if (!$this->getBool('require_zero_main_gold_before_other_buy', true)) { + return; + } + + $productId = (int) ($product->id ?? 0); + if ($productId <= 0 || $this->isMainWalletProduct($productId)) { + return; + } + + $gold = (float) ($mainWallet->gold ?? 0); + // صفر = از قبل تسویه؛ فقط بدهی (زیر صفر) مسدود می‌کند + if ($gold >= 0) { + return; + } + + $label = $this->mainWalletProductLabels() ?: 'آبشده / کیف اصلی'; + throw new UnprocessableEntityHttpException( + "مانده طلای کیف اصلی منفی است. ابتدا مانده «{$label}» را صفر کنید، سپس می‌توانید محصول دیگر بخرید." + ); + } + public const ACCOUNTING_NONE = 'none'; public const ACCOUNTING_TAHESAB = 'tahesab'; public const ACCOUNTING_PARGAR = 'pargar'; diff --git a/database/sql/deploy_settings_const.sql b/database/sql/deploy_settings_const.sql index 2fa8388..3954e1c 100644 --- a/database/sql/deploy_settings_const.sql +++ b/database/sql/deploy_settings_const.sql @@ -897,6 +897,7 @@ UPDATE `settings` SET `type` = 'switch' WHERE `key` IN ( 'jibit_verification', 'register_jibit_verify', 'open_register', 'auto_active_customer', 'close_price', 'show_last_price', 'show_gold_ounce_price', 'fee_deduct_from_gold', + 'require_zero_main_gold_before_other_buy', 'profit_gold_api_enabled', 'payping_round_toman', 'payping_strict_failed_withdraw', 'has_page_earn_money', 'charge_notif', 'group_sms', 'sms_panel', 'customer_direct_sms', 'sms_notif_order_admin', 'sms_notif_order_customer', @@ -1008,6 +1009,11 @@ SELECT 'main_wallet_products', '13', 'محصولات متصل به کیف اصل 'محصولاتی که موجودی‌شان از کیف طلای اصلی خوانده می‌شود. چند محصول با کاما. پیش‌فرض: 13' WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'main_wallet_products' LIMIT 1); +INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`, `type`) +SELECT 'require_zero_main_gold_before_other_buy', 'true', 'الزام صفر بودن کیف اصلی قبل از خرید محصول دیگر', 0, 1, + 'روشن: اگر مانده طلای کیف اصلی صفر یا زیر صفر باشد (بدهی)، مشتری ابتدا باید آبشده/مانده کیف اصلی را صفر کند و بعد می‌تواند محصول دیگر بخرد. خاموش: بدون این محدودیت. معامله خودِ محصولات کیف اصلی همیشه مجاز است.', 'switch' +WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'require_zero_main_gold_before_other_buy' LIMIT 1); + INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`, `type`) SELECT 'apk_download_link', '', 'لینک دانلود اپ اندروید', 0, 1, 'آدرس کامل فایل APK اندروید (https). اگر خالی باشد لینک دانلود در اپ نمایش داده نمی‌شود.', 'text' @@ -1357,6 +1363,13 @@ UPDATE `settings` SET `description` = 'روشن: پنل پیامک و کیف پ UPDATE `settings` SET `description` = 'محصولاتی که موجودی‌شان از کیف طلای اصلی خوانده می‌شود. چند محصول با کاما. پیش‌فرض: 13' WHERE `key` = 'main_wallet_products'; UPDATE `settings` SET `value` = '13' WHERE `key` = 'main_wallet_products' AND TRIM(COALESCE(`value`, '')) = ''; UPDATE `settings` SET `can_edit` = 0 WHERE `key` = 'main_wallet_products'; +UPDATE `settings` SET + `title_fa` = 'الزام صفر بودن کیف اصلی قبل از خرید محصول دیگر', + `type` = 'switch', + `can_edit` = 0, + `description` = 'روشن: اگر مانده طلای کیف اصلی صفر یا زیر صفر باشد (بدهی)، مشتری ابتدا باید آبشده/مانده کیف اصلی را صفر کند و بعد می‌تواند محصول دیگر بخرد. خاموش: بدون این محدودیت. معامله خودِ محصولات کیف اصلی همیشه مجاز است.' +WHERE `key` = 'require_zero_main_gold_before_other_buy'; +UPDATE `settings` SET `title_fa` = 'الزام صفر بودن کیف اصلی قبل از خرید محصول دیگر' WHERE `key` = 'require_zero_main_gold_before_other_buy'; UPDATE `settings` SET `description` = 'روشن: API محاسبه سود طلا فعال است. در اکثر نصب‌ها خاموش می‌ماند.' WHERE `key` = 'profit_gold_api_enabled'; -- --------------------------------------------------------------------------- @@ -1464,6 +1477,7 @@ UPDATE `settings` SET `title_fa` = 'نام فلز اصلی (ادمین)' WHERE ` UPDATE `settings` SET `title_fa` = 'محصول آبشده' WHERE `key` = 'main_product'; UPDATE `settings` SET `title_fa` = 'قیمت از محصول (legacy)' WHERE `key` = 'main_product_price'; UPDATE `settings` SET `title_fa` = 'محصولات متصل به کیف اصلی' WHERE `key` = 'main_wallet_products'; +UPDATE `settings` SET `title_fa` = 'الزام صفر بودن کیف اصلی قبل از خرید محصول دیگر' WHERE `key` = 'require_zero_main_gold_before_other_buy'; UPDATE `settings` SET `title_fa` = 'عنوان فلز در UI' WHERE `key` = 'metal_type'; UPDATE `settings` SET `title_fa` = 'حداقل اولین خرید (ریال)' WHERE `key` = 'min_first_buy'; UPDATE `settings` SET `title_fa` = 'حداقل برداشت (ریال)' WHERE `key` = 'min_withdraw'; @@ -1566,6 +1580,7 @@ UPDATE `settings` SET `can_edit` = 0 WHERE `key` IN ( 'sms_panel', 'logo_login', 'logo_register', 'title_pwa', 'title_fav', 'main_product', 'main_wallet_products', 'metal_type', 'main_metal', + 'require_zero_main_gold_before_other_buy', 'montify_name', 'montzar_base_url', 'montzar_closed', 'montzar_diff', 'montzar_last_product_log', 'montzar_live_price', 'montzar_mazaneh',