From 0a643efbb6d7850fd6fbd2c392b355a5fe280ad5 Mon Sep 17 00:00:00 2001 From: Yoga Pangestu Date: Sat, 7 Mar 2026 12:03:12 +0700 Subject: [PATCH] feat: Enhance WarehouseResource with stock management features, including a repeater for stock entries and improved quantity handling in the WarehouseStock model --- .../Master/Warehouses/WarehouseResource.php | 55 ++++++++++++++++--- app/Models/WarehouseStock.php | 9 ++- ..._02_01_000000_create_warehouses_table.php} | 0 ...7_003159_create_warehouse_stocks_table.php | 3 +- ...gg_collections_totals_to_decimal_final.php | 24 -------- 5 files changed, 56 insertions(+), 35 deletions(-) rename database/migrations/{2026_03_06_164222_create_warehouses_table.php => 2026_02_01_000000_create_warehouses_table.php} (100%) delete mode 100644 database/migrations/2026_03_07_003345_modify_egg_collections_totals_to_decimal_final.php diff --git a/app/Filament/Resources/Master/Warehouses/WarehouseResource.php b/app/Filament/Resources/Master/Warehouses/WarehouseResource.php index d61c8fa..df73321 100644 --- a/app/Filament/Resources/Master/Warehouses/WarehouseResource.php +++ b/app/Filament/Resources/Master/Warehouses/WarehouseResource.php @@ -13,6 +13,8 @@ use App\Models\Warehouse; use BackedEnum; use Filament\Actions\BulkActionGroup; +use Filament\Forms\Components\Repeater; +use Filament\Forms\Components\Select; use Filament\Forms\Components\TextInput; use Filament\Resources\Resource; use Filament\Schemas\Schema; @@ -46,11 +48,47 @@ public static function form(Schema $schema): Schema return $schema ->components([ TextInput::make('name') - ->label('Nama Gudang') + ->label('Nama') ->placeholder('Gudang Utama') ->autocomplete(false) ->required() ->maxLength(30), + + Repeater::make('stocks') + ->label('Stok Telur') + ->relationship('stocks') + ->schema([ + Select::make('unit_id') + ->label('Satuan') + ->relationship('unit', 'name') + ->required() + ->searchable() + ->preload(), + + TextInput::make('quantity') + ->label('Jumlah') + ->placeholder('0') + ->autocomplete(false) + ->required() + ->currencyMask(thousandSeparator: '.', decimalSeparator: ',', precision: 2) + ->formatStateUsing(fn ($state) => $state === null ? null : (float) $state) + ->dehydrateStateUsing(function ($state) { + if (blank($state)) { + return 0; + } + if (is_numeric($state)) { + return (float) $state; + } + + return (float) str($state) + ->replace('.', '') + ->replace(',', '.') + ->toString(); + }), + ]) + ->columns(2) + ->addActionLabel('Tambah Stok') + ->columnSpanFull(), ]) ->columns(1); } @@ -60,22 +98,23 @@ public static function table(Table $table): Table return $table ->columns([ TextColumn::make('name') - ->label('Nama Gudang') + ->label('Nama') ->searchable() ->sortable(), TextColumn::make('stocks') - ->label('Stok Telur') + ->label('Stok') ->getStateUsing(function (Warehouse $record) { return $record->stocks() ->where('quantity', '>', 0) ->with('unit') ->get() - ->map(fn ($stock) => (float) $stock->quantity.' '.$stock->unit?->alias.($stock->is_broken ? ' (Pecah)' : '')) - ->join(', ') ?: 'Kosong'; + ->map(fn ($stock) => str_replace('.', ',', (float) $stock->quantity).' '.$stock->unit?->alias) + ->toArray(); }) - ->badge() - ->color('info'), + ->listWithLineBreaks() + ->color('info') + ->placeholder('Kosong'), ...TimestampColumns::make(), ]) @@ -86,7 +125,7 @@ public static function table(Table $table): Table ]) ->recordActions([ EditAction::make() - ->modalWidth(Width::Large), + ->modalWidth(Width::FourExtraLarge), DeleteAction::make(), diff --git a/app/Models/WarehouseStock.php b/app/Models/WarehouseStock.php index 5945ee2..d320ee4 100644 --- a/app/Models/WarehouseStock.php +++ b/app/Models/WarehouseStock.php @@ -11,6 +11,10 @@ class WarehouseStock extends Model protected $guarded = ['id']; + protected $casts = [ + 'quantity' => 'decimal:2', + ]; + public function warehouse() { return $this->belongsTo(Warehouse::class); @@ -23,10 +27,13 @@ public function unit() public static function adjustStock(int $warehouseId, int $unitId, bool $isBroken, float $quantity): void { + if ($isBroken) { + return; + } + $stock = self::firstOrCreate([ 'warehouse_id' => $warehouseId, 'unit_id' => $unitId, - 'is_broken' => $isBroken, ], [ 'quantity' => 0, ]); diff --git a/database/migrations/2026_03_06_164222_create_warehouses_table.php b/database/migrations/2026_02_01_000000_create_warehouses_table.php similarity index 100% rename from database/migrations/2026_03_06_164222_create_warehouses_table.php rename to database/migrations/2026_02_01_000000_create_warehouses_table.php diff --git a/database/migrations/2026_03_07_003159_create_warehouse_stocks_table.php b/database/migrations/2026_03_07_003159_create_warehouse_stocks_table.php index ab7762d..e315637 100644 --- a/database/migrations/2026_03_07_003159_create_warehouse_stocks_table.php +++ b/database/migrations/2026_03_07_003159_create_warehouse_stocks_table.php @@ -12,11 +12,10 @@ public function up(): void $table->id(); $table->foreignId('warehouse_id')->constrained()->cascadeOnDelete(); $table->foreignId('unit_id')->constrained()->cascadeOnDelete(); - $table->boolean('is_broken')->default(false); $table->decimal('quantity', 12, 2)->default(0); $table->timestamps(); - $table->unique(['warehouse_id', 'unit_id', 'is_broken'], 'warehouse_unit_condition_unique'); + $table->unique(['warehouse_id', 'unit_id'], 'warehouse_unit_unique'); }); } diff --git a/database/migrations/2026_03_07_003345_modify_egg_collections_totals_to_decimal_final.php b/database/migrations/2026_03_07_003345_modify_egg_collections_totals_to_decimal_final.php deleted file mode 100644 index 15bea57..0000000 --- a/database/migrations/2026_03_07_003345_modify_egg_collections_totals_to_decimal_final.php +++ /dev/null @@ -1,24 +0,0 @@ -decimal('total_eggs', 12, 2)->default(0)->change(); - $table->decimal('total_broken_eggs', 12, 2)->default(0)->change(); - }); - } - - public function down(): void - { - Schema::table('egg_collections', function (Blueprint $table) { - $table->unsignedInteger('total_eggs')->default(0)->change(); - $table->unsignedInteger('total_broken_eggs')->default(0)->change(); - }); - } -};