From 17e29b23cdde316e61a49d8506878288418760b9 Mon Sep 17 00:00:00 2001 From: Vajda Lehel Date: Sat, 4 Jul 2026 17:47:30 +0300 Subject: [PATCH 1/2] Enforce a minimum unit quantity of 1 Add minValue(1) to the unit quantity form field on ProductVariantResource and clamp DefaultPriceFormatter's unitQty to 1 in the constructor, so a zero or negative value can't be entered or divided by when computing unit prices. --- .../Resources/ProductVariantResource.php | 4 ++- .../src/Pricing/DefaultPriceFormatter.php | 4 +++ .../Pages/ManageVariantInventoryTest.php | 33 +++++++++++++++++++ tests/core/Unit/DataTypes/PriceTest.php | 12 +++++++ 4 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 tests/admin/Feature/Filament/Resources/ProductVariantResource/Pages/ManageVariantInventoryTest.php diff --git a/packages/admin/src/Filament/Resources/ProductVariantResource.php b/packages/admin/src/Filament/Resources/ProductVariantResource.php index 14a37f3877..e93fca0f2d 100644 --- a/packages/admin/src/Filament/Resources/ProductVariantResource.php +++ b/packages/admin/src/Filament/Resources/ProductVariantResource.php @@ -154,7 +154,9 @@ public static function getUnitQtyFormComponent(): TextInput __('lunarpanel::productvariant.form.unit_quantity.label') )->helperText( __('lunarpanel::productvariant.form.unit_quantity.helper_text') - )->numeric(); + ) + ->numeric() + ->minValue(1); } public static function getQuantityIncrementFormComponent(): TextInput diff --git a/packages/core/src/Pricing/DefaultPriceFormatter.php b/packages/core/src/Pricing/DefaultPriceFormatter.php index 397dd40d7d..5f163eec2e 100644 --- a/packages/core/src/Pricing/DefaultPriceFormatter.php +++ b/packages/core/src/Pricing/DefaultPriceFormatter.php @@ -14,6 +14,10 @@ public function __construct( public ?CurrencyContract $currency = null, public int $unitQty = 1 ) { + if ($this->unitQty < 1) { + $this->unitQty = 1; + } + if (! $this->currency) { $this->currency = Currency::getDefault(); } diff --git a/tests/admin/Feature/Filament/Resources/ProductVariantResource/Pages/ManageVariantInventoryTest.php b/tests/admin/Feature/Filament/Resources/ProductVariantResource/Pages/ManageVariantInventoryTest.php new file mode 100644 index 0000000000..d6fde226c9 --- /dev/null +++ b/tests/admin/Feature/Filament/Resources/ProductVariantResource/Pages/ManageVariantInventoryTest.php @@ -0,0 +1,33 @@ +group('resource.product-variant'); + +it('rejects a unit quantity below one', function () { + Language::factory()->create(['default' => true]); + Currency::factory()->create(['default' => true]); + + $product = Product::factory()->create(); + + $variant = ProductVariant::factory()->create([ + 'product_id' => $product->id, + ]); + + $this->asStaff(); + + Livewire::test( + ManageVariantInventory::class, [ + 'record' => $variant->getRouteKey(), + ])->fillForm([ + 'unit_quantity' => 0, + ])->call('save') + ->assertHasFormErrors(['unit_quantity' => 'minValue']); +}); diff --git a/tests/core/Unit/DataTypes/PriceTest.php b/tests/core/Unit/DataTypes/PriceTest.php index 8c41d2cff7..ead3e1f4da 100644 --- a/tests/core/Unit/DataTypes/PriceTest.php +++ b/tests/core/Unit/DataTypes/PriceTest.php @@ -61,6 +61,18 @@ expect($dataType->unitFormatted(null, NumberFormatter::CURRENCY, 4))->toEqual('£0.1155'); }); +test('unit qty below one is clamped to one', function () { + $currency = Currency::factory()->create([ + 'code' => 'GBP', + 'decimal_places' => 2, + ]); + + $dataType = new Price(1500, $currency, 0); + + expect($dataType->unitDecimal())->toEqual(15.00); + expect($dataType->unitFormatted())->toEqual('£15.00'); +}); + test('can handle no decimal places', function () { $currency = Currency::factory()->create([ 'code' => 'VND', From 90826895cc8d102afdb018e5f60046855ba39941 Mon Sep 17 00:00:00 2001 From: Vajda Lehel Date: Sat, 4 Jul 2026 18:03:31 +0300 Subject: [PATCH 2/2] fix(tests): correct error message for minimum unit quantity validation --- .../ProductVariantResource/Pages/ManageVariantInventoryTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/admin/Feature/Filament/Resources/ProductVariantResource/Pages/ManageVariantInventoryTest.php b/tests/admin/Feature/Filament/Resources/ProductVariantResource/Pages/ManageVariantInventoryTest.php index d6fde226c9..ed639a565f 100644 --- a/tests/admin/Feature/Filament/Resources/ProductVariantResource/Pages/ManageVariantInventoryTest.php +++ b/tests/admin/Feature/Filament/Resources/ProductVariantResource/Pages/ManageVariantInventoryTest.php @@ -29,5 +29,5 @@ ])->fillForm([ 'unit_quantity' => 0, ])->call('save') - ->assertHasFormErrors(['unit_quantity' => 'minValue']); + ->assertHasFormErrors(['unit_quantity' => 'min']); });