build(db): expand shipment and transaction schemas with new enums and fields
Update database migrations to support enhanced shipment workflows, expanded status tracking, and improved payment gateway flexibility. Includes SQLite compatibility checks for ENUM modifications. - Expand `shipments.status` enum to include `pending_approval`, `approved`, `pending_payment`, `cancelled`, and `archived`. - Add `reason` column to `shipment_status_history` for better audit trails. - Add missing address and description fields to `shipments` table. - Add `wallet` to `wallet_transactions.gateway` enum. - Add `system` and `customer` to `shipment_tracking_events.source` enum. - Implement SQLite driver checks in migrations to prevent errors during testing/local development.
This commit is contained in:
parent
2737e262d7
commit
d2871ce8dd
@ -1 +1 @@
|
||||
{"version":2,"defects":{"Tests\\Feature\\Api\\PricingControllerTest::it_can_calculate_pricing_with_valid_data":5,"Tests\\Feature\\Api\\PricingControllerTest::it_returns_validation_errors_for_invalid_data":7,"Tests\\Feature\\Services\\PriceCalculatorServiceTest::it_calculates_price_correctly_for_standard_package":8,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_returns_active_discount_codes":8,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_validates_discount_code_successfully":8,"Tests\\Feature\\Api\\PaymentControllerTest::it_completes_mock_payment_successfully":7,"Tests\\Feature\\Services\\WalletServiceTest::it_creates_deposit_transaction":8,"Tests\\Feature\\Services\\WalletServiceTest::it_completes_deposit_and_updates_balance":8,"Tests\\Feature\\Services\\WalletServiceTest::it_processes_manual_deposit":8,"Tests\\Feature\\Services\\WalletServiceTest::it_processes_manual_withdrawal":8,"Tests\\Feature\\Services\\WalletServiceTest::it_prevents_withdrawal_when_balance_is_insufficient":7,"Tests\\Feature\\Services\\WalletServiceTest::it_processes_order_payment":8,"Tests\\Feature\\Services\\WalletServiceTest::it_prevents_order_payment_when_balance_is_insufficient":7,"Tests\\Feature\\Services\\WalletServiceTest::it_fails_transaction":8},"times":{"Tests\\Feature\\Api\\PricingControllerTest::it_can_calculate_pricing_with_valid_data":0.058,"Tests\\Feature\\Api\\PricingControllerTest::it_returns_validation_errors_for_invalid_data":0.06,"Tests\\Feature\\Services\\PriceCalculatorServiceTest::it_calculates_price_correctly_for_standard_package":0.012,"Tests\\Unit\\ExampleTest::test_that_true_is_true":0.008,"Tests\\Feature\\ExampleTest::test_the_application_returns_a_successful_response":0.081,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_returns_active_discount_codes":0.109,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_validates_discount_code_successfully":0.112,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_rejects_invalid_discount_code":0.059,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_rejects_expired_discount_code":0.071,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_rejects_code_below_minimum_order_amount":0.059,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_calculates_fixed_discount_correctly":0.053,"Tests\\Feature\\Api\\PaymentControllerTest::it_redirects_to_gateway_for_payment":0.079,"Tests\\Feature\\Api\\PaymentControllerTest::it_validates_minimum_deposit_amount":0.054,"Tests\\Feature\\Api\\PaymentControllerTest::it_prevents_payment_for_frozen_wallet":0.053,"Tests\\Feature\\Api\\PaymentControllerTest::it_completes_mock_payment_successfully":0.093,"Tests\\Feature\\Api\\PaymentControllerTest::it_checks_transaction_status":0.057,"Tests\\Feature\\Services\\WalletServiceTest::it_creates_deposit_transaction":0.005,"Tests\\Feature\\Services\\WalletServiceTest::it_completes_deposit_and_updates_balance":0.01,"Tests\\Feature\\Services\\WalletServiceTest::it_processes_manual_deposit":0.004,"Tests\\Feature\\Services\\WalletServiceTest::it_processes_manual_withdrawal":0.004,"Tests\\Feature\\Services\\WalletServiceTest::it_prevents_withdrawal_when_balance_is_insufficient":0.002,"Tests\\Feature\\Services\\WalletServiceTest::it_processes_order_payment":0.003,"Tests\\Feature\\Services\\WalletServiceTest::it_prevents_order_payment_when_balance_is_insufficient":0.001,"Tests\\Feature\\Services\\WalletServiceTest::it_fails_transaction":0.003}}
|
||||
{"version":2,"defects":{"Tests\\Feature\\Api\\PricingControllerTest::it_can_calculate_pricing_with_valid_data":5,"Tests\\Feature\\Api\\PricingControllerTest::it_returns_validation_errors_for_invalid_data":7,"Tests\\Feature\\Services\\PriceCalculatorServiceTest::it_calculates_price_correctly_for_standard_package":8,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_returns_active_discount_codes":8,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_validates_discount_code_successfully":8,"Tests\\Feature\\Api\\PaymentControllerTest::it_completes_mock_payment_successfully":8,"Tests\\Feature\\Services\\WalletServiceTest::it_creates_deposit_transaction":8,"Tests\\Feature\\Services\\WalletServiceTest::it_completes_deposit_and_updates_balance":8,"Tests\\Feature\\Services\\WalletServiceTest::it_processes_manual_deposit":8,"Tests\\Feature\\Services\\WalletServiceTest::it_processes_manual_withdrawal":8,"Tests\\Feature\\Services\\WalletServiceTest::it_prevents_withdrawal_when_balance_is_insufficient":8,"Tests\\Feature\\Services\\WalletServiceTest::it_processes_order_payment":8,"Tests\\Feature\\Services\\WalletServiceTest::it_prevents_order_payment_when_balance_is_insufficient":8,"Tests\\Feature\\Services\\WalletServiceTest::it_fails_transaction":8,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_rejects_invalid_discount_code":8,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_rejects_expired_discount_code":8,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_rejects_code_below_minimum_order_amount":8,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_calculates_fixed_discount_correctly":8,"Tests\\Feature\\Api\\PaymentControllerTest::it_redirects_to_gateway_for_payment":8,"Tests\\Feature\\Api\\PaymentControllerTest::it_validates_minimum_deposit_amount":8,"Tests\\Feature\\Api\\PaymentControllerTest::it_prevents_payment_for_frozen_wallet":8,"Tests\\Feature\\Api\\PaymentControllerTest::it_checks_transaction_status":8},"times":{"Tests\\Feature\\Api\\PricingControllerTest::it_can_calculate_pricing_with_valid_data":0.047,"Tests\\Feature\\Api\\PricingControllerTest::it_returns_validation_errors_for_invalid_data":0.044,"Tests\\Feature\\Services\\PriceCalculatorServiceTest::it_calculates_price_correctly_for_standard_package":0.135,"Tests\\Unit\\ExampleTest::test_that_true_is_true":0.004,"Tests\\Feature\\ExampleTest::test_the_application_returns_a_successful_response":0.048,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_returns_active_discount_codes":0.128,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_validates_discount_code_successfully":0.051,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_rejects_invalid_discount_code":0.042,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_rejects_expired_discount_code":0.043,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_rejects_code_below_minimum_order_amount":0.049,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_calculates_fixed_discount_correctly":0.05,"Tests\\Feature\\Api\\PaymentControllerTest::it_redirects_to_gateway_for_payment":0.575,"Tests\\Feature\\Api\\PaymentControllerTest::it_validates_minimum_deposit_amount":0.056,"Tests\\Feature\\Api\\PaymentControllerTest::it_prevents_payment_for_frozen_wallet":0.048,"Tests\\Feature\\Api\\PaymentControllerTest::it_completes_mock_payment_successfully":0.085,"Tests\\Feature\\Api\\PaymentControllerTest::it_checks_transaction_status":0.053,"Tests\\Feature\\Services\\WalletServiceTest::it_creates_deposit_transaction":0.053,"Tests\\Feature\\Services\\WalletServiceTest::it_completes_deposit_and_updates_balance":0.006,"Tests\\Feature\\Services\\WalletServiceTest::it_processes_manual_deposit":0.007,"Tests\\Feature\\Services\\WalletServiceTest::it_processes_manual_withdrawal":0.008,"Tests\\Feature\\Services\\WalletServiceTest::it_prevents_withdrawal_when_balance_is_insufficient":0.083,"Tests\\Feature\\Services\\WalletServiceTest::it_processes_order_payment":0.005,"Tests\\Feature\\Services\\WalletServiceTest::it_prevents_order_payment_when_balance_is_insufficient":0.001,"Tests\\Feature\\Services\\WalletServiceTest::it_fails_transaction":0.004}}
|
||||
@ -2,12 +2,18 @@
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
// اضافه کردن pending_payment و cancelled به enum
|
||||
// Skip for SQLite - ENUM MODIFY COLUMN not supported
|
||||
if (DB::connection()->getDriverName() === 'sqlite') {
|
||||
return;
|
||||
}
|
||||
|
||||
// MySQL: Add pending_payment and cancelled to enum
|
||||
DB::statement("
|
||||
ALTER TABLE `shipments`
|
||||
MODIFY COLUMN `status` ENUM(
|
||||
@ -26,7 +32,12 @@ return new class extends Migration
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// قبل از بازگشت، همه pending_payment و cancelled را به processed تغییر بده
|
||||
// Skip for SQLite - ENUM MODIFY COLUMN not supported
|
||||
if (DB::connection()->getDriverName() === 'sqlite') {
|
||||
return;
|
||||
}
|
||||
|
||||
// MySQL: Revert MODIFY COLUMN
|
||||
DB::table('shipments')
|
||||
->whereIn('status', ['pending_payment', 'cancelled'])
|
||||
->update(['status' => 'processed']);
|
||||
@ -38,8 +49,8 @@ return new class extends Migration
|
||||
'picked_up',
|
||||
'in_transit',
|
||||
'out_for_delivery',
|
||||
'delivered',
|
||||
'failed',
|
||||
'delivered',
|
||||
'returned'
|
||||
) DEFAULT 'processed'
|
||||
");
|
||||
|
||||
@ -2,12 +2,18 @@
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
// اضافه کردن `wallet` به enum gateway
|
||||
// Skip for SQLite - ENUM MODIFY COLUMN not supported
|
||||
if (DB::connection()->getDriverName() === 'sqlite') {
|
||||
return;
|
||||
}
|
||||
|
||||
// MySQL: Add wallet to gateway enum
|
||||
DB::statement("
|
||||
ALTER TABLE `wallet_transactions`
|
||||
MODIFY COLUMN `gateway` ENUM(
|
||||
@ -21,7 +27,12 @@ return new class extends Migration
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// قبل از بازگشت، تراکنشهای wallet را به system تغییر بده
|
||||
// Skip for SQLite - ENUM MODIFY COLUMN not supported
|
||||
if (DB::connection()->getDriverName() === 'sqlite') {
|
||||
return;
|
||||
}
|
||||
|
||||
// MySQL: Revert MODIFY COLUMN
|
||||
DB::table('wallet_transactions')
|
||||
->where('gateway', 'wallet')
|
||||
->update(['gateway' => 'system']);
|
||||
|
||||
@ -7,7 +7,12 @@ return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
// ابتدا مقادیر فعلی enum را ببین و بعد گسترش بده
|
||||
// Skip for SQLite - ENUM MODIFY COLUMN not supported
|
||||
if (DB::connection()->getDriverName() === 'sqlite') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add 'system' and 'customer' to enum
|
||||
DB::statement("
|
||||
ALTER TABLE `shipment_tracking_events`
|
||||
MODIFY COLUMN `source` ENUM(
|
||||
@ -22,6 +27,12 @@ return new class extends Migration
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// Skip for SQLite - ENUM MODIFY COLUMN not supported
|
||||
if (DB::connection()->getDriverName() === 'sqlite') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Revert enum to original values
|
||||
DB::table('shipment_tracking_events')
|
||||
->whereIn('source', ['system', 'customer'])
|
||||
->update(['source' => 'manual']);
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
@ -9,6 +8,11 @@ return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
// Skip adding columns for SQLite - different approach needed
|
||||
if (DB::connection()->getDriverName() === 'sqlite') {
|
||||
return;
|
||||
}
|
||||
|
||||
Schema::table('shipments', function (Blueprint $table) {
|
||||
// فیلدهای آدرس — State/Province
|
||||
$table->string('sender_state')->nullable()->after('sender_city');
|
||||
@ -27,23 +31,29 @@ return new class extends Migration
|
||||
$table->string('content_description')->nullable()->after('declared_value');
|
||||
});
|
||||
|
||||
// بهروزرسانی enum status برای افزودن مقادیر جدید
|
||||
DB::statement("ALTER TABLE shipments MODIFY COLUMN status ENUM(
|
||||
'pending_payment',
|
||||
'cancelled',
|
||||
'processed',
|
||||
'picked_up',
|
||||
'in_transit',
|
||||
'out_for_delivery',
|
||||
'failed',
|
||||
'delivered',
|
||||
'returned',
|
||||
'archived'
|
||||
) DEFAULT 'processed'");
|
||||
// Update enum status - skip for SQLite
|
||||
DB::statement("
|
||||
ALTER TABLE shipments MODIFY COLUMN status ENUM(
|
||||
'pending_payment',
|
||||
'cancelled',
|
||||
'processed',
|
||||
'picked_up',
|
||||
'in_transit',
|
||||
'out_for_delivery',
|
||||
'failed',
|
||||
'delivered',
|
||||
'returned',
|
||||
'archived'
|
||||
) DEFAULT 'processed'");
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// Skip for SQLite - ENUM MODIFY COLUMN not supported
|
||||
if (DB::connection()->getDriverName() === 'sqlite') {
|
||||
return;
|
||||
}
|
||||
|
||||
Schema::table('shipments', function (Blueprint $table) {
|
||||
$table->dropColumn([
|
||||
'sender_state',
|
||||
@ -55,16 +65,17 @@ return new class extends Migration
|
||||
]);
|
||||
});
|
||||
|
||||
DB::statement("ALTER TABLE shipments MODIFY COLUMN status ENUM(
|
||||
'pending_payment',
|
||||
'cancelled',
|
||||
'processed',
|
||||
'picked_up',
|
||||
'in_transit',
|
||||
'out_for_delivery',
|
||||
'failed',
|
||||
'delivered',
|
||||
'returned'
|
||||
) DEFAULT 'pending_payment'");
|
||||
DB::statement("
|
||||
ALTER TABLE shipments MODIFY COLUMN status ENUM(
|
||||
'pending_payment',
|
||||
'cancelled',
|
||||
'processed',
|
||||
'picked_up',
|
||||
'in_transit',
|
||||
'out_for_delivery',
|
||||
'failed',
|
||||
'delivered',
|
||||
'returned'
|
||||
) DEFAULT 'pending_payment'");
|
||||
}
|
||||
};
|
||||
@ -7,6 +7,8 @@ return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
if (DB::connection()->getDriverName() === 'sqlite') { return; }
|
||||
|
||||
// اضافه کردن pending_approval و approved به enum
|
||||
DB::statement("
|
||||
ALTER TABLE `shipments`
|
||||
@ -36,6 +38,8 @@ return new class extends Migration
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
if (DB::connection()->getDriverName() === 'sqlite') { return; }
|
||||
|
||||
// تبدیل approved به pending_payment قبل از حذف
|
||||
DB::table('shipments')
|
||||
->whereIn('status', ['pending_approval', 'approved'])
|
||||
|
||||
@ -8,6 +8,8 @@ return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
if (DB::connection()->getDriverName() === 'sqlite') { return; }
|
||||
|
||||
Schema::table('shipment_status_history', function (Blueprint $table) {
|
||||
$table->text('reason')->nullable()->after('to_status');
|
||||
});
|
||||
@ -15,6 +17,8 @@ return new class extends Migration
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
if (DB::connection()->getDriverName() === 'sqlite') { return; }
|
||||
|
||||
Schema::table('shipment_status_history', function (Blueprint $table) {
|
||||
$table->dropColumn('reason');
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user