feat: add some fields to product

This commit is contained in:
2026-06-18 12:46:37 +03:30
parent 7afceffdd3
commit 4185113091
3 changed files with 81 additions and 5 deletions
+35 -2
View File
@@ -21,7 +21,7 @@ public function index(Request $request, $packageName)
'message' => 'package name not found' 'message' => 'package name not found'
], 404); ], 404);
} }
$products = $packageName->products; $products = $packageName->products()->orderBy('sort_order')->orderBy('id')->get();
return $products; return $products;
} }
@@ -33,6 +33,12 @@ public function store(Request $request, $packageName)
'type' => ['integer', Rule::in(Product::TYPES)], 'type' => ['integer', Rule::in(Product::TYPES)],
'descriptions' => 'array|nullable', 'descriptions' => 'array|nullable',
'descriptions.*' => 'string|max:1000', 'descriptions.*' => 'string|max:1000',
// Display-only text fields (no calculation)
'discounted_price' => 'string|nullable',
'daily_price' => 'string|nullable',
'discount' => 'string|nullable',
'is_best_seller' => 'boolean|nullable',
'sort_order' => 'integer|nullable',
]); ]);
if (!$packageName = PackageName::with('products')->where('name', $packageName)->first()) { if (!$packageName = PackageName::with('products')->where('name', $packageName)->first()) {
@@ -42,6 +48,11 @@ public function store(Request $request, $packageName)
} }
$product = $packageName->products()->create($data); $product = $packageName->products()->create($data);
if (!empty($data['is_best_seller'])) {
$this->keepSingleBestSeller($packageName, $product->id);
}
return $product; return $product;
} }
@@ -52,7 +63,13 @@ public function update(Request $request, $packageName, $productId)
'price' => 'integer|required', 'price' => 'integer|required',
'type' => ['integer', Rule::in(Product::TYPES)], 'type' => ['integer', Rule::in(Product::TYPES)],
'descriptions' => 'array|nullable', 'descriptions' => 'array|nullable',
'descriptions.*' => 'string|max:1000' 'descriptions.*' => 'string|max:1000',
// Display-only text fields (no calculation)
'discounted_price' => 'string|nullable',
'daily_price' => 'string|nullable',
'discount' => 'string|nullable',
'is_best_seller' => 'boolean|nullable',
'sort_order' => 'integer|nullable',
]); ]);
if (!$packageName = PackageName::with('products')->where('name', $packageName)->first()) { if (!$packageName = PackageName::with('products')->where('name', $packageName)->first()) {
@@ -68,9 +85,25 @@ public function update(Request $request, $packageName, $productId)
} }
$product->update($data); $product->update($data);
if (!empty($data['is_best_seller'])) {
$this->keepSingleBestSeller($packageName, $product->id);
}
return $product; return $product;
} }
/**
* Make sure only one product within a package is flagged as best-seller.
*/
private function keepSingleBestSeller(PackageName $packageName, $keepProductId): void
{
$packageName->products()
->where('id', '!=', $keepProductId)
->where('is_best_seller', true)
->update(['is_best_seller' => false]);
}
public function delete($packageName, $productId) public function delete($packageName, $productId)
{ {
if (!$packageName = PackageName::with('products')->where('name', $packageName)->first()) { if (!$packageName = PackageName::with('products')->where('name', $packageName)->first()) {
+2
View File
@@ -27,6 +27,8 @@ public function users()
} }
protected $casts = [ protected $casts = [
'descriptions' => 'array', 'descriptions' => 'array',
'is_best_seller' => 'boolean',
'sort_order' => 'integer',
]; ];
@@ -0,0 +1,41 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('products', function (Blueprint $table) {
// Display-only text fields (no calculation, just shown in the UI)
$table->string('discounted_price')->nullable()->after('descriptions'); // قیمت کلی تخفیف خورده
$table->string('daily_price')->nullable()->after('discounted_price'); // قیمت روزانه
$table->string('discount')->nullable()->after('daily_price'); // تخفیف
// Best-seller flag (only one per package should be active)
$table->boolean('is_best_seller')->default(false)->after('discount'); // پرفروش‌ترین
// Display order (lower = shown higher, 0 is top)
$table->unsignedInteger('sort_order')->default(0)->after('is_best_seller'); // ترتیب
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('products', function (Blueprint $table) {
$table->dropColumn([
'discounted_price',
'daily_price',
'discount',
'is_best_seller',
'sort_order',
]);
});
}
};