';
}
el.innerHTML = html;
}
// legacy alias used elsewhere in the file
function filterCustomers() { custRenderList(); }
function rendercustomerList() { custRenderList(); }
// ── view customer detail ──────────────────────────────────────────────
function custViewDetail(key) {
var parts = key.split('|');
var name = parts[0] || '';
var phone = parts.slice(1).join('|'); // phone may be empty
CUST_CURRENT_KEY = key;
// legacy alias
currentcustomerId = key;
var titleEl = document.getElementById('cust-detail-name');
var bodyEl = document.getElementById('cust-detail-body');
if (titleEl) titleEl.textContent = name;
if (bodyEl) bodyEl.innerHTML = '
Loading...
';
openModal('customer-detail');
http('GET', 'invoices?limit=1000', null, function(err, res) {
if (!res || !res.ok) {
if (bodyEl) bodyEl.innerHTML = '
Failed to load data.
';
return;
}
var allInv = (res.data && res.data.invoices) ? res.data.invoices : [];
var invs = [];
for (var i = 0; i < allInv.length; i++) {
var inv = allInv[i];
// BUG FIX: this used to match on `phone === '' || inv.cust_phone === phone`,
// which meant that for any customer with no phone number, EVERY invoice
// with the same name matched regardless of its own phone — merging the
// purchase history/due totals of unrelated customers who share a name
// (e.g. multiple walk-in "Rahim" customers with different numbers).
// Match on the exact same "name|phone" key used to build the customer
// list instead, so only invoices belonging to this specific customer show.
var invKey = inv.cust_name + '|' + (inv.cust_phone || '');
if (invKey === key) {
invs.push(inv);
}
}
var totalSpent = 0, totalDue = 0;
for (var j = 0; j < invs.length; j++) {
totalSpent += parseFloat(invs[j].total || 0);
if (invs[j].pay_status === 'due' || invs[j].pay_status === 'partial') {
var dAmt = (invs[j].due_amount != null)
? parseFloat(invs[j].due_amount)
: (parseFloat(invs[j].total || 0) - parseFloat(invs[j].paid_amount || 0));
totalDue += (dAmt > 0 ? dAmt : 0);
}
}
var html = '