Files
shopPRO/admin/templates/shop-order/order-edit-custom-script.php
Jacek Pyziak 21efe28464 ver. 0.295: Admin order product editing — add/remove/modify products, AJAX search, stock adjustment
- Order product CRUD in admin panel (add, delete, edit quantity/prices)
- AJAX product search endpoint for order edit form
- Automatic stock adjustment when editing order products
- Transport cost recalculation based on free delivery threshold
- Fix: promo price = 0 when equal to base price (no real promotion)
- Clean up stale temp/ build artifacts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 19:30:38 +01:00

245 lines
9.9 KiB
PHP

<script type="text/javascript">
$(function() {
// =========================================================================
// InPost paczkomat
// =========================================================================
function toggleInpostField() {
if ($('#transport_id').val() != '2') {
$('#inpost_paczkomat').closest('.row').hide();
} else {
$('#inpost_paczkomat').closest('.row').show();
}
}
toggleInpostField();
$('body').on('change', '#transport_id', function() {
toggleInpostField();
recalculateTotals();
});
$('body').on('click', '.btn-paczkomat', function() {
window.easyPackAsyncInit = function () {
easyPack.init({
mapType: 'osm',
searchType: 'osm',
});
easyPack.mapWidget('inpost-map', function(point) {
$('#inpost_paczkomat').val(point.name + ' | ' + point.address.line1 + ', ' + point.address.line2);
$('.inpost-map-container').hide();
});
};
$('.inpost-map-container').show();
});
// =========================================================================
// Order save
// =========================================================================
$('body').on('click', '#order-save', function(e) {
e.preventDefault();
$('#fg-order-details').attr('method', 'POST').attr('action', '/admin/shop_order/order_save/').submit();
});
// =========================================================================
// Product row index counter
// =========================================================================
var productIndex = $('#order-products-body .order-product-row').length;
// =========================================================================
// Remove product
// =========================================================================
$('body').on('click', '.btn-remove-product', function() {
var $row = $(this).closest('.order-product-row');
var orderProductId = $row.find('input[name$="[order_product_id]"]').val();
if (orderProductId && orderProductId !== '0') {
// Istniejący produkt — ukryj i oznacz do usunięcia
$row.hide();
$row.append('<input type="hidden" name="products[' + $row.data('index') + '][delete]" value="1">');
} else {
// Nowy produkt — po prostu usuń z DOM
$row.remove();
}
recalculateTotals();
});
// =========================================================================
// Quantity and price change — recalculate
// =========================================================================
$('body').on('change input', '.product-qty, .product-price, .product-price-promo', function() {
recalculateTotals();
});
// =========================================================================
// Product search (AJAX)
// =========================================================================
var searchTimer = null;
var $searchInput = $('#product-search-input');
var $searchResults = $('#product-search-results');
$searchInput.on('keyup', function() {
var query = $(this).val().trim();
clearTimeout(searchTimer);
if (query.length < 2) {
$searchResults.hide().empty();
return;
}
searchTimer = setTimeout(function() {
$.ajax({
url: '/admin/shop_order/search_products_ajax/',
type: 'GET',
data: { query: query },
dataType: 'json',
success: function(data) {
$searchResults.empty();
if (!data || !data.products || data.products.length === 0) {
$searchResults.append('<div style="padding:10px;color:#999">Brak wyników</div>');
$searchResults.show();
return;
}
for (var i = 0; i < data.products.length; i++) {
var p = data.products[i];
var priceDisplay = p.price_brutto_promo > 0
? '<span style="text-decoration:line-through;color:#999">' + parseFloat(p.price_brutto).toFixed(2) + ' zł</span> <strong>' + parseFloat(p.price_brutto_promo).toFixed(2) + ' zł</strong>'
: '<strong>' + parseFloat(p.price_brutto).toFixed(2) + ' zł</strong>';
var stockWarning = p.quantity <= 0
? ' <span style="color:#d9534f;font-size:11px">(brak na stanie)</span>'
: ' <span style="color:#5cb85c;font-size:11px">(stan: ' + p.quantity + ')</span>';
var imgHtml = p.image
? '<img src="' + p.image + '" style="width:35px;height:35px;object-fit:cover;margin-right:8px;border-radius:3px">'
: '<span style="display:inline-block;width:35px;height:35px;margin-right:8px;background:#eee;border-radius:3px"></span>';
var $item = $('<div class="product-search-item" style="padding:8px 10px;cursor:pointer;display:flex;align-items:center;border-bottom:1px solid #f0f0f0"></div>');
$item.html(imgHtml + '<div><div>' + $('<span>').text(p.name).html() + (p.sku ? ' <span style="color:#999;font-size:11px">(' + $('<span>').text(p.sku).html() + ')</span>' : '') + stockWarning + '</div><div>' + priceDisplay + '</div></div>');
$item.data('product', p);
$searchResults.append($item);
}
$searchResults.show();
}
});
}, 300);
});
// Kliknięcie w wynik wyszukiwania — dodaj produkt
$('body').on('click', '.product-search-item', function() {
var p = $(this).data('product');
if (p.quantity <= 0) {
if (!confirm('Produkt "' + p.name + '" nie jest dostępny na stanie. Czy na pewno chcesz go dodać?')) {
return;
}
}
addProductRow(p);
$searchInput.val('');
$searchResults.hide().empty();
});
// Ukryj wyniki przy kliknięciu poza
$(document).on('click', function(e) {
if (!$(e.target).closest('#add-product-section').length) {
$searchResults.hide();
}
});
// =========================================================================
// Add product row
// =========================================================================
function addProductRow(product) {
var idx = productIndex++;
var imgHtml = product.image
? '<img src="' + product.image + '" style="max-width:50px;max-height:50px">'
: '';
var effectivePrice = product.price_brutto_promo > 0 ? product.price_brutto_promo : product.price_brutto;
var $row = $('<tr class="order-product-row" data-index="' + idx + '"></tr>');
$row.html(
'<input type="hidden" name="products[' + idx + '][order_product_id]" value="0">' +
'<input type="hidden" name="products[' + idx + '][product_id]" value="' + product.product_id + '">' +
'<input type="hidden" name="products[' + idx + '][parent_product_id]" value="' + (product.parent_product_id || product.product_id) + '">' +
'<input type="hidden" name="products[' + idx + '][name]" value="' + $('<span>').text(product.name).html() + '">' +
'<input type="hidden" name="products[' + idx + '][vat]" value="' + product.vat + '">' +
'<td class="product-image">' + imgHtml + '</td>' +
'<td>' + $('<span>').text(product.name).html() +
(product.sku ? ' <span class="small text-muted">(' + $('<span>').text(product.sku).html() + ')</span>' : '') +
'</td>' +
'<td class="tab-center"><input type="number" name="products[' + idx + '][quantity]" value="1" min="1" class="form-control form-control-sm text-center product-qty" style="width:70px"></td>' +
'<td class="tab-right"><input type="number" name="products[' + idx + '][price_brutto]" value="' + parseFloat(product.price_brutto).toFixed(2) + '" step="0.01" min="0" class="form-control form-control-sm text-right product-price" style="width:110px"></td>' +
'<td class="tab-right"><input type="number" name="products[' + idx + '][price_brutto_promo]" value="' + parseFloat(product.price_brutto_promo).toFixed(2) + '" step="0.01" min="0" class="form-control form-control-sm text-right product-price-promo" style="width:110px"></td>' +
'<td class="tab-right product-row-total">' + parseFloat(effectivePrice).toFixed(2).replace('.', ',') + ' zł</td>' +
'<td class="text-center"><button type="button" class="btn btn-xs btn-danger btn-remove-product" title="Usuń produkt"><i class="fa fa-times"></i></button></td>'
);
$('#order-products-body').append($row);
recalculateTotals();
}
// =========================================================================
// Recalculate totals
// =========================================================================
function recalculateTotals() {
var productsTotal = 0;
$('#order-products-body .order-product-row:visible').each(function() {
var qty = parseFloat($(this).find('.product-qty').val()) || 0;
var price = parseFloat($(this).find('.product-price').val()) || 0;
var pricePromo = parseFloat($(this).find('.product-price-promo').val()) || 0;
var effectivePrice = pricePromo > 0 ? pricePromo : price;
var rowTotal = effectivePrice * qty;
$(this).find('.product-row-total').text(rowTotal.toFixed(2).replace('.', ',') + ' zł');
productsTotal += rowTotal;
});
// Transport cost (z uwzględnieniem progu darmowej dostawy)
var transportId = parseInt($('#transport_id').val()) || 0;
var transportCost = 0;
var transports = orderEditConfig.transports || [];
for (var i = 0; i < transports.length; i++) {
if (transports[i].id === transportId) {
var t = transports[i];
if (t.delivery_free === 1 && orderEditConfig.freeDelivery > 0 && productsTotal >= orderEditConfig.freeDelivery) {
transportCost = 0;
} else {
transportCost = t.cost;
}
break;
}
}
var orderTotal = productsTotal + transportCost;
$('#products-total-display').text(productsTotal.toFixed(2).replace('.', ','));
$('#transport-cost-display').text(transportCost.toFixed(2).replace('.', ','));
$('#order-summary-display').text(orderTotal.toFixed(2).replace('.', ',') + ' zł');
}
// Inicjalizacja sum przy załadowaniu strony
recalculateTotals();
});
</script>