From 8165fc37b817df0ea9a723bbc609675bc5214dcb Mon Sep 17 00:00:00 2001 From: adonis Date: Wed, 22 Jul 2026 14:15:22 +0330 Subject: [PATCH] fix trigger bug 2 --- .../Admin/ConditionalOrderController.php | 8 +++-- .../Customer/ConditionalOrderController.php | 8 +++-- app/Services/ConditionalOrderService.php | 4 ++- app/Support/ConditionalOrderValidation.php | 6 +++- ...000002_create_conditional_orders_table.php | 2 +- ...ditional_orders_expires_at_to_datetime.php | 31 +++++++++++++++++++ 6 files changed, 52 insertions(+), 7 deletions(-) create mode 100644 database/migrations/2026_07_22_000002_change_conditional_orders_expires_at_to_datetime.php diff --git a/app/Http/Controllers/Admin/ConditionalOrderController.php b/app/Http/Controllers/Admin/ConditionalOrderController.php index 559b811..1b55fae 100644 --- a/app/Http/Controllers/Admin/ConditionalOrderController.php +++ b/app/Http/Controllers/Admin/ConditionalOrderController.php @@ -126,13 +126,17 @@ class ConditionalOrderController extends Controller if (! empty($data['expires_at'])) { try { - $expires = \Illuminate\Support\Carbon::parse($data['expires_at']); + $expires = \Illuminate\Support\Carbon::parse( + $data['expires_at'], + config('app.timezone') + )->timezone(config('app.timezone')); } catch (\Throwable $e) { throw new UnprocessableEntityHttpException('زمان اعتبار تاریخ معتبری نیست.'); } if ($expires->lte(now())) { - throw new UnprocessableEntityHttpException('زمان اعتبار باید بعد از الان باشد.'); + throw new UnprocessableEntityHttpException('زمان اعتبار باید بعد از تایم فعلی باشد.'); } + // Wall-clock in app TZ; column is DATETIME (not TIMESTAMP) to avoid double TZ shift. $data['expires_at'] = $expires->format('Y-m-d H:i:s'); } diff --git a/app/Http/Controllers/Customer/ConditionalOrderController.php b/app/Http/Controllers/Customer/ConditionalOrderController.php index 178add0..0eaadce 100644 --- a/app/Http/Controllers/Customer/ConditionalOrderController.php +++ b/app/Http/Controllers/Customer/ConditionalOrderController.php @@ -149,13 +149,17 @@ class ConditionalOrderController extends Controller if (! empty($data['expires_at'])) { try { - $expires = \Illuminate\Support\Carbon::parse($data['expires_at']); + $expires = \Illuminate\Support\Carbon::parse( + $data['expires_at'], + config('app.timezone') + )->timezone(config('app.timezone')); } catch (\Throwable $e) { throw new UnprocessableEntityHttpException('زمان اعتبار تاریخ معتبری نیست.'); } if ($expires->lte(now())) { - throw new UnprocessableEntityHttpException('زمان اعتبار باید بعد از الان باشد.'); + throw new UnprocessableEntityHttpException('زمان اعتبار باید بعد از تایم فعلی باشد.'); } + // Wall-clock in app TZ; column is DATETIME (not TIMESTAMP) to avoid double TZ shift. $data['expires_at'] = $expires->format('Y-m-d H:i:s'); } diff --git a/app/Services/ConditionalOrderService.php b/app/Services/ConditionalOrderService.php index 25479b1..a445f6d 100644 --- a/app/Services/ConditionalOrderService.php +++ b/app/Services/ConditionalOrderService.php @@ -205,10 +205,12 @@ class ConditionalOrderService public function expirePendingPastDue(): int { + $now = now()->timezone(config('app.timezone'))->format('Y-m-d H:i:s'); + return ConditionalOrder::query() ->where('status', ConditionalOrder::STATUS_PENDING) ->whereNotNull('expires_at') - ->where('expires_at', '<', now()) + ->where('expires_at', '<', $now) ->update([ 'status' => ConditionalOrder::STATUS_EXPIRED, 'is_active' => false, diff --git a/app/Support/ConditionalOrderValidation.php b/app/Support/ConditionalOrderValidation.php index 53f7a56..c63dcfc 100644 --- a/app/Support/ConditionalOrderValidation.php +++ b/app/Support/ConditionalOrderValidation.php @@ -16,7 +16,11 @@ class ConditionalOrderValidation 'in' => ':attribute انتخاب‌شده نامعتبر است.', 'boolean' => ':attribute باید صحیح یا غلط باشد.', 'date' => ':attribute تاریخ معتبری نیست.', - 'after' => ':attribute باید بعد از الان باشد.', + 'after' => 'زمان اعتبار باید بعد از تایم فعلی باشد.', + 'after_or_equal' => 'زمان اعتبار باید بعد از تایم فعلی باشد.', + 'expires_at.date' => 'زمان اعتبار تاریخ معتبری نیست.', + 'expires_at.after' => 'زمان اعتبار باید بعد از تایم فعلی باشد.', + 'expires_at.after_or_equal' => 'زمان اعتبار باید بعد از تایم فعلی باشد.', 'exists' => ':attribute انتخاب‌شده معتبر نیست.', 'string' => ':attribute باید متن باشد.', 'nullable' => '', diff --git a/database/migrations/2026_07_21_000002_create_conditional_orders_table.php b/database/migrations/2026_07_21_000002_create_conditional_orders_table.php index a002e59..382c3b6 100644 --- a/database/migrations/2026_07_21_000002_create_conditional_orders_table.php +++ b/database/migrations/2026_07_21_000002_create_conditional_orders_table.php @@ -21,7 +21,7 @@ return new class extends Migration $table->unsignedBigInteger('trigger_price'); $table->decimal('amount', 16, 4)->nullable(); $table->decimal('number', 16, 4)->nullable(); - $table->timestamp('expires_at')->nullable()->index(); + $table->dateTime('expires_at')->nullable()->index(); $table->text('description')->nullable(); $table->boolean('is_active')->default(true); $table->string('status', 16)->default('pending')->index(); // pending|executed|failed|expired diff --git a/database/migrations/2026_07_22_000002_change_conditional_orders_expires_at_to_datetime.php b/database/migrations/2026_07_22_000002_change_conditional_orders_expires_at_to_datetime.php new file mode 100644 index 0000000..73e96e9 --- /dev/null +++ b/database/migrations/2026_07_22_000002_change_conditional_orders_expires_at_to_datetime.php @@ -0,0 +1,31 @@ +