From aecbd5b3bfcbed7469d8942e246c4625d373723e Mon Sep 17 00:00:00 2001 From: safavimohadeseh78 Date: Sat, 12 Sep 2026 10:12:43 +0330 Subject: [PATCH] changes of giftcard --- .../abshode-domain-lookup/learned-notes.md | 4 + .../Controllers/Admin/GiftCardController.php | 105 +++++++++++++----- app/Models/Withdraw.php | 9 +- 3 files changed, 86 insertions(+), 32 deletions(-) diff --git a/.cursor/skills/abshode-domain-lookup/learned-notes.md b/.cursor/skills/abshode-domain-lookup/learned-notes.md index 519c7ce..3a992d5 100644 --- a/.cursor/skills/abshode-domain-lookup/learned-notes.md +++ b/.cursor/skills/abshode-domain-lookup/learned-notes.md @@ -9,4 +9,8 @@ - 2026-09-08 | لیست گیفت کاربر | `GiftCardController::mine` + `GET customer/giftcard/mine` + `GiftCardCodes::giftcard` | available=اختصاصی+عمومی تک‌کد use_once=0؛ history از assigned_to - 2026-09-09 | «کد قابل استفاده» خالی در اپ | `routes/customer.php` + `GiftCardController::mine` | مسیر `GET customer/giftcard/mine` هنوز کامیت/دیپلوی نشده؛ سرور واقعی ۴۰۴ می‌دهد (use و me → ۴۰۱) پس لیست همیشه خالی است - 2026-09-09 | کارت هدیه فلزی | `GiftCardController::useGiftCard` | unit=2 دیگر «در دست ساخت» نیست؛ شارژ gold کیف اصلی + سینک ته‌حساب/زرین/پرگار؛ used_count فقط بعد از موفقیت +- 2026-09-12 | واریز کیف‌پول + هدیه ریالی | `Withdraw::scopeDeposits` | note«کارت هدیه» با cash>0 در لیست واریز می‌آید؛ هدیه مسی (فقط gold) نه +- 2026-09-12 | پیامک کارت هدیه | `GiftCardController::useGiftCard` | پسوند SMS: ریالی→«قلک ریال»، فلزی→«قلک مس» (نه name_fa / قلک طلا) +- 2026-09-12 | تعداد کد هدیه | `GiftCardController::redeem` | count=N → N کارت جدا هرکدام ۱ کد یکتا + مبلغ کامل؛ store هم برای unit 1/2 چندکد می‌سازد +- 2026-09-12 | انقضای کارت هدیه | `GiftCardController::validateGiftExpiryDate` + `GiftCardEditorFormBody` | تاریخ قبل از امروز → ۴۰۰ / خطای فرم؛ امروز مجاز - 2026-09-09 | رمز ادمین ≠ لاگین اپ | `Customer::setPasswordAttribute` + `AuthController` + `updateAdmin` | قبل از هش/لاگین ارقام فارسی→انگلیسی؛ jwt hash=false؛ آنلاین فقط password غیرخالی بفرست diff --git a/app/Http/Controllers/Admin/GiftCardController.php b/app/Http/Controllers/Admin/GiftCardController.php index eb4da98..9cc5402 100644 --- a/app/Http/Controllers/Admin/GiftCardController.php +++ b/app/Http/Controllers/Admin/GiftCardController.php @@ -25,39 +25,47 @@ class GiftCardController extends Controller } $user = auth()->user(); - $count = $request->count; + $count = (int) $request->count; $amount = $request->amount; if(!$user){ throw new UnprocessableEntityHttpException('auth failed!'); } - $codes = []; - if((!is_numeric($count) || $count < 0) || (!is_numeric($amount) || $amount <= 0)){ + if((!is_numeric($request->count) || $count < 1) || (!is_numeric($amount) || $amount <= 0)){ return response()->json(['message' => 'تعداد کد را چک کنید!'], 400); } + + $expiryError = $this->validateGiftExpiryDate($request->expiry_date); + if ($expiryError !== null) { + return response()->json(['message' => $expiryError], 400); + } + $customer = Customer::select('id', 'name', 'mobile')->where('mobile', $request->mobile)->first(); - $gift = GiftCard::create([ - 'customer_id' => $customer->id ?? null, - 'count' => $count, - 'amount' => $amount, - 'mobile' => $request->mobile ?? null, - 'name' => ($customer ? $customer->name : $request->name) ?? null, - 'amount' => $amount, - 'total' => $count*$amount, - 'sts' => 1, - 'unit' => $request->unit, - 'expiry_date' => $request->expiry_date, - 'created_at' => now(), - 'updated_at' => now(), - 'description' => $request->description, - ]); - + // هر عدد از «تعداد کدها» = یک کارت هدیه جدا + یک کد یکتا با همان مبلغ شارژ + $createdGifts = []; + $createdCodes = []; for ($i = 0; $i < $count; $i++) { do { $unique_code = strtoupper(bin2hex(random_bytes(4))); } while (GiftCardCodes::where('code', $unique_code)->exists()); - $codes[] = [ + $gift = GiftCard::create([ + 'customer_id' => $customer->id ?? null, + 'count' => 1, + 'amount' => $amount, + 'mobile' => $request->mobile ?? null, + 'name' => ($customer ? $customer->name : $request->name) ?? null, + 'unique_code' => $unique_code, + 'total' => $amount, + 'sts' => 1, + 'unit' => $request->unit, + 'expiry_date' => $request->expiry_date, + 'created_at' => now(), + 'updated_at' => now(), + 'description' => $request->description, + ]); + + GiftCardCodes::insert([ 'giftcard_id' => $gift->id, 'code' => $unique_code, 'sts' => 1, @@ -65,15 +73,18 @@ class GiftCardController extends Controller 'amount' => $amount, 'expiry_date' => $request->expiry_date, 'created_at' => now(), - ]; + ]); + + $createdGifts[] = $gift->load('giftcardcodes'); + $createdCodes[] = $unique_code; } - GiftCardCodes::insert($codes); return response()->json([ 'customer' => $customer ?? null, - 'order' => $gift, - 'codes' => $gift->giftcardcodes, - 'total' => $count*$amount, + 'order' => $createdGifts[0] ?? null, + 'orders' => $createdGifts, + 'codes' => $createdCodes, + 'total' => $count * $amount, ]); } @@ -164,7 +175,7 @@ class GiftCardController extends Controller $message = "$user->name عزیز کیف پول شما به مقدار $amount ریال به واسطه کارت هدیه از طرف $gift->name شارژ شد. - ".$this->Config('name_fa'); + قلک ریال"; }elseif ($unit === 2){ // شارژ کیف فلزی (طلا / مس — فیلد gold کیف اصلی) @@ -253,7 +264,7 @@ class GiftCardController extends Controller $message = "$user->name عزیز کیف $metalLabel شما به مقدار $formattedGold $weightUnit به واسطه کارت هدیه از طرف $gift->name شارژ شد. - ".$this->Config('name_fa'); + قلک مس"; try { app(\App\Services\CustomerAppNotifyService::class)->notifyCustomer( @@ -428,6 +439,28 @@ class GiftCardController extends Controller ]); } + /** + * تاریخ انقضا نباید قبل از امروز باشد (امروز مجاز است). + */ + private function validateGiftExpiryDate(mixed $expiryDate): ?string + { + if ($expiryDate === null || $expiryDate === '') { + return 'تاریخ انقضا الزامی است.'; + } + + try { + $expiryDay = \Carbon\Carbon::parse($expiryDate)->startOfDay(); + } catch (\Throwable $e) { + return 'تاریخ انقضا نامعتبر است.'; + } + + if ($expiryDay->lt(now()->startOfDay())) { + return 'تاریخ انقضا نمی‌تواند قبل از امروز باشد.'; + } + + return null; + } + private function isCodeExpired(GiftCardCodes $code, GiftCard $gift): bool { if ($code->expiry_date && $code->expiry_date <= now()) { @@ -523,24 +556,32 @@ class GiftCardController extends Controller private function storeRedeem(Request $request) { $user = auth()->user(); - $count = $request->count; + $count = (int) $request->count; $amount = $request->amount; if (! $user) { throw new UnprocessableEntityHttpException('auth failed!'); } - if ((! is_numeric($count) || $count < 0) || (! is_numeric($amount) || $amount <= 0)) { + if ((! is_numeric($request->count) || $count < 1) || (! is_numeric($amount) || $amount <= 0)) { return response()->json(['message' => 'تعداد کد را چک کنید!'], 400); } + $expiryError = $this->validateGiftExpiryDate($request->expiry_date); + if ($expiryError !== null) { + return response()->json(['message' => $expiryError], 400); + } + if (isset($request->code) && GiftCardCodes::where('code', $request->code)->where('unit', $request->unit)->exists()) { return response()->json(['message' => 'کد تکراری میباشد!'], 400); } $codes = []; $unitAmount = $request->unit == 3 ? $amount / 100 : $amount; + $unit = (int) $request->unit; + // کارت هدیه (ریالی/فلزی): همیشه N کد یکتا؛ تخفیف با use_once=0 می‌تواند تک‌کد مشترک باشد + $createUniqueCodes = $request->use_once || $unit === 1 || $unit === 2; - if ($request->use_once) { + if ($createUniqueCodes) { $gift = GiftCard::create([ 'use_once' => $request->use_once ? 1 : 0, 'count' => $count, @@ -572,6 +613,10 @@ class GiftCardController extends Controller ]; } GiftCardCodes::insert($codes); + if ($count === 1) { + $gift->unique_code = $codes[0]['code']; + $gift->save(); + } } else { do { $unique_code = strtoupper(bin2hex(random_bytes(4))); diff --git a/app/Models/Withdraw.php b/app/Models/Withdraw.php index 38735d6..b8a28c7 100644 --- a/app/Models/Withdraw.php +++ b/app/Models/Withdraw.php @@ -109,14 +109,19 @@ class Withdraw extends Model }); } - /** واریز: ورود پول/طلا به کیف (درگاه، شارژ ادمین، پاداش) — بدون کسر ادمین */ + /** واریز: ورود پول/طلا به کیف (درگاه، شارژ ادمین، پاداش، کارت هدیه ریالی) — بدون کسر ادمین */ public static function scopeDeposits($query) { return $query->where(function ($q) { $q->where(function ($inner) { $inner->where('note', 'like', '%واریز%') ->orWhere('type', 1) - ->orWhereIn('sts', [4, 5, 9]); + ->orWhereIn('sts', [4, 5, 9]) + // کارت هدیه ریالی (نه فلزی/مسی) + ->orWhere(function ($gift) { + $gift->where('note', 'like', '%کارت هدیه%') + ->where('cash', '>', 0); + }); })->where(function ($excludeWithdrawNotes) { $excludeWithdrawNotes->whereNull('note') ->orWhere('note', 'not like', '%برداشت%');