diff --git a/app/Console/Commands/Migrations/MigratePerfumesFromOldData.php b/app/Console/Commands/Migrations/MigratePerfumesFromOldData.php index 117486c..48a91c0 100644 --- a/app/Console/Commands/Migrations/MigratePerfumesFromOldData.php +++ b/app/Console/Commands/Migrations/MigratePerfumesFromOldData.php @@ -72,7 +72,6 @@ public function handle() 'brand_id' => $oldFragrance->brand_id, 'name' => $oldFragrance->name, 'slug' => Str::slug($oldFragrance->name), - 'sku' => $this->generateSKU('PERF', $oldFragrance->id), 'concentration' => Concentration::EXTRAIT_DE_PERFUME, // Default concentration 'cost_price' => $oldFragrance->buying_price, 'sale_price' => $oldFragrance->selling_price, @@ -155,12 +154,4 @@ private function getOutletMapping(): array return $mapping; } - - private function generateSKU(string $prefix, int $id): string - { - // Use timestamp to ensure uniqueness when recreating - $timestamp = now()->format('His'); - - return $prefix.str_pad($id, 3, '0', STR_PAD_LEFT).$timestamp; - } } diff --git a/app/Console/Commands/Migrations/MigrateProductsFromOldData.php b/app/Console/Commands/Migrations/MigrateProductsFromOldData.php index f15a211..2a00b4a 100644 --- a/app/Console/Commands/Migrations/MigrateProductsFromOldData.php +++ b/app/Console/Commands/Migrations/MigrateProductsFromOldData.php @@ -70,7 +70,6 @@ public function handle() $product = Product::create([ 'name' => $oldProduct->name, 'slug' => Str::slug($oldProduct->name), - 'sku' => $this->generateSKU('PROD', $oldProduct->id), 'cost_price' => $oldProduct->buying_price, 'sale_price' => $oldProduct->selling_price, 'description' => null, @@ -144,12 +143,4 @@ private function getOutletMapping(): array return $mapping; } - - private function generateSKU(string $prefix, int $id): string - { - // Use timestamp to ensure uniqueness when recreating - $timestamp = now()->format('His'); - - return $prefix.str_pad($id, 3, '0', STR_PAD_LEFT).$timestamp; - } } diff --git a/app/Livewire/Datatable/Catalog/PerfumesTable.php b/app/Livewire/Datatable/Catalog/PerfumesTable.php index d5d3423..fe0f050 100644 --- a/app/Livewire/Datatable/Catalog/PerfumesTable.php +++ b/app/Livewire/Datatable/Catalog/PerfumesTable.php @@ -26,13 +26,11 @@ public function columns(): array return <<
{$row->name}
- {$row->sku} HTML; }) ->searchable(function ($query, $searchTerm) { - $query->where('perfumes.name', 'like', "%{$searchTerm}%") - ->orWhere('sku', 'like', "%{$searchTerm}%"); + $query->where('perfumes.name', 'like', "%{$searchTerm}%"); }) ->html(), @@ -111,7 +109,6 @@ public function builder(): Builder { return Perfume::select( 'perfumes.id', - 'sku', 'perfumes.name', 'concentration', 'sale_price' diff --git a/app/Livewire/Datatable/Catalog/ProductsTable.php b/app/Livewire/Datatable/Catalog/ProductsTable.php index da143da..ec9140b 100644 --- a/app/Livewire/Datatable/Catalog/ProductsTable.php +++ b/app/Livewire/Datatable/Catalog/ProductsTable.php @@ -26,13 +26,11 @@ public function columns(): array return <<
{$row->name}
- {$row->sku} HTML; }) ->searchable(function ($query, $searchTerm) { - $query->where('name', 'like', "%{$searchTerm}%") - ->orWhere('sku', 'like', "%{$searchTerm}%"); + $query->where('name', 'like', "%{$searchTerm}%"); }) ->html(), @@ -98,7 +96,7 @@ class='flex items-center space-x-2 bg-gray-50 border border-gray-200 rounded-lg public function builder(): Builder { - return Product::select('products.id', 'sku', 'products.name', 'sale_price') + return Product::select('products.id', 'products.name', 'sale_price') ->with('outlets') ->whereHas( 'outlets', diff --git a/app/Livewire/Forms/Studio/Catalog/PerfumeForm.php b/app/Livewire/Forms/Studio/Catalog/PerfumeForm.php index c45df20..c1b4537 100644 --- a/app/Livewire/Forms/Studio/Catalog/PerfumeForm.php +++ b/app/Livewire/Forms/Studio/Catalog/PerfumeForm.php @@ -20,8 +20,6 @@ class PerfumeForm extends Form public string $name = ''; - public string $sku = ''; - public ?string $brand_id = null; public string $cost_price = ''; @@ -48,12 +46,6 @@ public function rules(): array { return [ 'name' => ['required', 'string', 'max:50'], - 'sku' => [ - 'required', - 'string', - 'max:20', - Rule::unique('perfumes', 'sku')->ignore($this->perfume), - ], 'brand_id' => ['nullable', Rule::exists('brands', 'id')], 'cost_price' => [Rule::requiredIf(auth()->user()->hasRole(['Developer', 'Owner'])), new UnsignedInteger], 'sale_price' => ['required', new UnsignedInteger], @@ -93,7 +85,6 @@ public function setPerfume(Perfume $perfume): void $this->perfume = $perfume; $this->name = $perfume->name; - $this->sku = $perfume->sku; $this->brand_id = $perfume->brand_id; $this->cost_price = $perfume->cost_price; $this->sale_price = $perfume->sale_price; @@ -181,7 +172,6 @@ private function prepareSavedData(): array { return [ 'name' => $this->name, - 'sku' => $this->sku, 'cost_price' => parseRupiahToInt($this->cost_price == '' ? '0' : $this->cost_price), 'sale_price' => parseRupiahToInt($this->sale_price), 'base_notes' => $this->base_notes, diff --git a/app/Livewire/Forms/Studio/Catalog/ProductForm.php b/app/Livewire/Forms/Studio/Catalog/ProductForm.php index 2a56c66..91ad1d5 100644 --- a/app/Livewire/Forms/Studio/Catalog/ProductForm.php +++ b/app/Livewire/Forms/Studio/Catalog/ProductForm.php @@ -19,8 +19,6 @@ class ProductForm extends Form public string $name = ''; - public string $sku = ''; - public string $cost_price = ''; public string $sale_price = ''; @@ -35,12 +33,6 @@ public function rules(): array { return [ 'name' => ['required', 'string', 'max:50'], - 'sku' => [ - 'required', - 'string', - 'max:20', - Rule::unique('products', 'sku')->ignore($this->product), - ], 'cost_price' => [Rule::requiredIf(auth()->user()->hasRole(['Developer', 'Owner'])), new UnsignedInteger], 'sale_price' => ['required', new UnsignedInteger], 'description' => ['nullable', 'string'], @@ -70,7 +62,6 @@ public function setProduct(Product $product): void $this->product = $product; $this->name = $product->name; - $this->sku = $product->sku; $this->cost_price = $product->cost_price; $this->sale_price = $product->sale_price; $this->description = $product->description; @@ -148,7 +139,6 @@ private function prepareSavedData(): array { return [ 'name' => $this->name, - 'sku' => $this->sku, 'cost_price' => parseRupiahToInt($this->cost_price == '' ? '0' : $this->cost_price), 'sale_price' => parseRupiahToInt($this->sale_price), 'description' => $this->description, diff --git a/app/Livewire/Studio/Manage/Order/Create.php b/app/Livewire/Studio/Manage/Order/Create.php index 24c9853..f1555f8 100644 --- a/app/Livewire/Studio/Manage/Order/Create.php +++ b/app/Livewire/Studio/Manage/Order/Create.php @@ -62,7 +62,7 @@ public function mount(): void $this->perfumes = Perfume::whereHas('outlets', fn ($query) => $query->where('outlets.id', $this->form->outlet_id))->orderBy('name')->pluck('name', 'id')->toArray(); - $this->bottles = Bottle::whereHas('outlets', fn ($query) => $query->where('outlets.id', $this->form->outlet_id))->orderBy('size')->pluck('name', 'id')->toArray(); + $this->bottles = Bottle::whereHas('outlets', fn ($query) => $query->where('outlets.id', $this->form->outlet_id))->get()->pluck('display_name', 'id')->toArray(); $this->products = Product::whereHas('outlets', fn ($query) => $query->where('outlets.id', $this->form->outlet_id))->orderBy('name')->pluck('name', 'id')->toArray(); @@ -113,7 +113,7 @@ public function save(): void public function updatedFormOutletId($value): void { $this->perfumes = Perfume::whereHas('outlets', fn ($query) => $query->where('outlets.id', $value))->orderBy('name')->pluck('name', 'id')->toArray(); - $this->bottles = Bottle::whereHas('outlets', fn ($query) => $query->where('outlets.id', $value))->orderBy('size')->pluck('name', 'id')->toArray(); + $this->bottles = Bottle::whereHas('outlets', fn ($query) => $query->where('outlets.id', $value))->get()->pluck('display_name', 'id')->toArray(); $this->products = Product::whereHas('outlets', fn ($query) => $query->where('outlets.id', $value))->orderBy('name')->pluck('name', 'id')->toArray(); } diff --git a/app/Livewire/Studio/Master/Formula.php b/app/Livewire/Studio/Master/Formula.php index aa74c3d..12cefdc 100644 --- a/app/Livewire/Studio/Master/Formula.php +++ b/app/Livewire/Studio/Master/Formula.php @@ -34,7 +34,7 @@ class Formula extends Component public function mount(): void { - $this->sizes = Bottle::distinct()->orderBy('size')->pluck('size')->toArray(); + $this->sizes = Bottle::distinct()->get()->pluck('size')->toArray(); } public function create(): void diff --git a/app/Livewire/Studio/Stock/Purchase/Create.php b/app/Livewire/Studio/Stock/Purchase/Create.php index 3beea23..5bf3056 100644 --- a/app/Livewire/Studio/Stock/Purchase/Create.php +++ b/app/Livewire/Studio/Stock/Purchase/Create.php @@ -43,7 +43,7 @@ public function mount(): void $this->perfumes = Perfume::orderBy('name')->pluck('name', 'id')->toArray(); - $this->bottles = Bottle::orderBy('name')->pluck('name', 'id')->toArray(); + $this->bottles = Bottle::get()->pluck('display_name', 'id')->toArray(); $this->products = Product::orderBy('name')->pluck('name', 'id')->toArray(); diff --git a/app/Livewire/Studio/Stock/Restock/Create.php b/app/Livewire/Studio/Stock/Restock/Create.php index 1d2536b..1897a62 100644 --- a/app/Livewire/Studio/Stock/Restock/Create.php +++ b/app/Livewire/Studio/Stock/Restock/Create.php @@ -76,23 +76,20 @@ private function loadCreateItems(): void $this->perfumes = $warehouse->perfumes() ->wherePivot('stock', '>', 0) - ->orderBy('name') ->get() ->pluck('name', 'id') ->toArray(); $this->products = $warehouse->products() ->wherePivot('stock', '>', 0) - ->orderBy('name') ->get() ->pluck('name', 'id') ->toArray(); $this->bottles = $warehouse->bottles() ->wherePivot('stock', '>', 0) - ->orderBy('name') ->get() - ->pluck('name', 'id') + ->pluck('display_name', 'id') ->toArray(); } diff --git a/app/Livewire/Studio/Stock/StockTransfer/Create.php b/app/Livewire/Studio/Stock/StockTransfer/Create.php index 6446fc9..e9dad5d 100644 --- a/app/Livewire/Studio/Stock/StockTransfer/Create.php +++ b/app/Livewire/Studio/Stock/StockTransfer/Create.php @@ -76,23 +76,20 @@ private function loadCreateItems(): void $this->perfumes = $sourceOutlet->perfumes() ->wherePivot('stock', '>', 0) - ->orderBy('name') ->get() ->pluck('name', 'id') ->toArray(); $this->products = $sourceOutlet->products() ->wherePivot('stock', '>', 0) - ->orderBy('name') ->get() ->pluck('name', 'id') ->toArray(); $this->bottles = $sourceOutlet->bottles() ->wherePivot('stock', '>', 0) - ->orderBy('name') ->get() - ->pluck('name', 'id') + ->pluck('display_name', 'id') ->toArray(); } diff --git a/app/Models/Bottle.php b/app/Models/Bottle.php index be786c8..4b2a36f 100644 --- a/app/Models/Bottle.php +++ b/app/Models/Bottle.php @@ -2,6 +2,7 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsToMany; @@ -19,6 +20,13 @@ class Bottle extends Model implements HasMedia protected $guarded = ['id']; + protected static function booted(): void + { + static::addGlobalScope('orderedBySize', function ($builder) { + $builder->orderBy('size', 'asc')->orderBy('name', 'asc'); + }); + } + protected function casts(): array { return [ @@ -35,6 +43,13 @@ public function getSlugOptions(): SlugOptions ->saveSlugsTo('slug'); } + protected function displayName(): Attribute + { + return Attribute::make( + get: fn () => "{$this->size}ml {$this->name}", + ); + } + public function items(): MorphMany { return $this->morphMany(OrderItem::class, 'orderable'); diff --git a/app/Models/Perfume.php b/app/Models/Perfume.php index dfcd3df..8911ff7 100644 --- a/app/Models/Perfume.php +++ b/app/Models/Perfume.php @@ -21,6 +21,13 @@ class Perfume extends Model implements HasMedia protected $guarded = ['id']; + protected static function booted(): void + { + static::addGlobalScope('alphabetical', function ($builder) { + $builder->orderBy('name', 'asc'); + }); + } + protected function casts(): array { return [ diff --git a/app/Models/Product.php b/app/Models/Product.php index 492b162..b3ddb46 100644 --- a/app/Models/Product.php +++ b/app/Models/Product.php @@ -19,6 +19,13 @@ class Product extends Model implements HasMedia protected $guarded = ['id']; + protected static function booted(): void + { + static::addGlobalScope('alphabetical', function ($builder) { + $builder->orderBy('name', 'asc'); + }); + } + protected function casts(): array { return [ diff --git a/database/factories/PerfumeFactory.php b/database/factories/PerfumeFactory.php index a5ef57f..6059cb2 100644 --- a/database/factories/PerfumeFactory.php +++ b/database/factories/PerfumeFactory.php @@ -20,7 +20,6 @@ public function definition(): array 'brand_id' => Brand::factory(), 'name' => Str::title($name), 'slug' => Str::slug($name.'-'.$this->faker->unique()->randomNumber()), - 'sku' => strtoupper($this->faker->unique()->bothify('PER-#####')), 'concentration' => $this->faker->randomElement(Concentration::cases()), 'cost_price' => $this->faker->numberBetween(50000, 250000), 'sale_price' => $this->faker->numberBetween(80000, 400000), diff --git a/database/factories/ProductFactory.php b/database/factories/ProductFactory.php index e4a5527..472475c 100644 --- a/database/factories/ProductFactory.php +++ b/database/factories/ProductFactory.php @@ -17,7 +17,6 @@ public function definition(): array return [ 'name' => Str::title($name), 'slug' => Str::slug($name.'-'.$this->faker->unique()->randomNumber()), - 'sku' => strtoupper($this->faker->unique()->bothify('PRD-#####')), 'cost_price' => $this->faker->numberBetween(20000, 150000), 'sale_price' => $this->faker->numberBetween(30000, 200000), ]; diff --git a/database/migrations/2026_02_12_155236_remove_sku_from_perfumes_and_products.php b/database/migrations/2026_02_12_155236_remove_sku_from_perfumes_and_products.php new file mode 100644 index 0000000..d180804 --- /dev/null +++ b/database/migrations/2026_02_12_155236_remove_sku_from_perfumes_and_products.php @@ -0,0 +1,36 @@ +dropColumn('sku'); + }); + + Schema::table('products', function (Blueprint $table) { + $table->dropColumn('sku'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('perfumes', function (Blueprint $table) { + $table->string('sku', 20)->unique()->after('slug'); + }); + + Schema::table('products', function (Blueprint $table) { + $table->string('sku', 20)->unique()->after('slug'); + }); + } +}; diff --git a/database/seeders/PerfumeSeeder.php b/database/seeders/PerfumeSeeder.php index 7de3e1d..6f1e23b 100644 --- a/database/seeders/PerfumeSeeder.php +++ b/database/seeders/PerfumeSeeder.php @@ -32,7 +32,6 @@ public function run(): void foreach ($perfumeNames as $index => $name) { $brand = $brands[$index % $brands->count()]; $slug = Str::slug($name); - $sku = Str::upper(Str::random(3)).'-'.str_pad($index + 1, 4, '0', STR_PAD_LEFT); $salePrice = fake()->numberBetween(25, 50) * 100; @@ -40,7 +39,6 @@ public function run(): void 'brand_id' => $brand->id, 'name' => $name, 'slug' => $slug, - 'sku' => $sku, 'concentration' => fake()->randomElement(Concentration::values()), 'cost_price' => fake()->numberBetween(5, 11) * 100, 'sale_price' => $salePrice, diff --git a/database/seeders/ProductSeeder.php b/database/seeders/ProductSeeder.php index f110cac..06c405f 100644 --- a/database/seeders/ProductSeeder.php +++ b/database/seeders/ProductSeeder.php @@ -26,14 +26,12 @@ public function run(): void foreach ($products as $index => $name) { $slug = Str::slug($name); - $sku = Str::upper(Str::random(3)).'-'.str_pad($index + 1, 4, '0', STR_PAD_LEFT); $salePrice = fake()->numberBetween(15, 200) * 1000; $product = Product::create([ 'name' => $name, 'slug' => $slug, - 'sku' => $sku, 'cost_price' => fake()->numberBetween(15, 80) * 1000, 'sale_price' => $salePrice, 'description' => fake()->sentence(12), diff --git a/resources/views/livewire/studio/catalog/perfume/form.blade.php b/resources/views/livewire/studio/catalog/perfume/form.blade.php index b8e8ee1..0fa6fcb 100644 --- a/resources/views/livewire/studio/catalog/perfume/form.blade.php +++ b/resources/views/livewire/studio/catalog/perfume/form.blade.php @@ -25,12 +25,6 @@ - - SKU * - - -
- - SKU * - - - @if (auth()->user()->hasRole(['Developer', 'Owner'])) diff --git a/resources/views/livewire/studio/stock/stock-opname/manage.blade.php b/resources/views/livewire/studio/stock/stock-opname/manage.blade.php index ee8043e..7900182 100644 --- a/resources/views/livewire/studio/stock/stock-opname/manage.blade.php +++ b/resources/views/livewire/studio/stock/stock-opname/manage.blade.php @@ -29,7 +29,7 @@ @foreach ($items as $item) - {{ $item->itemable?->name }} + {{ $item->itemable?->display_name ?? $item->itemable?->name }} {{ $item->qty_system }} @foreach ($items as $item) - {{ $item->itemable?->name }} + {{ $item->itemable?->display_name ?? $item->itemable?->name }} {{ $item->qty_system }} {{ $item->qty_physical }}