fix: enforce stock limits on basket quantities

No stock validation existed in the ordering flow, allowing customers
to order more items than available.

Cap quantity to ``stock_current`` in ``Baskets::getBasketData()`` when
adding to cart. Add ``min=1`` and ``max=stock`` attributes on the
basket quantity input, with JS clamping in the change handler.
Verify stock again in ``Shop\OrderController::store()`` before saving
the order as a race-condition safeguard.
This commit is contained in:
Valentin Lab
2026-02-20 12:17:22 +01:00
parent ef52addc7d
commit 63673117b3
6 changed files with 65 additions and 3 deletions

View File

@@ -18,8 +18,9 @@
'name' => 'quantity',
'class' => 'quantity',
'id_name' => $model . '-quantity',
'value' => (int) $data[0]['prices'][0]['quantity'],
'min' => $data[0]['prices'][0]['quantity'],
'value' => 1,
'min' => 1,
'max' => $data[0]['stock'] ?? false,
'step' => 1,
])
</div>
@@ -44,10 +45,35 @@
@push('js')
<script>
var {{ $model }}Stocks = {
@foreach ($data as $offer)
{{ $offer['id'] }}: {{ $offer['stock'] !== null ? $offer['stock'] : 'null' }},
@endforeach
};
function update{{ ucfirst($model) }}Max() {
var offerId = $('#{{ $model }}-offer_id').find('option:selected').val();
var stock = {{ $model }}Stocks[offerId];
var input = $('#{{ $model }}-quantity');
if (stock !== null && stock !== undefined) {
input.attr('max', stock);
if (parseInt(input.val()) > stock) {
input.val(stock);
}
} else {
input.removeAttr('max');
}
if (parseInt(input.val()) < 1) {
input.val(1);
}
}
$('#{{ $model }}-quantity').change(function() {
update{{ ucfirst($model) }}Max();
setPrice('{{ $model }}');
});
$('#{{ $model }}-offer_id').change(function() {
update{{ ucfirst($model) }}Max();
setPrice('{{ $model }}');
});
</script>