change gift-card

This commit is contained in:
2026-09-21 11:09:40 +03:30
parent ba2ac5aefe
commit 698fbed805
4 changed files with 105 additions and 20 deletions
@@ -39,7 +39,7 @@ class GiftCardController extends Controller
return response()->json(['message' => $expiryError], 400); return response()->json(['message' => $expiryError], 400);
} }
$customer = Customer::select('id', 'name', 'mobile')->where('mobile', $request->mobile)->first(); $customer = $this->resolveGiftCardCustomerForCreate($request);
$gift = $this->createGiftCardWithUniqueCodes($request, $customer); $gift = $this->createGiftCardWithUniqueCodes($request, $customer);
$createdCodes = $gift->giftcardcodes->pluck('code')->all(); $createdCodes = $gift->giftcardcodes->pluck('code')->all();
@@ -342,6 +342,10 @@ class GiftCardController extends Controller
continue; continue;
} }
if (! $this->isPublicGiftVisibleInApp($gift)) {
continue;
}
$codes = $gift->giftcardcodes $codes = $gift->giftcardcodes
->filter(function ($code) use ($gift) { ->filter(function ($code) use ($gift) {
return (int) $code->sts !== 2 return (int) $code->sts !== 2
@@ -350,23 +354,16 @@ class GiftCardController extends Controller
}) })
->values(); ->values();
// عمومی: فقط پویش تک‌کد مشترک (جلوگیری از افشای بچ تصادفی) foreach ($codes as $code) {
if ($codes->count() !== 1 && empty($gift->unique_code)) { if ($this->customerAlreadyUsedCode($code, $customerId, $gift)) {
continue; continue;
}
if (isset($seenCodes[$code->code])) {
continue;
}
$seenCodes[$code->code] = true;
$available[] = $this->mapCustomerGiftItem($gift, $code, 'public');
} }
$code = $codes->first();
if (! $code) {
continue;
}
if ($this->customerAlreadyUsedCode($code, $customerId, $gift)) {
continue;
}
if (isset($seenCodes[$code->code])) {
continue;
}
$seenCodes[$code->code] = true;
$available[] = $this->mapCustomerGiftItem($gift, $code, 'public');
} }
$history = []; $history = [];
@@ -403,11 +400,55 @@ class GiftCardController extends Controller
]); ]);
} }
private function resolveGiftCardCustomer(Request $request): ?Customer
{
if ($request->filled('customer_id')) {
return Customer::select('id', 'name', 'mobile')->find((int) $request->customer_id);
}
if ($request->filled('mobile')) {
return Customer::select('id', 'name', 'mobile')->where('mobile', $request->mobile)->first();
}
return null;
}
/**
* کارت عمومی: show_in_app=1 → در لیست اپ همه؛ ۰ → فقط با وارد کردن دستی کد.
* سازگاری با رکوردهای قبل از ستون show_in_app: تک‌کد مشترک مثل قبل در اپ می‌آید.
*/
private function isPublicGiftVisibleInApp(GiftCard $gift): bool
{
if (! isset($gift->show_in_app)) {
$codesCount = $gift->relationLoaded('giftcardcodes')
? $gift->giftcardcodes->count()
: $gift->giftcardcodes()->count();
return $codesCount === 1 || ! empty($gift->unique_code);
}
return (int) $gift->show_in_app === 1;
}
private function resolveGiftCardCustomerForCreate(Request $request): ?Customer
{
$customer = $this->resolveGiftCardCustomer($request);
if ($request->filled('customer_id') && ! $customer) {
throw new UnprocessableEntityHttpException('مشتری انتخاب‌شده یافت نشد!');
}
return $customer;
}
/** /**
* یک رکورد giftcards + N کد یکتا در giftcard_codes (نه N رکورد جدا). * یک رکورد giftcards + N کد یکتا در giftcard_codes (نه N رکورد جدا).
*/ */
private function createGiftCardWithUniqueCodes(Request $request, ?Customer $customer = null): GiftCard private function createGiftCardWithUniqueCodes(Request $request, ?Customer $customer = null): GiftCard
{ {
if ($customer === null) {
$customer = $this->resolveGiftCardCustomer($request);
}
$count = (int) $request->count; $count = (int) $request->count;
$amount = $request->amount; $amount = $request->amount;
$unit = (int) $request->unit; $unit = (int) $request->unit;
@@ -416,6 +457,7 @@ class GiftCardController extends Controller
$gift = GiftCard::create([ $gift = GiftCard::create([
'customer_id' => $customer?->id, 'customer_id' => $customer?->id,
'use_once' => $request->use_once ? 1 : 0, 'use_once' => $request->use_once ? 1 : 0,
'show_in_app' => $customer ? 0 : ($request->boolean('show_in_app') ? 1 : 0),
'count' => $count, 'count' => $count,
'amount' => $unitAmount, 'amount' => $unitAmount,
'mobile' => $customer?->mobile ?? $request->mobile ?? null, 'mobile' => $customer?->mobile ?? $request->mobile ?? null,
@@ -453,7 +495,7 @@ class GiftCardController extends Controller
$gift->save(); $gift->save();
} }
return $gift->load('giftcardcodes'); return $gift->load(['giftcardcodes', 'customer']);
} }
/** /**
@@ -598,7 +640,12 @@ class GiftCardController extends Controller
$createUniqueCodes = $request->use_once || $unit === 1 || $unit === 2; $createUniqueCodes = $request->use_once || $unit === 1 || $unit === 2;
if ($createUniqueCodes) { if ($createUniqueCodes) {
$gift = $this->createGiftCardWithUniqueCodes($request); try {
$customer = $this->resolveGiftCardCustomerForCreate($request);
} catch (UnprocessableEntityHttpException $e) {
return response()->json(['message' => $e->getMessage()], 400);
}
$gift = $this->createGiftCardWithUniqueCodes($request, $customer);
} else { } else {
do { do {
$unique_code = strtoupper(bin2hex(random_bytes(4))); $unique_code = strtoupper(bin2hex(random_bytes(4)));
@@ -722,8 +769,9 @@ class GiftCardController extends Controller
throw new UnprocessableEntityHttpException('auth failed!'); throw new UnprocessableEntityHttpException('auth failed!');
} }
$records = GiftCard::with([ $records = GiftCard::with([
'customer',
'giftcardcodes', 'giftcardcodes',
'giftcardcodes.assignedTo' 'giftcardcodes.assignedTo',
]); ]);
TableEngine::create($records, $request->all()) TableEngine::create($records, $request->all())
->initSearch([]) ->initSearch([])
+7
View File
@@ -4,6 +4,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use App\Models\Customer;
use App\Models\GiftCardCodes; use App\Models\GiftCardCodes;
class GiftCard extends Model class GiftCard extends Model
@@ -15,6 +16,7 @@ class GiftCard extends Model
protected $fillable = [ protected $fillable = [
'customer_id', 'customer_id',
'use_once', 'use_once',
'show_in_app',
'count', 'count',
'amount', 'amount',
'total', 'total',
@@ -33,6 +35,11 @@ class GiftCard extends Model
return $this->hasMany(GiftCardCodes::class, 'giftcard_id', 'id'); return $this->hasMany(GiftCardCodes::class, 'giftcard_id', 'id');
} }
public function customer()
{
return $this->belongsTo(Customer::class, 'customer_id', 'id')->select('id', 'name', 'mobile');
}
static $STS = [ static $STS = [
1 => "فعال", 1 => "فعال",
2 => "تمام شده", 2 => "تمام شده",
@@ -0,0 +1,22 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
if (Schema::hasTable('giftcards') && ! Schema::hasColumn('giftcards', 'show_in_app')) {
Schema::table('giftcards', function (Blueprint $table) {
$table->unsignedTinyInteger('show_in_app')->default(0)->after('use_once');
});
}
}
public function down(): void
{
// ستون ممکن است روی نصب‌های قدیمی استفاده شود؛ drop نمی‌کنیم.
}
};
+8
View File
@@ -794,6 +794,14 @@ SET @sql = IF(
); );
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET @sql = IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA=@db AND TABLE_NAME='giftcards' AND COLUMN_NAME='show_in_app') = 0,
'ALTER TABLE `giftcards` ADD COLUMN `show_in_app` TINYINT UNSIGNED NOT NULL DEFAULT 0 AFTER `use_once`',
'SELECT ''skip giftcards.show_in_app'' AS info'
);
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET @sql = IF( SET @sql = IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS (SELECT COUNT(*) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA=@db AND TABLE_NAME='giftcard_codes' AND COLUMN_NAME='amount') > 0 WHERE TABLE_SCHEMA=@db AND TABLE_NAME='giftcard_codes' AND COLUMN_NAME='amount') > 0