refactor: Improve quantity and monetary value handling in DelayedGoodForm and DelayedGoodsTable, enhancing state management and formatting for better user experience.

This commit is contained in:
Yoga Pangestu 2026-03-07 13:13:14 +07:00
parent 48b182cd4b
commit 49387e7923
2 changed files with 68 additions and 35 deletions

View File

@ -14,16 +14,47 @@ class DelayedGoodForm
{
public static function configure(Schema $schema): Schema
{
$recalculateTotal = function (callable $get, callable $set): void {
$quantity = (int) str()->replace('.', '', (string) ($get('quantity') ?? 0));
$unitPrice = (int) str()->replace('.', '', (string) ($get('unit_price') ?? 0));
$unmaskQty = function ($state) {
if (blank($state)) {
return 0;
}
if (is_int($state) || is_float($state)) {
return $state;
}
return (float) str($state)
->replace(',', '.')
->toString();
};
$unmaskMoney = function ($state) {
if (blank($state)) {
return 0;
}
if (is_int($state) || is_float($state)) {
return $state;
}
return (float) str($state)
->replace('.', '')
->replace(',', '.')
->toString();
};
$recalculateTotal = function (callable $get, callable $set) use ($unmaskMoney, $unmaskQty): void {
$quantity = $unmaskQty($get('quantity'));
$unitPrice = $unmaskMoney($get('unit_price'));
$totalAmount = $quantity * $unitPrice;
$set('total_amount', number_format($totalAmount, 0, ',', '.'));
};
$recalculateRemaining = function (callable $get, callable $set): void {
$paidAmount = (int) str()->replace('.', '', (string) ($get('paid_amount') ?? 0));
$totalAmount = (int) str()->replace('.', '', (string) ($get('total_amount') ?? 0));
$recalculateRemaining = function (callable $get, callable $set) use ($unmaskMoney): void {
$paidAmount = $unmaskMoney($get('paid_amount'));
$totalAmount = $unmaskMoney($get('total_amount'));
$remaining = max(0, $totalAmount - $paidAmount);
@ -61,8 +92,9 @@ public static function configure(Schema $schema): Schema
$recalculateTotal($get, $set);
$recalculateRemaining($get, $set);
})
->currencyMask(thousandSeparator: '.', decimalSeparator: ',', precision: 0)
->dehydrateStateUsing(fn ($state) => (int) str()->replace('.', '', (string) ($state ?? 0))),
->currencyMask(thousandSeparator: '.', decimalSeparator: ',', precision: 2)
->formatStateUsing(fn($state) => $state === null ? null : (float) $state)
->dehydrateStateUsing($unmaskQty),
TextInput::make('unit_price')
->label('Harga per Satuan')
@ -72,7 +104,7 @@ public static function configure(Schema $schema): Schema
->required()
->live()
->currencyMask(thousandSeparator: '.', decimalSeparator: ',', precision: 0)
->dehydrateStateUsing(fn ($state) => (int) str()->replace('.', '', (string) ($state ?? 0)))
->dehydrateStateUsing($unmaskMoney)
->afterStateUpdated(function ($state, callable $get, callable $set) use ($recalculateTotal, $recalculateRemaining): void {
$recalculateTotal($get, $set);
$recalculateRemaining($get, $set);
@ -97,9 +129,9 @@ public static function configure(Schema $schema): Schema
->required()
->live()
->formatStateUsing(
fn ($state) => number_format((int) ($state ?? 0), 0, ',', '.')
fn($state) => number_format((float) ($state ?? 0), 0, ',', '.')
)
->dehydrateStateUsing(fn ($state) => (int) str()->replace('.', '', (string) ($state ?? 0))),
->dehydrateStateUsing($unmaskMoney),
TextInput::make('paid_amount')
->label('Jumlah yang Sudah Dibayar (DP)')
@ -110,9 +142,9 @@ public static function configure(Schema $schema): Schema
->live()
->prefix('Rp')
->readOnly(fn(callable $get) => $get('is_paid'))
->afterStateUpdated(function ($state, callable $get, callable $set) use ($recalculateRemaining): void {
$paidAmount = (int) str()->replace('.', '', (string) ($state ?? 0));
$totalAmount = (int) str()->replace('.', '', (string) ($get('total_amount') ?? 0));
->afterStateUpdated(function ($state, callable $get, callable $set) use ($recalculateRemaining, $unmaskMoney): void {
$paidAmount = $unmaskMoney($state);
$totalAmount = $unmaskMoney($get('total_amount'));
$recalculateRemaining($get, $set);
@ -129,7 +161,7 @@ public static function configure(Schema $schema): Schema
}
})
->currencyMask(thousandSeparator: '.', decimalSeparator: ',', precision: 0)
->dehydrateStateUsing(fn ($state) => (int) str()->replace('.', '', (string) ($state ?? 0))),
->dehydrateStateUsing($unmaskMoney),
TextInput::make('remaining_amount')
->label('Sisa Pembayaran')
@ -138,9 +170,9 @@ public static function configure(Schema $schema): Schema
->prefix('Rp')
->default(0)
->live()
->formatStateUsing(function ($state, callable $get) {
$paidAmount = (int) str()->replace('.', '', (string) ($get('paid_amount') ?? 0));
$totalAmount = (int) str()->replace('.', '', (string) ($get('total_amount') ?? 0));
->formatStateUsing(function ($state, callable $get) use ($unmaskMoney) {
$paidAmount = $unmaskMoney($get('paid_amount'));
$totalAmount = $unmaskMoney($get('total_amount'));
$remaining = max(0, $totalAmount - $paidAmount);
return number_format($remaining, 0, ',', '.');
@ -151,11 +183,11 @@ public static function configure(Schema $schema): Schema
->label('Lunas')
->default(false)
->live()
->afterStateUpdated(function ($state, callable $get, callable $set) use ($recalculateRemaining): void {
$totalAmount = (int) str()->replace('.', '', (string) ($get('total_amount') ?? 0));
->afterStateUpdated(function ($state, callable $get, callable $set) use ($recalculateRemaining, $unmaskMoney): void {
$totalAmount = $unmaskMoney($get('total_amount'));
if ($state) {
$set('paid_amount', $totalAmount);
$set('paid_amount', number_format($totalAmount, 0, ',', '.'));
if (! $get('payment_date')) {
$set('payment_date', now());
@ -172,9 +204,9 @@ public static function configure(Schema $schema): Schema
->label('Tanggal Pembayaran Lunas')
->native(false)
->displayFormat('l, d F Y')
->visible(function (callable $get) {
$paidAmount = (int) str()->replace('.', '', (string) ($get('paid_amount') ?? 0));
$totalAmount = (int) str()->replace('.', '', (string) ($get('total_amount') ?? 0));
->visible(function (callable $get) use ($unmaskMoney) {
$paidAmount = $unmaskMoney($get('paid_amount'));
$totalAmount = $unmaskMoney($get('total_amount'));
return $paidAmount >= $totalAmount && $totalAmount > 0;
}),

View File

@ -36,8 +36,9 @@ public static function configure(Table $table): Table
TextColumn::make('quantity')
->label('Jumlah')
->suffix(fn ($record) => ' '.$record->unit?->alias)
->numeric()
->getStateUsing(function ($record) {
return str_replace('.', ',', (float) $record->quantity) . " {$record->unit?->alias}";
})
->sortable(),
TextColumn::make('unit_price')
@ -103,7 +104,7 @@ public static function configure(Table $table): Table
->prefix('Rp')
->live()
->currencyMask(thousandSeparator: '.', decimalSeparator: ',', precision: 0)
->dehydrateStateUsing(fn ($state) => (int) str()->replace('.', '', (string) ($state ?? 0))),
->dehydrateStateUsing(fn($state) => (float) str()->replace(',', '.', str()->replace('.', '', (string) ($state ?? 0)))),
])
->requiresConfirmation()
->action(function (array $data, $record) {