feat(sync): add delivery cost, discount tracking and import settings
Parse delivery.total and discounts[] from GoMag JSON into new delivery_cost/discount_total fields. Add app_settings table for configuring transport/discount CODMAT codes. When configured, transport and discount are appended as extra articles in the Oracle import JSON. Reorder Total column in dashboard/logs tables and show transport/discount breakdown in order detail modals. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -313,10 +313,10 @@ async function loadDashOrders() {
|
||||
<td>${dateStr}</td>
|
||||
${renderClientCell(o)}
|
||||
<td>${o.items_count || 0}</td>
|
||||
<td class="text-end">${orderTotal}</td>
|
||||
<td class="text-nowrap">${statusDot(o.status)} ${statusLabelText(o.status)}</td>
|
||||
<td>${o.id_comanda || '-'}</td>
|
||||
<td>${invoiceBadge}</td>
|
||||
<td>${orderTotal}</td>
|
||||
</tr>`;
|
||||
}).join('');
|
||||
}
|
||||
@@ -479,6 +479,10 @@ async function openDashOrderDetail(orderNumber) {
|
||||
if (detailItemsTotal) detailItemsTotal.textContent = '-';
|
||||
const detailOrderTotal = document.getElementById('detailOrderTotal');
|
||||
if (detailOrderTotal) detailOrderTotal.textContent = '-';
|
||||
const deliveryWrap = document.getElementById('detailDeliveryWrap');
|
||||
if (deliveryWrap) deliveryWrap.style.display = 'none';
|
||||
const discountWrap = document.getElementById('detailDiscountWrap');
|
||||
if (discountWrap) discountWrap.style.display = 'none';
|
||||
const mobileContainer = document.getElementById('detailItemsMobile');
|
||||
if (mobileContainer) mobileContainer.innerHTML = '';
|
||||
|
||||
@@ -510,6 +514,22 @@ async function openDashOrderDetail(orderNumber) {
|
||||
document.getElementById('detailError').style.display = '';
|
||||
}
|
||||
|
||||
// Show delivery cost
|
||||
const dlvWrap = document.getElementById('detailDeliveryWrap');
|
||||
const dlvEl = document.getElementById('detailDeliveryCost');
|
||||
if (order.delivery_cost && Number(order.delivery_cost) > 0) {
|
||||
if (dlvEl) dlvEl.textContent = Number(order.delivery_cost).toFixed(2) + ' lei';
|
||||
if (dlvWrap) dlvWrap.style.display = '';
|
||||
}
|
||||
|
||||
// Show discount
|
||||
const dscWrap = document.getElementById('detailDiscountWrap');
|
||||
const dscEl = document.getElementById('detailDiscount');
|
||||
if (order.discount_total && Number(order.discount_total) > 0) {
|
||||
if (dscEl) dscEl.textContent = '-' + Number(order.discount_total).toFixed(2) + ' lei';
|
||||
if (dscWrap) dscWrap.style.display = '';
|
||||
}
|
||||
|
||||
const items = data.items || [];
|
||||
if (items.length === 0) {
|
||||
document.getElementById('detailItemsBody').innerHTML = '<tr><td colspan="8" class="text-center text-muted">Niciun articol</td></tr>';
|
||||
@@ -709,3 +729,81 @@ async function saveQuickMapping() {
|
||||
alert('Eroare: ' + err.message);
|
||||
}
|
||||
}
|
||||
|
||||
// ── App Settings ─────────────────────────────────
|
||||
|
||||
let settAcTimeout = null;
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
loadAppSettings();
|
||||
wireSettingsAutocomplete('settTransportCodmat', 'settTransportAc');
|
||||
wireSettingsAutocomplete('settDiscountCodmat', 'settDiscountAc');
|
||||
});
|
||||
|
||||
async function loadAppSettings() {
|
||||
try {
|
||||
const res = await fetch('/api/settings');
|
||||
const data = await res.json();
|
||||
const el = (id) => document.getElementById(id);
|
||||
if (el('settTransportCodmat')) el('settTransportCodmat').value = data.transport_codmat || '';
|
||||
if (el('settTransportVat')) el('settTransportVat').value = data.transport_vat || '21';
|
||||
if (el('settDiscountCodmat')) el('settDiscountCodmat').value = data.discount_codmat || '';
|
||||
} catch (err) {
|
||||
console.error('loadAppSettings error:', err);
|
||||
}
|
||||
}
|
||||
|
||||
async function saveAppSettings() {
|
||||
const transport_codmat = document.getElementById('settTransportCodmat')?.value?.trim() || '';
|
||||
const transport_vat = document.getElementById('settTransportVat')?.value || '21';
|
||||
const discount_codmat = document.getElementById('settDiscountCodmat')?.value?.trim() || '';
|
||||
try {
|
||||
const res = await fetch('/api/settings', {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ transport_codmat, transport_vat, discount_codmat })
|
||||
});
|
||||
const data = await res.json();
|
||||
if (data.success) {
|
||||
alert('Setari salvate!');
|
||||
} else {
|
||||
alert('Eroare: ' + JSON.stringify(data));
|
||||
}
|
||||
} catch (err) {
|
||||
alert('Eroare salvare setari: ' + err.message);
|
||||
}
|
||||
}
|
||||
|
||||
function wireSettingsAutocomplete(inputId, dropdownId) {
|
||||
const input = document.getElementById(inputId);
|
||||
const dropdown = document.getElementById(dropdownId);
|
||||
if (!input || !dropdown) return;
|
||||
|
||||
input.addEventListener('input', () => {
|
||||
clearTimeout(settAcTimeout);
|
||||
settAcTimeout = setTimeout(async () => {
|
||||
const q = input.value.trim();
|
||||
if (q.length < 2) { dropdown.classList.add('d-none'); return; }
|
||||
try {
|
||||
const res = await fetch(`/api/articles/search?q=${encodeURIComponent(q)}`);
|
||||
const data = await res.json();
|
||||
if (!data.results || data.results.length === 0) { dropdown.classList.add('d-none'); return; }
|
||||
dropdown.innerHTML = data.results.map(r =>
|
||||
`<div class="autocomplete-item" onmousedown="settSelectArticle('${inputId}', '${dropdownId}', '${esc(r.codmat)}')">
|
||||
<span class="codmat">${esc(r.codmat)}</span> — <span class="denumire">${esc(r.denumire)}</span>
|
||||
</div>`
|
||||
).join('');
|
||||
dropdown.classList.remove('d-none');
|
||||
} catch { dropdown.classList.add('d-none'); }
|
||||
}, 250);
|
||||
});
|
||||
|
||||
input.addEventListener('blur', () => {
|
||||
setTimeout(() => dropdown.classList.add('d-none'), 200);
|
||||
});
|
||||
}
|
||||
|
||||
function settSelectArticle(inputId, dropdownId, codmat) {
|
||||
document.getElementById(inputId).value = codmat;
|
||||
document.getElementById(dropdownId).classList.add('d-none');
|
||||
}
|
||||
|
||||
@@ -162,8 +162,8 @@ async function loadRunOrders(runId, statusFilter, page) {
|
||||
<td><code>${esc(o.order_number)}</code></td>
|
||||
<td>${esc(o.customer_name)}</td>
|
||||
<td>${o.items_count || 0}</td>
|
||||
<td class="text-end">${orderTotal}</td>
|
||||
<td class="text-nowrap">${statusDot(o.status)} ${logStatusText(o.status)}</td>
|
||||
<td>${orderTotal}</td>
|
||||
</tr>`;
|
||||
}).join('');
|
||||
}
|
||||
@@ -324,6 +324,10 @@ async function openOrderDetail(orderNumber) {
|
||||
if (detailItemsTotal) detailItemsTotal.textContent = '-';
|
||||
const detailOrderTotal = document.getElementById('detailOrderTotal');
|
||||
if (detailOrderTotal) detailOrderTotal.textContent = '-';
|
||||
const deliveryWrap = document.getElementById('detailDeliveryWrap');
|
||||
if (deliveryWrap) deliveryWrap.style.display = 'none';
|
||||
const discountWrap = document.getElementById('detailDiscountWrap');
|
||||
if (discountWrap) discountWrap.style.display = 'none';
|
||||
const mobileContainer = document.getElementById('detailItemsMobile');
|
||||
if (mobileContainer) mobileContainer.innerHTML = '';
|
||||
|
||||
@@ -355,6 +359,22 @@ async function openOrderDetail(orderNumber) {
|
||||
document.getElementById('detailError').style.display = '';
|
||||
}
|
||||
|
||||
// Show delivery cost
|
||||
const dlvWrap = document.getElementById('detailDeliveryWrap');
|
||||
const dlvEl = document.getElementById('detailDeliveryCost');
|
||||
if (order.delivery_cost && Number(order.delivery_cost) > 0) {
|
||||
if (dlvEl) dlvEl.textContent = Number(order.delivery_cost).toFixed(2) + ' lei';
|
||||
if (dlvWrap) dlvWrap.style.display = '';
|
||||
}
|
||||
|
||||
// Show discount
|
||||
const dscWrap = document.getElementById('detailDiscountWrap');
|
||||
const dscEl = document.getElementById('detailDiscount');
|
||||
if (order.discount_total && Number(order.discount_total) > 0) {
|
||||
if (dscEl) dscEl.textContent = '-' + Number(order.discount_total).toFixed(2) + ' lei';
|
||||
if (dscWrap) dscWrap.style.display = '';
|
||||
}
|
||||
|
||||
const items = data.items || [];
|
||||
if (items.length === 0) {
|
||||
document.getElementById('detailItemsBody').innerHTML = '<tr><td colspan="8" class="text-center text-muted">Niciun articol</td></tr>';
|
||||
|
||||
Reference in New Issue
Block a user