mirror of
https://github.com/Sea-Haven-Industries/payments-dashboard.git
synced 2026-10-06 19:22:08 +00:00
Update dashboard: split scheduled by method, outstanding checks with 90-day buckets, remove cleared section
This commit is contained in:
parent
3b8c201444
commit
7d1686bf94
1 changed files with 71 additions and 25 deletions
|
|
@ -104,11 +104,13 @@ function buildHomeView(payments, metadata) {
|
||||||
today.setHours(0, 0, 0, 0);
|
today.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
// Categorize payments
|
// Categorize payments
|
||||||
const scheduled = []; // future payments not yet due
|
const scheduledChecks = [];
|
||||||
const outstanding = []; // past-due checks not yet cleared, or returned by BoA
|
const scheduledACH = [];
|
||||||
const cleared = []; // confirmed cleared by BoA or ACH past due date
|
const outstandingChecks = [];
|
||||||
|
|
||||||
const skipStatuses = ["voided", "cancelled"];
|
const skipStatuses = ["voided", "cancelled", "canceled", "marked as void", "cleared"];
|
||||||
|
const ninetyDaysAgo = new Date(today);
|
||||||
|
ninetyDaysAgo.setDate(ninetyDaysAgo.getDate() - 90);
|
||||||
|
|
||||||
for (const p of payments) {
|
for (const p of payments) {
|
||||||
if (p.method !== "ACH" && p.method !== "Check") continue;
|
if (p.method !== "ACH" && p.method !== "Check") continue;
|
||||||
|
|
@ -116,21 +118,16 @@ function buildHomeView(payments, metadata) {
|
||||||
const dt = parseMDYLocal(p.send_payment_on);
|
const dt = parseMDYLocal(p.send_payment_on);
|
||||||
if (!dt) continue;
|
if (!dt) continue;
|
||||||
|
|
||||||
// Skip voided/cancelled payments entirely
|
const status = (p.status || "").toLowerCase();
|
||||||
if (skipStatuses.includes((p.status || "").toLowerCase())) continue;
|
if (skipStatuses.includes(status)) continue;
|
||||||
|
|
||||||
if (p.clear_status === "Returned") {
|
if (dt >= today) {
|
||||||
outstanding.push(p);
|
// Future — scheduled
|
||||||
} else if (p.clear_status === "Cleared") {
|
if (p.method === "Check") scheduledChecks.push(p);
|
||||||
cleared.push(p);
|
else scheduledACH.push(p);
|
||||||
} else if (p.method === "ACH" && dt < today) {
|
} else if (p.method === "Check") {
|
||||||
// ACH assumed cleared once past due date
|
// Past-due check not cleared — outstanding
|
||||||
cleared.push(p);
|
outstandingChecks.push(p);
|
||||||
} else if (dt < today) {
|
|
||||||
// Check past due date but not yet confirmed by BoA
|
|
||||||
outstanding.push(p);
|
|
||||||
} else {
|
|
||||||
scheduled.push(p);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -140,11 +137,14 @@ function buildHomeView(payments, metadata) {
|
||||||
const db = parseMDYLocal(b.send_payment_on);
|
const db = parseMDYLocal(b.send_payment_on);
|
||||||
return (da || 0) - (db || 0);
|
return (da || 0) - (db || 0);
|
||||||
};
|
};
|
||||||
scheduled.sort(byDate);
|
scheduledChecks.sort(byDate);
|
||||||
outstanding.sort(byDate);
|
scheduledACH.sort(byDate);
|
||||||
cleared.sort(byDate);
|
|
||||||
|
|
||||||
const buildSectionBlocks = (title, emoji, items) => {
|
// Split outstanding into <=90 days and >90 days
|
||||||
|
const outstanding90 = outstandingChecks.filter((p) => parseMDYLocal(p.send_payment_on) >= ninetyDaysAgo);
|
||||||
|
const outstandingOver90 = outstandingChecks.filter((p) => parseMDYLocal(p.send_payment_on) < ninetyDaysAgo);
|
||||||
|
|
||||||
|
const buildScheduledBlocks = (title, emoji, items) => {
|
||||||
const total = items.reduce((sum, p) => sum + p.amount_usd, 0);
|
const total = items.reduce((sum, p) => sum + p.amount_usd, 0);
|
||||||
|
|
||||||
const blocks = [
|
const blocks = [
|
||||||
|
|
@ -197,6 +197,52 @@ function buildHomeView(payments, metadata) {
|
||||||
return blocks;
|
return blocks;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const buildOutstandingBlocks = () => {
|
||||||
|
const totalAll = outstandingChecks.reduce((sum, p) => sum + p.amount_usd, 0);
|
||||||
|
|
||||||
|
const blocks = [
|
||||||
|
{
|
||||||
|
type: "section",
|
||||||
|
text: {
|
||||||
|
type: "mrkdwn",
|
||||||
|
text: `*:warning: Outstanding Checks*\n${outstandingChecks.length} checks • ${formatCurrency(totalAll)}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ type: "divider" },
|
||||||
|
];
|
||||||
|
|
||||||
|
if (!outstandingChecks.length) {
|
||||||
|
blocks.push({
|
||||||
|
type: "section",
|
||||||
|
text: { type: "mrkdwn", text: "_None_" },
|
||||||
|
});
|
||||||
|
blocks.push({ type: "divider" });
|
||||||
|
return blocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
const total90 = outstanding90.reduce((sum, p) => sum + p.amount_usd, 0);
|
||||||
|
const totalOver90 = outstandingOver90.reduce((sum, p) => sum + p.amount_usd, 0);
|
||||||
|
|
||||||
|
blocks.push({
|
||||||
|
type: "section",
|
||||||
|
fields: [
|
||||||
|
{ type: "mrkdwn", text: `*90 days or less*` },
|
||||||
|
{ type: "mrkdwn", text: `${outstanding90.length} checks • ${formatCurrency(total90)}` },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
blocks.push({
|
||||||
|
type: "section",
|
||||||
|
fields: [
|
||||||
|
{ type: "mrkdwn", text: `*Over 90 days*` },
|
||||||
|
{ type: "mrkdwn", text: `${outstandingOver90.length} checks • ${formatCurrency(totalOver90)}` },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
blocks.push({ type: "divider" });
|
||||||
|
return blocks;
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: "home",
|
type: "home",
|
||||||
blocks: [
|
blocks: [
|
||||||
|
|
@ -212,9 +258,9 @@ function buildHomeView(payments, metadata) {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{ type: "divider" },
|
{ type: "divider" },
|
||||||
...buildSectionBlocks("Scheduled", ":calendar:", scheduled),
|
...buildScheduledBlocks("Scheduled Checks", ":calendar:", scheduledChecks),
|
||||||
...buildSectionBlocks("Outstanding", ":warning:", outstanding),
|
...buildScheduledBlocks("Scheduled ACH", ":calendar:", scheduledACH),
|
||||||
...buildSectionBlocks("Cleared", ":white_check_mark:", cleared),
|
...buildOutstandingBlocks(),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue