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:
@@ -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>
|
||||
|
||||
@@ -53,7 +53,12 @@
|
||||
|
||||
$('.basket-quantity').change(function() {
|
||||
var offer_id = $(this).data('id');
|
||||
var quantity = $(this).val();
|
||||
var quantity = parseInt($(this).val()) || 1;
|
||||
var min = parseInt($(this).attr('min')) || 1;
|
||||
var max = parseInt($(this).attr('max'));
|
||||
if (quantity < min) quantity = min;
|
||||
if (max && quantity > max) quantity = max;
|
||||
$(this).val(quantity);
|
||||
var $row = $(this).closest('.row');
|
||||
updateBasket(offer_id, quantity, function() {
|
||||
calculatePrice($row);
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
'value' => $item['quantity'],
|
||||
'class' => 'basket-quantity',
|
||||
'data_id' => $item['id'],
|
||||
'min' => 1,
|
||||
'max' => $item['stock'] ?? false,
|
||||
])
|
||||
</div>
|
||||
<div class="col-4 text-right" style="font-size: 2em;" id="basket_total-{{ $item['id'] }}">
|
||||
|
||||
Reference in New Issue
Block a user