feat(orders): add resync and delete order buttons
Resync soft-deletes from Oracle then re-imports from GoMag with fresh article data. Delete soft-deletes and marks DELETED_IN_ROA. Both have invoice safety gates (refuse if invoiced or Oracle unavailable). UI: split modal footer (Delete left, Resync+Close right), inline confirm pattern (no native confirm()), dashboard row hover action icons, disabled+tooltip for invoiced orders. 8 unit tests for safety gates and happy paths. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -375,7 +375,7 @@ async function loadDashOrders() {
|
||||
<td>${o.items_count || 0}</td>
|
||||
<td class="text-end text-muted">${fmtCost(o.delivery_cost)}</td>
|
||||
<td class="text-end text-muted">${fmtCost(o.discount_total)}</td>
|
||||
<td class="text-end fw-bold">${orderTotal}</td>
|
||||
<td class="text-end fw-bold" style="position:relative">${orderTotal}${(o.status === 'IMPORTED' || o.status === 'ALREADY_IMPORTED') && !(o.invoice && o.invoice.facturat) ? '<span class="row-actions"><button class="btn btn-xs btn-outline-warning" aria-label="Resync comanda" title="Resync" onclick="event.stopPropagation(); dashResyncOrder(\'' + esc(o.order_number) + '\', this)"><i class="bi bi-arrow-repeat"></i></button><button class="btn btn-xs btn-outline-danger" aria-label="Sterge din ROA" title="Sterge din ROA" onclick="event.stopPropagation(); dashDeleteOrder(\'' + esc(o.order_number) + '\', this)"><i class="bi bi-trash"></i></button></span>' : ''}</td>
|
||||
</tr>`;
|
||||
}).join('');
|
||||
}
|
||||
@@ -595,3 +595,69 @@ function openDashQuickMap(sku, productName, orderNumber, itemIdx) {
|
||||
});
|
||||
}
|
||||
|
||||
// ── Dashboard row action handlers ────────────────
|
||||
|
||||
function dashResyncOrder(orderNumber, btn) {
|
||||
inlineConfirmAction(btn, '?', async (b) => {
|
||||
try {
|
||||
const res = await fetch(`/api/orders/${encodeURIComponent(orderNumber)}/resync`, { method: 'POST' });
|
||||
const data = await res.json();
|
||||
if (data.success) {
|
||||
b.innerHTML = '<i class="bi bi-check-circle"></i>';
|
||||
b.className = 'btn btn-xs btn-success';
|
||||
setTimeout(() => loadDashOrders(), 1500);
|
||||
} else {
|
||||
b.innerHTML = '<i class="bi bi-exclamation-triangle"></i>';
|
||||
b.className = 'btn btn-xs btn-danger';
|
||||
b.title = data.message || 'Eroare';
|
||||
setTimeout(() => {
|
||||
b.innerHTML = '<i class="bi bi-arrow-repeat"></i>';
|
||||
b.className = 'btn btn-xs btn-outline-warning';
|
||||
b.disabled = false;
|
||||
b.title = 'Resync';
|
||||
}, 3000);
|
||||
}
|
||||
} catch (err) {
|
||||
b.innerHTML = '<i class="bi bi-exclamation-triangle"></i>';
|
||||
b.disabled = false;
|
||||
}
|
||||
}, {
|
||||
defaultHtml: '<i class="bi bi-arrow-repeat"></i>',
|
||||
loadingText: '',
|
||||
confirmClass: 'btn-warning',
|
||||
defaultBtnClass: 'btn-outline-warning'
|
||||
});
|
||||
}
|
||||
|
||||
function dashDeleteOrder(orderNumber, btn) {
|
||||
inlineConfirmAction(btn, '?', async (b) => {
|
||||
try {
|
||||
const res = await fetch(`/api/orders/${encodeURIComponent(orderNumber)}/delete`, { method: 'POST' });
|
||||
const data = await res.json();
|
||||
if (data.success) {
|
||||
b.innerHTML = '<i class="bi bi-check-circle"></i>';
|
||||
b.className = 'btn btn-xs btn-success';
|
||||
setTimeout(() => loadDashOrders(), 1500);
|
||||
} else {
|
||||
b.innerHTML = '<i class="bi bi-exclamation-triangle"></i>';
|
||||
b.className = 'btn btn-xs btn-danger';
|
||||
b.title = data.message || 'Eroare';
|
||||
setTimeout(() => {
|
||||
b.innerHTML = '<i class="bi bi-trash"></i>';
|
||||
b.className = 'btn btn-xs btn-outline-danger';
|
||||
b.disabled = false;
|
||||
b.title = 'Sterge din ROA';
|
||||
}, 3000);
|
||||
}
|
||||
} catch (err) {
|
||||
b.innerHTML = '<i class="bi bi-exclamation-triangle"></i>';
|
||||
b.disabled = false;
|
||||
}
|
||||
}, {
|
||||
defaultHtml: '<i class="bi bi-trash"></i>',
|
||||
loadingText: '',
|
||||
confirmClass: 'btn-danger',
|
||||
defaultBtnClass: 'btn-outline-danger'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user