diff --git a/apps/Backend/src/storage/payments-reports-storage.ts b/apps/Backend/src/storage/payments-reports-storage.ts index 8f906e70..561b7b41 100755 --- a/apps/Backend/src/storage/payments-reports-storage.ts +++ b/apps/Backend/src/storage/payments-reports-storage.ts @@ -175,18 +175,19 @@ export const paymentsReportsStorage: IPaymentsReportsStorage = { )) as { cnt: number }[]; const totalPatients = patientsCntRows?.[0]?.cnt ?? 0; - // totalOutstanding: sum of (charges - paid - adjusted) across patients, using payments in range + // totalOutstanding: totalBilled - mhPaidAmount - copayment - adjustment let outstandingSql = ""; if (hasFrom && hasTo) { outstandingSql = ` SELECT COALESCE(SUM( - COALESCE(pm.total_charges,0) - COALESCE(pm.total_paid,0) - COALESCE(pm.total_adjusted,0) + GREATEST(COALESCE(pm.total_charges,0) - COALESCE(pm.mh_paid,0) - COALESCE(pm.copayment,0) - COALESCE(pm.adjustment,0), 0) ),0)::numeric(14,2) AS outstanding FROM ( SELECT pay."patientId" AS patient_id, SUM(pay."totalBilled")::numeric(14,2) AS total_charges, - SUM(pay."totalPaid")::numeric(14,2) AS total_paid, - SUM(pay."totalAdjusted")::numeric(14,2) AS total_adjusted + SUM(COALESCE(pay."mhPaidAmount",0))::numeric(14,2) AS mh_paid, + SUM(pay."copayment")::numeric(14,2) AS copayment, + SUM(pay."adjustment")::numeric(14,2) AS adjustment FROM "Payment" pay WHERE pay."createdAt" >= ${fromStart} AND pay."createdAt" <= ${toNextStart} GROUP BY pay."patientId" @@ -195,13 +196,14 @@ export const paymentsReportsStorage: IPaymentsReportsStorage = { } else if (hasFrom) { outstandingSql = ` SELECT COALESCE(SUM( - COALESCE(pm.total_charges,0) - COALESCE(pm.total_paid,0) - COALESCE(pm.total_adjusted,0) + GREATEST(COALESCE(pm.total_charges,0) - COALESCE(pm.mh_paid,0) - COALESCE(pm.copayment,0) - COALESCE(pm.adjustment,0), 0) ),0)::numeric(14,2) AS outstanding FROM ( SELECT pay."patientId" AS patient_id, SUM(pay."totalBilled")::numeric(14,2) AS total_charges, - SUM(pay."totalPaid")::numeric(14,2) AS total_paid, - SUM(pay."totalAdjusted")::numeric(14,2) AS total_adjusted + SUM(COALESCE(pay."mhPaidAmount",0))::numeric(14,2) AS mh_paid, + SUM(pay."copayment")::numeric(14,2) AS copayment, + SUM(pay."adjustment")::numeric(14,2) AS adjustment FROM "Payment" pay WHERE pay."createdAt" >= ${fromStart} GROUP BY pay."patientId" @@ -210,13 +212,14 @@ export const paymentsReportsStorage: IPaymentsReportsStorage = { } else if (hasTo) { outstandingSql = ` SELECT COALESCE(SUM( - COALESCE(pm.total_charges,0) - COALESCE(pm.total_paid,0) - COALESCE(pm.total_adjusted,0) + GREATEST(COALESCE(pm.total_charges,0) - COALESCE(pm.mh_paid,0) - COALESCE(pm.copayment,0) - COALESCE(pm.adjustment,0), 0) ),0)::numeric(14,2) AS outstanding FROM ( SELECT pay."patientId" AS patient_id, SUM(pay."totalBilled")::numeric(14,2) AS total_charges, - SUM(pay."totalPaid")::numeric(14,2) AS total_paid, - SUM(pay."totalAdjusted")::numeric(14,2) AS total_adjusted + SUM(COALESCE(pay."mhPaidAmount",0))::numeric(14,2) AS mh_paid, + SUM(pay."copayment")::numeric(14,2) AS copayment, + SUM(pay."adjustment")::numeric(14,2) AS adjustment FROM "Payment" pay WHERE pay."createdAt" <= ${toNextStart} GROUP BY pay."patientId" @@ -225,13 +228,14 @@ export const paymentsReportsStorage: IPaymentsReportsStorage = { } else { outstandingSql = ` SELECT COALESCE(SUM( - COALESCE(pm.total_charges,0) - COALESCE(pm.total_paid,0) - COALESCE(pm.total_adjusted,0) + GREATEST(COALESCE(pm.total_charges,0) - COALESCE(pm.mh_paid,0) - COALESCE(pm.copayment,0) - COALESCE(pm.adjustment,0), 0) ),0)::numeric(14,2) AS outstanding FROM ( SELECT pay."patientId" AS patient_id, SUM(pay."totalBilled")::numeric(14,2) AS total_charges, - SUM(pay."totalPaid")::numeric(14,2) AS total_paid, - SUM(pay."totalAdjusted")::numeric(14,2) AS total_adjusted + SUM(COALESCE(pay."mhPaidAmount",0))::numeric(14,2) AS mh_paid, + SUM(pay."copayment")::numeric(14,2) AS copayment, + SUM(pay."adjustment")::numeric(14,2) AS adjustment FROM "Payment" pay GROUP BY pay."patientId" ) pm @@ -242,74 +246,78 @@ export const paymentsReportsStorage: IPaymentsReportsStorage = { )) as { outstanding: string }[]; const totalOutstanding = Number(outstandingRows?.[0]?.outstanding ?? 0); - // totalCollected: sum(totalPaid) in the range + // totalCollected: mhPaidAmount + copayment (adjustment is write-off, not collected) let collSql = ""; if (hasFrom && hasTo) { - collSql = `SELECT COALESCE(SUM("totalPaid"),0)::numeric(14,2) AS collected FROM "Payment" WHERE "createdAt" >= ${fromStart} AND "createdAt" <= ${toNextStart}`; + collSql = `SELECT COALESCE(SUM(COALESCE("mhPaidAmount",0) + "copayment"),0)::numeric(14,2) AS collected FROM "Payment" WHERE "createdAt" >= ${fromStart} AND "createdAt" <= ${toNextStart}`; } else if (hasFrom) { - collSql = `SELECT COALESCE(SUM("totalPaid"),0)::numeric(14,2) AS collected FROM "Payment" WHERE "createdAt" >= ${fromStart}`; + collSql = `SELECT COALESCE(SUM(COALESCE("mhPaidAmount",0) + "copayment"),0)::numeric(14,2) AS collected FROM "Payment" WHERE "createdAt" >= ${fromStart}`; } else if (hasTo) { - collSql = `SELECT COALESCE(SUM("totalPaid"),0)::numeric(14,2) AS collected FROM "Payment" WHERE "createdAt" <= ${toNextStart}`; + collSql = `SELECT COALESCE(SUM(COALESCE("mhPaidAmount",0) + "copayment"),0)::numeric(14,2) AS collected FROM "Payment" WHERE "createdAt" <= ${toNextStart}`; } else { - collSql = `SELECT COALESCE(SUM("totalPaid"),0)::numeric(14,2) AS collected FROM "Payment"`; + collSql = `SELECT COALESCE(SUM(COALESCE("mhPaidAmount",0) + "copayment"),0)::numeric(14,2) AS collected FROM "Payment"`; } const collRows = (await prisma.$queryRawUnsafe(collSql)) as { collected: string; }[]; const totalCollected = Number(collRows?.[0]?.collected ?? 0); - // NEW: patientsWithBalance: number of patients whose (charges - paid - adjusted) > 0, within the date range + // patientsWithBalance: patients where (billed - mhPaid - copayment - adjustment) > 0 let patientsWithBalanceSql = ""; if (hasFrom && hasTo) { patientsWithBalanceSql = ` SELECT COUNT(*)::int AS cnt FROM ( SELECT pay."patientId" AS patient_id, SUM(pay."totalBilled")::numeric(14,2) AS total_charges, - SUM(pay."totalPaid")::numeric(14,2) AS total_paid, - SUM(pay."totalAdjusted")::numeric(14,2) AS total_adjusted + SUM(COALESCE(pay."mhPaidAmount",0))::numeric(14,2) AS mh_paid, + SUM(pay."copayment")::numeric(14,2) AS copayment, + SUM(pay."adjustment")::numeric(14,2) AS adjustment FROM "Payment" pay WHERE pay."createdAt" >= ${fromStart} AND pay."createdAt" <= ${toNextStart} GROUP BY pay."patientId" ) t - WHERE (COALESCE(t.total_charges,0) - COALESCE(t.total_paid,0) - COALESCE(t.total_adjusted,0)) > 0 + WHERE (COALESCE(t.total_charges,0) - COALESCE(t.mh_paid,0) - COALESCE(t.copayment,0) - COALESCE(t.adjustment,0)) > 0 `; } else if (hasFrom) { patientsWithBalanceSql = ` SELECT COUNT(*)::int AS cnt FROM ( SELECT pay."patientId" AS patient_id, SUM(pay."totalBilled")::numeric(14,2) AS total_charges, - SUM(pay."totalPaid")::numeric(14,2) AS total_paid, - SUM(pay."totalAdjusted")::numeric(14,2) AS total_adjusted + SUM(COALESCE(pay."mhPaidAmount",0))::numeric(14,2) AS mh_paid, + SUM(pay."copayment")::numeric(14,2) AS copayment, + SUM(pay."adjustment")::numeric(14,2) AS adjustment FROM "Payment" pay WHERE pay."createdAt" >= ${fromStart} GROUP BY pay."patientId" ) t - WHERE (COALESCE(t.total_charges,0) - COALESCE(t.total_paid,0) - COALESCE(t.total_adjusted,0)) > 0 + WHERE (COALESCE(t.total_charges,0) - COALESCE(t.mh_paid,0) - COALESCE(t.copayment,0) - COALESCE(t.adjustment,0)) > 0 `; } else if (hasTo) { patientsWithBalanceSql = ` SELECT COUNT(*)::int AS cnt FROM ( SELECT pay."patientId" AS patient_id, SUM(pay."totalBilled")::numeric(14,2) AS total_charges, - SUM(pay."totalPaid")::numeric(14,2) AS total_paid, - SUM(pay."totalAdjusted")::numeric(14,2) AS total_adjusted + SUM(COALESCE(pay."mhPaidAmount",0))::numeric(14,2) AS mh_paid, + SUM(pay."copayment")::numeric(14,2) AS copayment, + SUM(pay."adjustment")::numeric(14,2) AS adjustment FROM "Payment" pay WHERE pay."createdAt" <= ${toNextStart} GROUP BY pay."patientId" ) t - WHERE (COALESCE(t.total_charges,0) - COALESCE(t.total_paid,0) - COALESCE(t.total_adjusted,0)) > 0 + WHERE (COALESCE(t.total_charges,0) - COALESCE(t.mh_paid,0) - COALESCE(t.copayment,0) - COALESCE(t.adjustment,0)) > 0 `; } else { patientsWithBalanceSql = ` SELECT COUNT(*)::int AS cnt FROM ( SELECT pay."patientId" AS patient_id, SUM(pay."totalBilled")::numeric(14,2) AS total_charges, - SUM(pay."totalPaid")::numeric(14,2) AS total_paid, - SUM(pay."totalAdjusted")::numeric(14,2) AS total_adjusted + SUM(COALESCE(pay."mhPaidAmount",0))::numeric(14,2) AS mh_paid, + SUM(pay."copayment")::numeric(14,2) AS copayment, + SUM(pay."adjustment")::numeric(14,2) AS adjustment FROM "Payment" pay GROUP BY pay."patientId" ) t - WHERE (COALESCE(t.total_charges,0) - COALESCE(t.total_paid,0) - COALESCE(t.total_adjusted,0)) > 0 + WHERE (COALESCE(t.total_charges,0) - COALESCE(t.mh_paid,0) - COALESCE(t.copayment,0) - COALESCE(t.adjustment,0)) > 0 `; } const pwbRows = (await prisma.$queryRawUnsafe( @@ -824,9 +832,10 @@ export const paymentsReportsStorage: IPaymentsReportsStorage = { payments_agg AS ( SELECT pay."patientId" AS patient_id, - SUM(pay."totalBilled")::numeric(14,2) AS total_charges, - SUM(pay."totalPaid")::numeric(14,2) AS total_paid, - SUM(pay."totalAdjusted")::numeric(14,2) AS total_adjusted + SUM(pay."totalBilled")::numeric(14,2) AS total_charges, + SUM(COALESCE(pay."mhPaidAmount",0))::numeric(14,2) AS mh_paid, + SUM(pay."copayment")::numeric(14,2) AS copayment, + SUM(pay."adjustment")::numeric(14,2) AS adjustment FROM "Payment" pay JOIN "Claim" c ON pay."claimId" = c.id WHERE c."staffId" = ${Number(staffId)} @@ -835,9 +844,9 @@ export const paymentsReportsStorage: IPaymentsReportsStorage = { ) SELECT json_build_object( 'totalPatients', COALESCE(COUNT(DISTINCT pa.patient_id),0), - 'totalOutstanding', COALESCE(SUM(COALESCE(pa.total_charges,0) - COALESCE(pa.total_paid,0) - COALESCE(pa.total_adjusted,0)),0)::text, - 'totalCollected', COALESCE(SUM(COALESCE(pa.total_paid,0)),0)::text, - 'patientsWithBalance', COALESCE(SUM(CASE WHEN (COALESCE(pa.total_charges,0) - COALESCE(pa.total_paid,0) - COALESCE(pa.total_adjusted,0)) > 0 THEN 1 ELSE 0 END),0) + 'totalOutstanding', COALESCE(SUM(GREATEST(COALESCE(pa.total_charges,0) - COALESCE(pa.mh_paid,0) - COALESCE(pa.copayment,0) - COALESCE(pa.adjustment,0), 0)),0)::text, + 'totalCollected', COALESCE(SUM(COALESCE(pa.mh_paid,0) + COALESCE(pa.copayment,0)),0)::text, + 'patientsWithBalance', COALESCE(SUM(CASE WHEN (COALESCE(pa.total_charges,0) - COALESCE(pa.mh_paid,0) - COALESCE(pa.copayment,0) - COALESCE(pa.adjustment,0)) > 0 THEN 1 ELSE 0 END),0) ) AS summary_json FROM payments_agg pa; `; diff --git a/apps/Frontend/src/components/payments/payments-recent-table.tsx b/apps/Frontend/src/components/payments/payments-recent-table.tsx index e4d43ec8..05112cb7 100755 --- a/apps/Frontend/src/components/payments/payments-recent-table.tsx +++ b/apps/Frontend/src/components/payments/payments-recent-table.tsx @@ -634,7 +634,11 @@ export default function PaymentsRecentTable({ paymentsData?.payments.map((payment) => { const totalBilled = Number(payment.totalBilled || 0); const totalPaid = Number(payment.totalPaid || 0); - const totalDue = Number(payment.totalDue || 0); + const mhPaid = Number(payment.mhPaidAmount || 0); + const copayment = Number(payment.copayment || 0); + const adjustment = Number(payment.adjustment || 0); + const totalDue = Math.max(0, totalBilled - mhPaid - copayment - adjustment); + const totalCollected = mhPaid + copayment; const displayName = getName(payment); const submittedOn = @@ -682,22 +686,25 @@ export default function PaymentsRecentTable({ - {/* 💰 Billed / Paid / Due breakdown */} + {/* 💰 Billed / Collected / Due breakdown */}
- Total Billed: $ - {Number(totalBilled).toFixed(2)} + Total Billed: ${totalBilled.toFixed(2)} - Total Paid: ${totalPaid.toFixed(2)} + Collected: ${totalCollected.toFixed(2)} + {adjustment > 0 && ( + + Adjustment:{" "} + -${adjustment.toFixed(2)} + + )} - Total Due:{" "} + Balance:{" "} {totalDue > 0 ? ( - - ${totalDue.toFixed(2)} - + ${totalDue.toFixed(2)} ) : ( Settled )}