From 75791d6257d64669bfbfc92279017f3464d52c42 Mon Sep 17 00:00:00 2001 From: pbao9 Date: Wed, 18 Feb 2026 21:44:31 +0700 Subject: [PATCH] feat: introduce `ProductCategoryResource` and refactor database migrations by deleting old tables and consolidating transaction schema. --- .../Api/Service/ProductCategoryController.php | 3 +- .../Api/Service/ProductCategoryResource.php | 26 ++++++++++ app/Models/Product.php | 16 +++++- app/Models/ProductCategories.php | 15 ++++++ ...150900_create_product_categories_table.php | 2 +- .../migrations/2024_01_31_153518_hosting.php | 49 ------------------- .../migrations/2024_02_21_154350_v_p_s.php | 45 ----------------- .../2024_05_13_165053_transaction.php | 2 + ...letes_to_customer_invoice_order_tables.php | 24 ++++----- ...0_add_softdeletes_to_transaction_table.php | 6 +-- ...000000_add_foreign_key_to_transactions.php | 30 ------------ ...2_18_000001_add_status_to_transactions.php | 21 -------- 12 files changed, 76 insertions(+), 163 deletions(-) create mode 100644 app/Http/Resources/Api/Service/ProductCategoryResource.php delete mode 100644 database/migrations/2024_01_31_153518_hosting.php delete mode 100644 database/migrations/2024_02_21_154350_v_p_s.php delete mode 100644 database/migrations/2026_02_18_000000_add_foreign_key_to_transactions.php delete mode 100644 database/migrations/2026_02_18_000001_add_status_to_transactions.php diff --git a/app/Http/Controllers/Api/Service/ProductCategoryController.php b/app/Http/Controllers/Api/Service/ProductCategoryController.php index 7c72020..09ad840 100644 --- a/app/Http/Controllers/Api/Service/ProductCategoryController.php +++ b/app/Http/Controllers/Api/Service/ProductCategoryController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers\Api\Service; use App\Http\Controllers\Controller; +use App\Http\Resources\Api\Service\ProductCategoryResource; use App\Http\Resources\Api\Service\ServiceResource; use App\Models\Product; use App\Models\ProductCategories; @@ -63,7 +64,7 @@ class ProductCategoryController extends Controller return response()->json([ 'error' => false, 'message' => 'Lấy dữ liệu thành công', - 'data' => $categories, + 'data' => ProductCategoryResource::collection($categories), ]); } diff --git a/app/Http/Resources/Api/Service/ProductCategoryResource.php b/app/Http/Resources/Api/Service/ProductCategoryResource.php new file mode 100644 index 0000000..c65519f --- /dev/null +++ b/app/Http/Resources/Api/Service/ProductCategoryResource.php @@ -0,0 +1,26 @@ + $this->id, + 'name' => $this->name, + 'slug' => $this->slug, + 'parent_id' => $this->parent_id, + 'is_active' => $this->is_active, + 'sort_order' => $this->sort_order, + 'type' => $this->type, + 'type_label' => $this->type_label, + 'children' => $this->when($this->children, function () { + return self::collection($this->children); + }), + ]; + } +} diff --git a/app/Models/Product.php b/app/Models/Product.php index 34b7705..c9dc541 100644 --- a/app/Models/Product.php +++ b/app/Models/Product.php @@ -32,7 +32,6 @@ class Product extends Model 'is_unlimited', 'is_active', 'sort_order', - 'product_type', 'product_categories_id', 'published_at', ]; @@ -42,8 +41,23 @@ class Product extends Model 'is_unlimited' => 'boolean', 'published_at' => 'date', 'gallery' => 'array', + 'product_type' => 'string', ]; + protected static function boot() + { + parent::boot(); + + static::saving(function ($product) { + if ($product->product_categories_id) { + $category = ProductCategories::find($product->product_categories_id); + if ($category && $category->type) { + $product->product_type = $category->type; + } + } + }); + } + /** * Relationship: Product belongs to a Category */ diff --git a/app/Models/ProductCategories.php b/app/Models/ProductCategories.php index cc66b02..2a581ed 100644 --- a/app/Models/ProductCategories.php +++ b/app/Models/ProductCategories.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Enums\Product\ProductTypeEnums; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; @@ -18,6 +19,7 @@ class ProductCategories extends Model 'parent_id', 'is_active', 'sort_order', + 'type', ]; public function parent() @@ -34,4 +36,17 @@ class ProductCategories extends Model { return $this->hasMany(Product::class, 'product_categories_id'); } + + public function getTypeLabelAttribute(): ?string + { + if (!$this->type) { + return null; + } + return ProductTypeEnums::tryFrom($this->type)?->label(); + } + + public static function getTypeOptions(): array + { + return array_map(fn($case) => $case->value, ProductTypeEnums::cases()); + } } diff --git a/database/migrations/2024_01_31_150900_create_product_categories_table.php b/database/migrations/2024_01_31_150900_create_product_categories_table.php index 91cff23..4ef16c2 100644 --- a/database/migrations/2024_01_31_150900_create_product_categories_table.php +++ b/database/migrations/2024_01_31_150900_create_product_categories_table.php @@ -17,7 +17,7 @@ return new class extends Migration { $table->foreignId('parent_id')->nullable() ->constrained('product_categories') ->nullOnDelete(); - + $table->enum('type', ['vps', 'hosting', 'cloud', 'email', 'ssl', 'domain', 'web_design', 'addon'])->nullable(); $table->boolean('is_active')->default(true); $table->integer('sort_order')->default(0); diff --git a/database/migrations/2024_01_31_153518_hosting.php b/database/migrations/2024_01_31_153518_hosting.php deleted file mode 100644 index 0fc577a..0000000 --- a/database/migrations/2024_01_31_153518_hosting.php +++ /dev/null @@ -1,49 +0,0 @@ -id()->autoIncrement(); - $table->string('name', 255)->nullable(); - $table->string('slug')->nullable(); - $table->integer('price')->nullable(); - $table->integer('price_sale')->nullable(); - $table->integer('ram')->default(0)->nullable(); - $table->integer('disk')->default(125)->nullable(); - $table->integer('cpu')->default(1)->nullable(); - $table->integer('gpu')->default(0)->nullable(); - $table->integer('ip')->default(0)->nullable(); - $table->integer('bandwidth')->default(1000)->nullable(); - $table->integer('module_host_id')->nullable()->index(); - $table->text('description')->nullable(); - $table->string('template', 255)->nullable(); - $table->tinyInteger('type_id')->default(0)->index(); - $table->integer('group_id')->default(0)->index(); - $table->tinyInteger('status')->default(1); - $table->timestamps(); - }); - } - - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::table('hosting', function (Blueprint $table) { - $table->dropForeign('group_id'); - $table->drop(); - }); - } -}; diff --git a/database/migrations/2024_02_21_154350_v_p_s.php b/database/migrations/2024_02_21_154350_v_p_s.php deleted file mode 100644 index 96892b3..0000000 --- a/database/migrations/2024_02_21_154350_v_p_s.php +++ /dev/null @@ -1,45 +0,0 @@ -id()->autoIncrement(); - $table->string('name', 100)->nullable(); - $table->integer('cpu')->default(1); - $table->integer('ram')->default(1); - $table->integer('disk')->default(10); - $table->integer('gpu')->nullable(); - $table->text('description')->nullable(); - $table->integer('bandwidth')->default(100); - $table->integer('price')->nullable(); - $table->integer('price_sale')->nullable(); - $table->bigInteger('module_host_id')->default(0)->index(); - $table->integer('type_id')->default(0)->index(); - $table->integer('group_id')->default(0)->index(); - $table->tinyInteger('status')->default(1); - $table->timestamps(); - }); - } - - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - // - Schema::dropIfExists('vps'); - } -}; diff --git a/database/migrations/2024_05_13_165053_transaction.php b/database/migrations/2024_05_13_165053_transaction.php index daa982a..89d68ce 100644 --- a/database/migrations/2024_05_13_165053_transaction.php +++ b/database/migrations/2024_05_13_165053_transaction.php @@ -16,6 +16,8 @@ return new class extends Migration { ->constrained('customers') ->cascadeOnDelete(); + $table->tinyInteger('status')->default(0)->comment('0: pending, 1: completed, 2: fail'); + $table->timestamps(); $table->softDeletes(); }); diff --git a/database/migrations/2026_02_16_000000_add_softdeletes_to_customer_invoice_order_tables.php b/database/migrations/2026_02_16_000000_add_softdeletes_to_customer_invoice_order_tables.php index d03acee..e8c1907 100644 --- a/database/migrations/2026_02_16_000000_add_softdeletes_to_customer_invoice_order_tables.php +++ b/database/migrations/2026_02_16_000000_add_softdeletes_to_customer_invoice_order_tables.php @@ -7,21 +7,21 @@ use Illuminate\Support\Facades\Schema; return new class extends Migration { public function up() { - Schema::table('customers', function (Blueprint $table) { - $table->softDeletes(); - }); + // Schema::table('customers', function (Blueprint $table) { + // $table->softDeletes(); + // }); - Schema::table('invoice', function (Blueprint $table) { - $table->softDeletes(); - }); + // Schema::table('invoice', function (Blueprint $table) { + // $table->softDeletes(); + // }); - Schema::table('order', function (Blueprint $table) { - $table->softDeletes(); - }); + // Schema::table('order', function (Blueprint $table) { + // $table->softDeletes(); + // }); - Schema::table('transaction', function (Blueprint $table) { - $table->softDeletes(); - }); + // Schema::table('transaction', function (Blueprint $table) { + // $table->softDeletes(); + // }); } public function down() diff --git a/database/migrations/2026_02_16_120000_add_softdeletes_to_transaction_table.php b/database/migrations/2026_02_16_120000_add_softdeletes_to_transaction_table.php index 4c141d3..6292c99 100644 --- a/database/migrations/2026_02_16_120000_add_softdeletes_to_transaction_table.php +++ b/database/migrations/2026_02_16_120000_add_softdeletes_to_transaction_table.php @@ -7,9 +7,9 @@ use Illuminate\Support\Facades\Schema; return new class extends Migration { public function up() { - Schema::table('transaction', function (Blueprint $table) { - $table->softDeletes(); - }); + // Schema::table('transaction', function (Blueprint $table) { + // $table->softDeletes(); + // }); } public function down() diff --git a/database/migrations/2026_02_18_000000_add_foreign_key_to_transactions.php b/database/migrations/2026_02_18_000000_add_foreign_key_to_transactions.php deleted file mode 100644 index 9207c28..0000000 --- a/database/migrations/2026_02_18_000000_add_foreign_key_to_transactions.php +++ /dev/null @@ -1,30 +0,0 @@ -id(); - $table->string('trans')->nullable(); - $table->integer('amount')->nullable(); - - $table->foreignId('customer_id') - ->constrained('customers') - ->cascadeOnDelete(); - - $table->timestamps(); - $table->softDeletes(); - }); - } - - public function down() - { - Schema::table('transactions', function (Blueprint $table) { - $table->dropForeign(['customer_id']); - }); - } -}; diff --git a/database/migrations/2026_02_18_000001_add_status_to_transactions.php b/database/migrations/2026_02_18_000001_add_status_to_transactions.php deleted file mode 100644 index 0360a70..0000000 --- a/database/migrations/2026_02_18_000001_add_status_to_transactions.php +++ /dev/null @@ -1,21 +0,0 @@ -tinyInteger('status')->default(0)->comment('0: pending, 1: completed, 2: fail')->after('amount'); - }); - } - - public function down() - { - Schema::table('transactions', function (Blueprint $table) { - $table->dropColumn('status'); - }); - } -};