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..ed639a565f --- /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' => 'min']); +}); 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',