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 }}