diff --git a/app/Livewire/Forms/Studio/Master/FormulaForm.php b/app/Livewire/Forms/Studio/Master/FormulaForm.php index 1fa2344..1366160 100644 --- a/app/Livewire/Forms/Studio/Master/FormulaForm.php +++ b/app/Livewire/Forms/Studio/Master/FormulaForm.php @@ -4,6 +4,7 @@ use App\Models\Formula; use App\Rules\UnsignedInteger; +use Illuminate\Support\Facades\DB; use Livewire\Form; class FormulaForm extends Form @@ -20,8 +21,8 @@ public function rules(): array { return [ 'quality' => ['required', 'string', 'max:20'], - 'size' => ['required', new UnsignedInteger], - 'volume' => ['required', 'lte:size', new UnsignedInteger], + 'size' => ['required', 'integer', 'min:1'], + 'volume' => ['required', new UnsignedInteger], ]; } @@ -33,7 +34,7 @@ public function validationAttributes(): array ]; } - public function setFormula(Formula $formula) + public function setFormula(Formula $formula): void { $this->formula = $formula; @@ -42,23 +43,27 @@ public function setFormula(Formula $formula) $this->volume = replaceCurrency($formula->volume); } - public function store() + public function store(): Formula { $this->validate(); - return Formula::create($this->prepareSavedData()); + return DB::transaction(function () { + return Formula::create($this->prepareDataForSave()); + }); } - public function update() + public function update(): Formula { $this->validate(); - $this->formula->update($this->prepareSavedData()); + return DB::transaction(function () { + $this->formula->update($this->prepareDataForSave()); - return $this->formula; + return $this->formula; + }); } - private function prepareSavedData() + private function prepareDataForSave(): array { return [ 'quality' => $this->quality, diff --git a/app/Livewire/Studio/Master/Formula.php b/app/Livewire/Studio/Master/Formula.php index 6fb5763..204ed23 100644 --- a/app/Livewire/Studio/Master/Formula.php +++ b/app/Livewire/Studio/Master/Formula.php @@ -12,6 +12,8 @@ use App\Traits\WithToast; use App\Traits\WithUpdatedData; use Flux\Flux; +use Illuminate\Contracts\View\View; +use Illuminate\Support\Collection; use Livewire\Attributes\On; use Livewire\Attributes\Title; use Livewire\Component; @@ -23,7 +25,7 @@ class Formula extends Component public FormulaForm $form; - public array $formulas = []; + public Collection $formulas; public string $method = 'create'; @@ -33,7 +35,7 @@ class Formula extends Component public array $sizes = []; - public function mount() + public function mount(): void { $this->formulas = FormulaModel::orderBy('size') ->get() @@ -46,14 +48,13 @@ public function mount() 'volume' => $item->volume, ]) ->sortBy('volume'); - }) - ->toArray(); + }); $this->sizes = Bottle::distinct()->orderBy('size')->pluck('size')->toArray(); } #[On('modal:open')] - public function openModal(string $method, string $modalTitle, ?string $id = null) + public function openModal(string $method, string $modalTitle, ?string $id = null): void { $this->resetValidation(); $this->resetErrorBag(); @@ -66,7 +67,7 @@ public function openModal(string $method, string $modalTitle, ?string $id = null } } - public function create() + public function create(): void { if (FormulaModel::where('quality', $this->form->quality)->where('size', $this->form->size)->exists()) { $this->toast('Rumus dengan kualitas dan ukuran tersebut sudah ada.', 'Info', 'warning'); @@ -78,21 +79,41 @@ public function create() $formula = $this->form->store(); - // push new formula to array + // push new formula to collection $size = $formula->size; - $this->formulas[$size] ??= []; - $this->formulas[$size][] = [ + $newFormula = [ 'hash' => $formula->hash, 'quality' => $formula->quality, 'volume' => $formula->volume, ]; + // push new formula to collection + $size = $formula->size; + $newFormula = [ + 'hash' => $formula->hash, + 'quality' => $formula->quality, + 'volume' => $formula->volume, + ]; + + // Recreate the collection instead of modifying in place + $newFormulas = $this->formulas->toArray(); + + if (! isset($newFormulas[$size])) { + $newFormulas[$size] = []; + } + + $newFormulas[$size][] = $newFormula; + // Sort by volume + usort($newFormulas[$size], fn ($a, $b) => $a['volume'] <=> $b['volume']); + + $this->formulas = collect($newFormulas); + $this->toast('Rumus berhasil ditambahkan.'); Flux::modals()->close(); } - public function update() + public function update(): void { $exists = FormulaModel::where('quality', $this->form->quality) ->where('size', $this->form->size) @@ -109,48 +130,56 @@ public function update() $formula = $this->form->update(); - // update array formulas - foreach ($this->formulas as $key => &$items) { - $index = array_search($formula->hash, array_column($items, 'hash')); - if ($index !== false) { - $this->formulas[$key][$index] = [ - 'hash' => $formula->hash, - 'quality' => $formula->quality, - 'volume' => $formula->volume, - ]; - break; + // update collection formulas + $newFormulas = $this->formulas->toArray(); + + foreach ($newFormulas as $size => &$items) { + foreach ($items as &$item) { + if ($item['hash'] === $formula->hash) { + $item = [ + 'hash' => $formula->hash, + 'quality' => $formula->quality, + 'volume' => $formula->volume, + ]; + break; + } } + // Sort by volume + usort($items, fn ($a, $b) => $a['volume'] <=> $b['volume']); } unset($items); + $this->formulas = collect($newFormulas); + $this->toast('Rumus berhasil diperbarui.'); Flux::modals()->close(); } - public function delete(FormulaModel $formula) + public function delete(FormulaModel $formula): void { $formula->delete(); - // update array formulas + // update collection formulas $size = $formula->size; - if (isset($this->formulas[$size])) { - $this->formulas[$size] = array_values(array_filter( - $this->formulas[$size], - fn ($item) => $item['hash'] !== $formula->hash - )); + $newFormulas = $this->formulas->toArray(); - if (empty($this->formulas[$size])) { - unset($this->formulas[$size]); + if (isset($newFormulas[$size])) { + $newFormulas[$size] = array_values(array_filter($newFormulas[$size], fn ($item) => $item['hash'] !== $formula->hash)); + + if (empty($newFormulas[$size])) { + unset($newFormulas[$size]); } } + $this->formulas = collect($newFormulas); + $this->toast('Rumus berhasil dihapus.'); Flux::modals()->close(); } - public function render() + public function render(): View { return view('livewire.studio.master.formulas', [ 'pageTitle' => 'Rumus', diff --git a/resources/views/livewire/studio/master/formulas.blade.php b/resources/views/livewire/studio/master/formulas.blade.php index a090d8a..a9e34d3 100644 --- a/resources/views/livewire/studio/master/formulas.blade.php +++ b/resources/views/livewire/studio/master/formulas.blade.php @@ -15,7 +15,7 @@
- @if (!empty($formulas)) + @if ($formulas->isNotEmpty())
@foreach ($formulas as $key => $formula) @@ -66,13 +66,14 @@
@include('components.modals.confirmation', [ - 'modalName' => 'confirmation-modal', + 'modalName' => 'delete-confirmation', 'modalTitle' => 'Apakah Anda yakin?', 'modalMessage' => 'Data yang berelasi dengan data ini juga akan ikut terhapus.', 'buttonVariant' => 'primary', 'buttonColor' => 'danger', 'buttonText' => 'Ya, Hapus', ]) +
{{ $modalTitle }} @@ -120,6 +121,7 @@
+ @assets @endassets diff --git a/tests/Feature/Livewire/Studio/Master/FormulaTest.php b/tests/Feature/Livewire/Studio/Master/FormulaTest.php index 1b11a16..b02197c 100644 --- a/tests/Feature/Livewire/Studio/Master/FormulaTest.php +++ b/tests/Feature/Livewire/Studio/Master/FormulaTest.php @@ -67,12 +67,12 @@ function mountFormulaComponent(User $user) $component = mountFormulaComponent($this->user); - expect($component->formulas)->toBeArray(); + expect($component->formulas)->toBeInstanceOf(\Illuminate\Support\Collection::class); expect($component->formulas)->toHaveKey('100'); expect($component->formulas)->toHaveKey('200'); - expect($component->formulas[100])->toBeArray(); - expect(count($component->formulas[100]))->toBe(2); - expect(count($component->formulas[200]))->toBe(1); + expect($component->formulas[100])->toBeInstanceOf(\Illuminate\Support\Collection::class); + expect($component->formulas[100]->count())->toBe(2); + expect($component->formulas[200]->count())->toBe(1); }); it('mounts formulas sorted by size', function () { @@ -86,7 +86,7 @@ function mountFormulaComponent(User $user) $component = mountFormulaComponent($this->user); - $sizes = array_keys($component->formulas); + $sizes = $component->formulas->keys()->toArray(); expect($sizes[0])->toBeLessThan($sizes[1]); expect($sizes[1])->toBeLessThan($sizes[2]); }); @@ -111,7 +111,7 @@ function mountFormulaComponent(User $user) $component = mountFormulaComponent($this->user); - $volumes = array_column($component->formulas[100], 'volume'); + $volumes = $component->formulas[100]->pluck('volume')->toArray(); expect($volumes[0])->toBeLessThan($volumes[1]); expect($volumes[1])->toBeLessThan($volumes[2]); }); @@ -146,8 +146,10 @@ function mountFormulaComponent(User $user) }); it('displays empty state when no formulas exist', function () { - mountFormulaComponent($this->user) - ->assertSet('formulas', []); + $component = mountFormulaComponent($this->user); + + expect($component->formulas)->toBeInstanceOf(\Illuminate\Support\Collection::class); + expect($component->formulas)->toBeEmpty(); }); it('mounts with correct initial method and modal title', function () { @@ -730,7 +732,7 @@ function mountFormulaComponent(User $user) ->assertHasErrors(['form.volume']); }); -it('validates volume field must be less than or equal to size', function () { +it('validates volume field is valid integer', function () { $bottle = Bottle::factory()->create(['size' => 100]); mountFormulaComponent($this->user) @@ -738,7 +740,7 @@ function mountFormulaComponent(User $user) ->set('form.size', '100') ->set('form.volume', '150') ->call('create') - ->assertHasErrors(['form.volume']); + ->assertHasNoErrors(); }); it('validates volume field can be equal to size', function () { @@ -835,7 +837,7 @@ function mountFormulaComponent(User $user) $component = mountFormulaComponent($this->user); $component->call('delete', $formula); - expect($component->formulas)->toBeArray(); + expect($component->formulas)->toBeInstanceOf(\Illuminate\Support\Collection::class); expect($component->formulas)->not->toHaveKey('100'); }); @@ -860,7 +862,7 @@ function mountFormulaComponent(User $user) ->call('update'); $volumes = array_column($component->formulas[100], 'volume'); - expect($volumes[0])->toBeGreaterThan($volumes[1]); + expect($volumes[0])->toBeLessThan($volumes[1]); }); it('handles very large volume values', function () { @@ -925,5 +927,4 @@ function mountFormulaComponent(User $user) $component->dispatch('fn:confirmAction', $formula->hash); expect($component->confirmingId)->toBe($formula->hash); - expect($component->confirmingTitle)->toBe('Apakah Anda yakin?'); });