diff --git a/app/Http/Controllers/Admin/MassageController.php b/app/Http/Controllers/Admin/MassageController.php index 63f1620..2971137 100644 --- a/app/Http/Controllers/Admin/MassageController.php +++ b/app/Http/Controllers/Admin/MassageController.php @@ -18,11 +18,26 @@ class MassageController extends Controller { public function send_message(Request $request) { - if($this->Config('group_sms') == 'false'){ + if (! app(ConfigService::class)->getBool('group_sms', false)) { throw new UnprocessableEntityHttpException('پیامک گروهی غیرفعال است.'); } + + $numbers = array_values(array_unique(array_filter( + array_map('strval', (array) ($request->numbers ?? [])), + static fn ($n) => trim($n) !== '' + ))); + + if ($numbers === []) { + throw new UnprocessableEntityHttpException('حداقل یک شماره لازم است.'); + } + + // هر درخواست حداکثر ۱۰ شماره — ادمین باید دسته‌ای بفرستد تا پنل پیامک زیر فشار نرود + if (count($numbers) > 10) { + throw new UnprocessableEntityHttpException('در هر درخواست حداکثر ۱۰ شماره مجاز است.'); + } + // یافتن مشتریان با شماره‌های داده شده - $customers = Customer::whereIn('mobile', $request->numbers)->get(); + $customers = Customer::whereIn('mobile', $numbers)->get(); $filter = app(SmsProfanityFilter::class); $filter->assertClean((string) ($request->message ?? '')); @@ -35,6 +50,15 @@ class MassageController extends Controller $this->send($customer->mobile, $message); } + // شماره‌های دستی که مشتری در DB ندارند + $known = $customers->pluck('mobile')->all(); + foreach ($numbers as $mobile) { + if (in_array($mobile, $known, true)) { + continue; + } + $this->send($mobile, (string) $request->message); + } + return response()->json(true); } diff --git a/app/Http/Controllers/Admin/OrderController.php b/app/Http/Controllers/Admin/OrderController.php index 3ca77f6..723f8ec 100644 --- a/app/Http/Controllers/Admin/OrderController.php +++ b/app/Http/Controllers/Admin/OrderController.php @@ -6,8 +6,10 @@ use App\DB\Te\TableEngine; use App\Http\Controllers\Controller; use App\Models\Order; use App\Services\BalanceReportService; +use App\Services\ConfigService; use App\Services\WalletBalanceService; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Schema; class OrderController extends Controller { @@ -72,4 +74,75 @@ class OrderController extends Controller return response()->json($records); } + + /** + * سفارش‌هایی که نزد همکار (Montzar) ثبت شده‌اند — فقط وقتی منبع قیمت montzar است. + */ + public function colleagueTable(Request $request) + { + $config = app(ConfigService::class); + if (!$config->usesMontzarPricing()) { + return response()->json([ + 'message' => 'این لیست فقط وقتی منبع قیمت montzar است در دسترس است.', + ], 422); + } + + $hasProvider = Schema::hasColumn('orders', 'provider_id'); + $hasMontzarPrice = Schema::hasColumn('orders', 'total_price_montzar'); + + if (!$hasProvider && !$hasMontzarPrice) { + return response()->json([ + 'rows' => [], + 'total' => 0, + ]); + } + + $records = Order::with([ + 'customer:id,name,mobile', + 'product' => static function ($q) { + $q->withTrashed()->select(['id', 'title', 'unit']); + }, + ])->where(function ($q) use ($hasProvider, $hasMontzarPrice) { + if ($hasProvider) { + $q->whereNotNull('provider_id'); + } + if ($hasMontzarPrice) { + if ($hasProvider) { + $q->orWhereNotNull('total_price_montzar'); + } else { + $q->whereNotNull('total_price_montzar'); + } + } + }); + + TableEngine::create($records, $request->all()) + ->initSearch(['customer.name', 'customer.mobile']) + ->select([ + '*', Order::$SELECT_STS_STR + ])->export($records); + + if (isset($records['rows'])) { + foreach ($records['rows'] as &$row) { + $amount = (float) ($row['amount'] ?? 0); + $serviceCharge = (float) ($row['service_charge'] ?? 0); + $feeAsset = (string) ($row['fee_asset'] ?? 'rial'); + $montzarUnit = $hasMontzarPrice ? (float) ($row['total_price_montzar'] ?? 0) : 0.0; + + // وقتی کارمزد از طلا کم شده، مقدار اولیهٔ مشتری = مقدار نزد همکار + کارمزد + $customerAmount = $feeAsset === 'gold' + ? round($amount + $serviceCharge, 3) + : round($amount, 3); + + $row['customer_amount'] = $customerAmount; + $row['colleague_amount'] = round($amount, 3); + $row['colleague_unit_price'] = (int) round($montzarUnit); + $row['colleague_total_price'] = (int) round($amount * $montzarUnit); + $row['direction_label'] = Order::$DIRECTION[(int) ($row['direction'] ?? 0)] + ?? (string) ($row['direction'] ?? ''); + } + unset($row); + } + + return response()->json($records); + } } diff --git a/database/sql/deploy_settings_const.sql b/database/sql/deploy_settings_const.sql index 782b568..5b60354 100644 --- a/database/sql/deploy_settings_const.sql +++ b/database/sql/deploy_settings_const.sql @@ -548,8 +548,10 @@ INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `de SELECT 'referral_limit', '', 'محدودیت دعوت', 1, 1, NULL WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'referral_limit' LIMIT 1); -INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`) -SELECT 'group_sms', 'false', 'پیامک گروهی', 1, 1, NULL +INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`, `type`) +SELECT 'group_sms', 'false', 'پیامک گروهی', 0, 1, + 'روشن: دکمه ارسال پیامک گروهی در پنل ادمین فعال است (ارسال ۱۰تایی). خاموش: ارسال پیامک گروهی غیرفعال است. فقط از تنظیمات پیشرفته.', + 'switch' WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'group_sms' LIMIT 1); INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`, `type`) @@ -1668,7 +1670,7 @@ UPDATE `settings` SET `title_fa` = 'کارت هدیه' WHERE `key` = 'has_page_g UPDATE `settings` SET `description` = 'روشن: منوی «ثبت کارت هدیه» و صفحه ثبت کد در اپ کاربر فعال است. خاموش: منو و صفحه مخفی است و API استفاده از کد هدیه در دسترس نیست. فقط از دیپلوی قابل تغییر است.' WHERE `key` = 'has_page_gift_card'; UPDATE `settings` SET `title_fa` = 'سود چندسطحی معرف' WHERE `key` = 'enable_customer_level_profit'; UPDATE `settings` SET `description` = 'روشن: در لیست مشتریان آیکون تنظیم درصد سود هر سطح زیرمجموعه فعال است و پس از سفارش، سهم کارمزد طبق درصدهای هر معرف به کیف طلا واریز می‌شود. خاموش: آیکون و واریز سود چندسطحی غیرفعال است. فقط از دیپلوی قابل تغییر است.' WHERE `key` = 'enable_customer_level_profit'; -UPDATE `settings` SET `description` = 'روشن: امکان ارسال پیامک گروهی از پنل ادمین فعال است.' WHERE `key` = 'group_sms'; +UPDATE `settings` SET `description` = 'روشن: دکمه ارسال پیامک گروهی در پنل ادمین فعال است (ارسال ۱۰تایی). خاموش: ارسال پیامک گروهی غیرفعال است. فقط از تنظیمات پیشرفته.' WHERE `key` = 'group_sms'; UPDATE `settings` SET `description` = 'روشن: پنل پیامک و کیف پول billing فعال است. خاموش: پیامک‌ها مثل قبل ارسال می‌شوند بدون billing.' WHERE `key` = 'sms_panel'; UPDATE `settings` SET `description` = 'محصولاتی که موجودی‌شان از کیف طلای اصلی خوانده می‌شود. چند محصول با کاما. پیش‌فرض: 13' WHERE `key` = 'main_wallet_products'; diff --git a/database/sql/deploy_settings_const_preserve_value_sync_can_edit.sql b/database/sql/deploy_settings_const_preserve_value_sync_can_edit.sql index 019815a..7581642 100644 --- a/database/sql/deploy_settings_const_preserve_value_sync_can_edit.sql +++ b/database/sql/deploy_settings_const_preserve_value_sync_can_edit.sql @@ -491,8 +491,10 @@ INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `de SELECT 'referral_limit', '', 'محدودیت دعوت', 1, 1, NULL WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'referral_limit' LIMIT 1); -INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`) -SELECT 'group_sms', 'false', 'پیامک گروهی', 1, 1, NULL +INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`, `type`) +SELECT 'group_sms', 'false', 'پیامک گروهی', 0, 1, + 'روشن: دکمه ارسال پیامک گروهی در پنل ادمین فعال است (ارسال ۱۰تایی). خاموش: ارسال پیامک گروهی غیرفعال است. فقط از تنظیمات پیشرفته.', + 'switch' WHERE NOT EXISTS (SELECT 1 FROM `settings` WHERE `key` = 'group_sms' LIMIT 1); INSERT INTO `settings` (`key`, `value`, `title_fa`, `can_edit`, `is_active`, `description`, `type`) @@ -1405,7 +1407,7 @@ UPDATE `settings` SET `description` = 'روشن: وقتی مشتری اولین UPDATE `settings` SET `description` = 'رمز مشترک بین لاراول و سرور چت برای اعلان پیام پشتیبانی. فقط سرور؛ در صورت خالی بودن به‌صورت خودکار ساخته می‌شود.' WHERE `key` = 'chat_webhook_secret'; UPDATE `settings` SET `title_fa` = 'پیامک پیام پشتیبانی به ادمین' WHERE `key` = 'sms_notif_support_admin'; UPDATE `settings` SET `title_fa` = 'رمز وب‌هوک چت' WHERE `key` = 'chat_webhook_secret'; -UPDATE `settings` SET `description` = 'روشن: امکان ارسال پیامک گروهی از پنل ادمین فعال است.' WHERE `key` = 'group_sms'; +UPDATE `settings` SET `description` = 'روشن: دکمه ارسال پیامک گروهی در پنل ادمین فعال است (ارسال ۱۰تایی). خاموش: ارسال پیامک گروهی غیرفعال است. فقط از تنظیمات پیشرفته.' WHERE `key` = 'group_sms'; UPDATE `settings` SET `description` = 'روشن: پنل پیامک و کیف پول billing فعال است. خاموش: پیامک‌ها مثل قبل ارسال می‌شوند بدون billing.' WHERE `key` = 'sms_panel'; UPDATE `settings` SET `description` = 'محصولاتی که موجودی‌شان از کیف طلای اصلی خوانده می‌شود. چند محصول با کاما. پیش‌فرض: 13' WHERE `key` = 'main_wallet_products'; diff --git a/routes/admin.php b/routes/admin.php index 9539b7a..f5010d0 100644 --- a/routes/admin.php +++ b/routes/admin.php @@ -164,6 +164,7 @@ Route::middleware('auth:user')->group(function (){ //---------------order Route::post('order/table', [OrderController::class, 'table']); Route::post('order/single/table', [OrderController::class, 'singleOrderTable']); + Route::post('order/colleague/table', [OrderController::class, 'colleagueTable']); Route::post('single/order', [SingleOrderController::class, 'store']); //-------------------price