feat: Enhance WarehouseResource with stock management features, including a repeater for stock entries and improved quantity handling in the WarehouseStock model
This commit is contained in:
parent
c6e7119b94
commit
0a643efbb6
@ -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(),
|
||||
|
||||
|
||||
@ -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,
|
||||
]);
|
||||
|
||||
@ -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');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -1,24 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('egg_collections', function (Blueprint $table) {
|
||||
$table->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();
|
||||
});
|
||||
}
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user