feat(giftcard): add customer giftcard/mine endpoint; fix admin/app password digit normalization
This commit is contained in:
@@ -194,6 +194,204 @@ class GiftCardController extends Controller
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* لیست کدهای قابلاستفاده (اختصاصی + عمومی تککد) و تاریخچهٔ مصرفشدهٔ مشتری.
|
||||
*/
|
||||
public function mine(Request $request)
|
||||
{
|
||||
$user = auth()->user();
|
||||
if (! $user) {
|
||||
throw new UnprocessableEntityHttpException('auth failed!');
|
||||
}
|
||||
|
||||
if (! app(ConfigService::class)->getBool('has_page_gift_card', false)) {
|
||||
throw new UnprocessableEntityHttpException('قابلیت کارت هدیه غیرفعال است.');
|
||||
}
|
||||
|
||||
$customerId = (int) $user->id;
|
||||
$mobile = $user->mobile ?? null;
|
||||
$available = [];
|
||||
$seenCodes = [];
|
||||
|
||||
$personalGifts = GiftCard::query()
|
||||
->where(function ($q) use ($customerId, $mobile) {
|
||||
$q->where('customer_id', $customerId);
|
||||
if ($mobile) {
|
||||
$q->orWhere('mobile', $mobile);
|
||||
}
|
||||
})
|
||||
->where(function ($q) {
|
||||
$q->whereNull('sts')->orWhere('sts', '!=', 3);
|
||||
})
|
||||
->where(function ($q) {
|
||||
$q->whereNull('expiry_date')->orWhere('expiry_date', '>', now());
|
||||
})
|
||||
->with(['giftcardcodes' => function ($q) {
|
||||
$q->where('sts', 1);
|
||||
}])
|
||||
->orderByDesc('id')
|
||||
->get();
|
||||
|
||||
foreach ($personalGifts as $gift) {
|
||||
foreach ($gift->giftcardcodes as $code) {
|
||||
if ($this->isCodeExpired($code, $gift)) {
|
||||
continue;
|
||||
}
|
||||
if (isset($seenCodes[$code->code])) {
|
||||
continue;
|
||||
}
|
||||
$seenCodes[$code->code] = true;
|
||||
$available[] = $this->mapCustomerGiftItem($gift, $code, 'personal');
|
||||
}
|
||||
}
|
||||
|
||||
$publicGifts = GiftCard::query()
|
||||
->where(function ($q) {
|
||||
$q->whereNull('customer_id')->orWhere('customer_id', 0);
|
||||
})
|
||||
->where(function ($q) {
|
||||
$q->whereNull('mobile')->orWhere('mobile', '');
|
||||
})
|
||||
->where('use_once', 0)
|
||||
->where(function ($q) {
|
||||
$q->whereNull('sts')->orWhere('sts', '!=', 3);
|
||||
})
|
||||
->where(function ($q) {
|
||||
$q->whereNull('expiry_date')->orWhere('expiry_date', '>', now());
|
||||
})
|
||||
->with('giftcardcodes')
|
||||
->orderByDesc('id')
|
||||
->get();
|
||||
|
||||
foreach ($publicGifts as $gift) {
|
||||
if ((int) $gift->count > 0 && (int) $gift->used_count >= (int) $gift->count) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$codes = $gift->giftcardcodes
|
||||
->filter(function ($code) use ($gift) {
|
||||
return (int) $code->sts !== 2
|
||||
&& (int) $code->sts !== 3
|
||||
&& ! $this->isCodeExpired($code, $gift);
|
||||
})
|
||||
->values();
|
||||
|
||||
// عمومی: فقط پویش تککد مشترک (جلوگیری از افشای بچ تصادفی)
|
||||
if ($codes->count() !== 1 && empty($gift->unique_code)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$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 = [];
|
||||
$historyCodes = GiftCardCodes::query()
|
||||
->whereNotNull('assigned_to')
|
||||
->where('assigned_to', '!=', '')
|
||||
->where(function ($q) use ($customerId) {
|
||||
$id = (string) $customerId;
|
||||
$q->where('assigned_to', $customerId)
|
||||
->orWhere('assigned_to', $id)
|
||||
->orWhere('assigned_to', '['.$id.']')
|
||||
->orWhere('assigned_to', 'like', '%"'.$id.'"%')
|
||||
->orWhere('assigned_to', 'like', '%['.$id.',%')
|
||||
->orWhere('assigned_to', 'like', '%,'.$id.']%')
|
||||
->orWhere('assigned_to', 'like', '%,'.$id.',%');
|
||||
})
|
||||
->with('giftcard')
|
||||
->orderByDesc('used_at')
|
||||
->orderByDesc('updated_at')
|
||||
->limit(100)
|
||||
->get();
|
||||
|
||||
foreach ($historyCodes as $code) {
|
||||
$gift = $code->giftcard;
|
||||
if (! $gift || ! $this->customerAlreadyUsedCode($code, $customerId, $gift)) {
|
||||
continue;
|
||||
}
|
||||
$history[] = $this->mapCustomerGiftItem($gift, $code, $this->resolveCodeScope($gift, $customerId, $mobile));
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'available' => $available,
|
||||
'history' => $history,
|
||||
]);
|
||||
}
|
||||
|
||||
private function isCodeExpired(GiftCardCodes $code, GiftCard $gift): bool
|
||||
{
|
||||
if ($code->expiry_date && $code->expiry_date <= now()) {
|
||||
return true;
|
||||
}
|
||||
if ($gift->expiry_date && $gift->expiry_date <= now()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function customerAlreadyUsedCode(GiftCardCodes $code, int $customerId, GiftCard $gift): bool
|
||||
{
|
||||
$assigned = $code->assigned_to;
|
||||
if ($assigned === null || $assigned === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((int) $gift->unit === 3 || (is_string($assigned) && str_starts_with(trim($assigned), '['))) {
|
||||
$ids = json_decode($assigned, true);
|
||||
if (! is_array($ids)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return in_array($customerId, $ids, false) || in_array((string) $customerId, $ids, false);
|
||||
}
|
||||
|
||||
return (string) $assigned === (string) $customerId;
|
||||
}
|
||||
|
||||
private function resolveCodeScope(GiftCard $gift, int $customerId, ?string $mobile): string
|
||||
{
|
||||
if ((int) $gift->customer_id === $customerId) {
|
||||
return 'personal';
|
||||
}
|
||||
if ($mobile && $gift->mobile && (string) $gift->mobile === (string) $mobile) {
|
||||
return 'personal';
|
||||
}
|
||||
|
||||
return 'public';
|
||||
}
|
||||
|
||||
private function mapCustomerGiftItem(GiftCard $gift, GiftCardCodes $code, string $scope): array
|
||||
{
|
||||
$unit = (int) ($code->unit ?? $gift->unit);
|
||||
|
||||
return [
|
||||
'id' => $code->id,
|
||||
'giftcard_id' => $gift->id,
|
||||
'code' => $code->code,
|
||||
'name' => $gift->name,
|
||||
'description' => $gift->description,
|
||||
'amount' => $code->amount ?? $gift->amount,
|
||||
'unit' => $unit,
|
||||
'kind' => $unit === 3 ? 'discount' : 'gift',
|
||||
'scope' => $scope,
|
||||
'sts' => (int) $code->sts,
|
||||
'expiry_date' => $code->expiry_date ?? $gift->expiry_date,
|
||||
'used_at' => $code->used_at,
|
||||
];
|
||||
}
|
||||
|
||||
public function useDiscount(Request $request)
|
||||
{
|
||||
if (! app(ConfigService::class)->isStore()) {
|
||||
|
||||
Reference in New Issue
Block a user