diff --git a/04_Laravel/.phpunit.result.cache b/04_Laravel/.phpunit.result.cache index 8143b2b..f9e6e9e 100644 --- a/04_Laravel/.phpunit.result.cache +++ b/04_Laravel/.phpunit.result.cache @@ -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}} \ No newline at end of file +{"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}} \ No newline at end of file diff --git a/04_Laravel/database/migrations/2026_08_10_020410_update_shipments_status_enum.php b/04_Laravel/database/migrations/2026_08_10_020410_update_shipments_status_enum.php index cff78fa..1351a28 100644 --- a/04_Laravel/database/migrations/2026_08_10_020410_update_shipments_status_enum.php +++ b/04_Laravel/database/migrations/2026_08_10_020410_update_shipments_status_enum.php @@ -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' "); diff --git a/04_Laravel/database/migrations/2026_08_10_080853_add_wallet_to_payment_gateway_enum.php b/04_Laravel/database/migrations/2026_08_10_080853_add_wallet_to_payment_gateway_enum.php index 6b0c2d0..81812e1 100644 --- a/04_Laravel/database/migrations/2026_08_10_080853_add_wallet_to_payment_gateway_enum.php +++ b/04_Laravel/database/migrations/2026_08_10_080853_add_wallet_to_payment_gateway_enum.php @@ -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']); diff --git a/04_Laravel/database/migrations/2026_08_10_082121_add_system_to_tracking_source_enum.php b/04_Laravel/database/migrations/2026_08_10_082121_add_system_to_tracking_source_enum.php index 744c2e2..4c9fc3f 100644 --- a/04_Laravel/database/migrations/2026_08_10_082121_add_system_to_tracking_source_enum.php +++ b/04_Laravel/database/migrations/2026_08_10_082121_add_system_to_tracking_source_enum.php @@ -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']); diff --git a/04_Laravel/database/migrations/2026_08_24_000001_add_missing_fields_to_shipments_table.php b/04_Laravel/database/migrations/2026_08_24_000001_add_missing_fields_to_shipments_table.php index bb8e5f0..3b3d85c 100644 --- a/04_Laravel/database/migrations/2026_08_24_000001_add_missing_fields_to_shipments_table.php +++ b/04_Laravel/database/migrations/2026_08_24_000001_add_missing_fields_to_shipments_table.php @@ -1,7 +1,6 @@ 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'"); } }; \ No newline at end of file diff --git a/04_Laravel/database/migrations/2026_09_03_000001_add_approval_statuses_to_shipments_table.php b/04_Laravel/database/migrations/2026_09_03_000001_add_approval_statuses_to_shipments_table.php index 3bf7f2b..2faee9d 100644 --- a/04_Laravel/database/migrations/2026_09_03_000001_add_approval_statuses_to_shipments_table.php +++ b/04_Laravel/database/migrations/2026_09_03_000001_add_approval_statuses_to_shipments_table.php @@ -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']) diff --git a/04_Laravel/database/migrations/2026_09_09_000003_add_reason_to_shipment_status_history_table.php b/04_Laravel/database/migrations/2026_09_09_000003_add_reason_to_shipment_status_history_table.php index eba08c8..04a2a65 100644 --- a/04_Laravel/database/migrations/2026_09_09_000003_add_reason_to_shipment_status_history_table.php +++ b/04_Laravel/database/migrations/2026_09_09_000003_add_reason_to_shipment_status_history_table.php @@ -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'); });