@mindbill/angular 0.4.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -3
- package/fesm2022/mindbill-angular.mjs +166 -4
- package/fesm2022/mindbill-angular.mjs.map +1 -1
- package/package.json +3 -3
- package/types/mindbill-angular.d.ts +102 -11
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @mindbill/angular
|
|
2
2
|
|
|
3
|
-
Native Angular billing UI with built-in session renewal
|
|
3
|
+
Native Angular billing UI with built-in session renewal, bill lifecycle API calls, dashboards, aging, bill lists, and reporting. The components are standalone and do not bundle React.
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
6
|
npm install @mindbill/angular @mindbill/node
|
|
@@ -10,12 +10,20 @@ Import the standalone component and pass the ID returned by your server's atomic
|
|
|
10
10
|
|
|
11
11
|
```ts
|
|
12
12
|
import { Component } from "@angular/core";
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
MindBillBillLifecycleComponent,
|
|
15
|
+
MindBillBillingDashboardComponent,
|
|
16
|
+
MindBillBillingReportComponent,
|
|
17
|
+
} from "@mindbill/angular";
|
|
14
18
|
|
|
15
19
|
@Component({
|
|
16
20
|
selector: "app-case-billing",
|
|
17
21
|
standalone: true,
|
|
18
|
-
imports: [
|
|
22
|
+
imports: [
|
|
23
|
+
MindBillBillLifecycleComponent,
|
|
24
|
+
MindBillBillingDashboardComponent,
|
|
25
|
+
MindBillBillingReportComponent,
|
|
26
|
+
],
|
|
19
27
|
template: `
|
|
20
28
|
<mindbill-bill-lifecycle
|
|
21
29
|
[billId]="billId"
|
|
@@ -50,3 +58,30 @@ app.post("/api/mindbill/session", requireUser, async (req, res) => {
|
|
|
50
58
|
```
|
|
51
59
|
|
|
52
60
|
Your permanent API key never reaches Angular. Available presets are `mindbill`, `qme-companion`, `orange-bright`, and `clinical-blue`; every visual token can also be overridden.
|
|
61
|
+
|
|
62
|
+
## Operations components
|
|
63
|
+
|
|
64
|
+
The operations surfaces consume a normalized list of bills, so they can be used together or independently:
|
|
65
|
+
|
|
66
|
+
```html
|
|
67
|
+
<mindbill-billing-dashboard
|
|
68
|
+
[bills]="bills"
|
|
69
|
+
[appearance]="appearance"
|
|
70
|
+
(billSelected)="openBill($event)"
|
|
71
|
+
/>
|
|
72
|
+
|
|
73
|
+
<mindbill-bill-aging-summary
|
|
74
|
+
[buckets]="summary.aging"
|
|
75
|
+
[appearance]="appearance"
|
|
76
|
+
/>
|
|
77
|
+
|
|
78
|
+
<mindbill-bill-list
|
|
79
|
+
[bills]="bills"
|
|
80
|
+
[appearance]="appearance"
|
|
81
|
+
(billSelected)="openBill($event)"
|
|
82
|
+
/>
|
|
83
|
+
|
|
84
|
+
<mindbill-billing-report [bills]="bills" [appearance]="appearance" />
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
`summarizeMindBillDashboard`, `buildMindBillReportRows`, and `buildMindBillReportCsv` are also exported for custom layouts and server-side reporting.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { signal, computed, EventEmitter, effect, Output, Input, Component } from '@angular/core';
|
|
2
|
+
import { signal, computed, EventEmitter, effect, Output, Input, Component, Directive } from '@angular/core';
|
|
3
3
|
import { createBillLifecycleClient } from '@mindbill/browser';
|
|
4
4
|
import * as i1 from '@angular/common';
|
|
5
5
|
import { CommonModule } from '@angular/common';
|
|
@@ -169,7 +169,7 @@ class MindBillBillLifecycleComponent {
|
|
|
169
169
|
</section>
|
|
170
170
|
|
|
171
171
|
<div class="columns">
|
|
172
|
-
<section class="card"><div class="card-title"><div><h3>Remittance</h3><p>Amounts reported by the payer and posted to this bill.</p></div></div><dl><div><dt>Payer reported</dt><dd>{{ data.remittance.payerReportedPaid == null ? '—' : (data.remittance.payerReportedPaid | currency) }}</dd></div><div><dt>
|
|
172
|
+
<section class="card"><div class="card-title"><div><h3>Remittance</h3><p>Amounts reported by the payer and posted to this bill.</p></div></div><dl><div><dt>Billed</dt><dd>{{ data.remittance.billedAmount | currency }}</dd></div><div><dt>Payer reported</dt><dd>{{ data.remittance.payerReportedPaid == null ? '—' : (data.remittance.payerReportedPaid | currency) }}</dd></div><div><dt>Principal posted</dt><dd>{{ data.remittance.postedPrincipal | currency }}</dd></div><div><dt>Penalty & interest</dt><dd>{{ data.remittance.postedAdditional | currency }}</dd></div><div><dt>Total received</dt><dd>{{ data.remittance.totalPostedCash | currency }}</dd></div><div><dt>Balance</dt><dd>{{ data.remittance.balanceDue | currency }}</dd></div></dl></section>
|
|
173
173
|
<section class="card"><div class="card-title"><div><h3>{{ data.delivery.payerName || 'Payer' }}</h3><p>Billing and follow-up contacts.</p></div></div><p class="muted">{{ payerContact(data) }}</p></section>
|
|
174
174
|
</div>
|
|
175
175
|
|
|
@@ -215,7 +215,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
|
|
|
215
215
|
</section>
|
|
216
216
|
|
|
217
217
|
<div class="columns">
|
|
218
|
-
<section class="card"><div class="card-title"><div><h3>Remittance</h3><p>Amounts reported by the payer and posted to this bill.</p></div></div><dl><div><dt>Payer reported</dt><dd>{{ data.remittance.payerReportedPaid == null ? '—' : (data.remittance.payerReportedPaid | currency) }}</dd></div><div><dt>
|
|
218
|
+
<section class="card"><div class="card-title"><div><h3>Remittance</h3><p>Amounts reported by the payer and posted to this bill.</p></div></div><dl><div><dt>Billed</dt><dd>{{ data.remittance.billedAmount | currency }}</dd></div><div><dt>Payer reported</dt><dd>{{ data.remittance.payerReportedPaid == null ? '—' : (data.remittance.payerReportedPaid | currency) }}</dd></div><div><dt>Principal posted</dt><dd>{{ data.remittance.postedPrincipal | currency }}</dd></div><div><dt>Penalty & interest</dt><dd>{{ data.remittance.postedAdditional | currency }}</dd></div><div><dt>Total received</dt><dd>{{ data.remittance.totalPostedCash | currency }}</dd></div><div><dt>Balance</dt><dd>{{ data.remittance.balanceDue | currency }}</dd></div></dl></section>
|
|
219
219
|
<section class="card"><div class="card-title"><div><h3>{{ data.delivery.payerName || 'Payer' }}</h3><p>Billing and follow-up contacts.</p></div></div><p class="muted">{{ payerContact(data) }}</p></section>
|
|
220
220
|
</div>
|
|
221
221
|
|
|
@@ -275,9 +275,171 @@ function ensureTrailingProcedureLine(lines) {
|
|
|
275
275
|
: entered;
|
|
276
276
|
}
|
|
277
277
|
|
|
278
|
+
const THEME = {
|
|
279
|
+
mindbill: { a: "#238dbd", ac: "#fff", bg: "#f3f8fa", s: "#fff", t: "#203743", m: "#657982", b: "#dbe6ea", r: "14px", cr: "8px", font: "Inter,system-ui,sans-serif" },
|
|
280
|
+
"qme-companion": { a: "#53b5dc", ac: "#173542", bg: "#f2f8fb", s: "#fff", t: "#1d3440", m: "#617783", b: "#d7e5eb", r: "12px", cr: "8px", font: "Inter,system-ui,sans-serif" },
|
|
281
|
+
"orange-bright": { a: "#f4510b", ac: "#fff", bg: "#fffaf6", s: "#fffefd", t: "#090f1f", m: "#626a73", b: "#e7e1da", r: "16px", cr: "10px", font: "Inter,system-ui,sans-serif" },
|
|
282
|
+
"clinical-blue": { a: "#1677ff", ac: "#fff", bg: "#f5f7fa", s: "#fff", t: "#1f2d3d", m: "#66788a", b: "#d9e2ec", r: "8px", cr: "6px", font: "Inter,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif" },
|
|
283
|
+
};
|
|
284
|
+
function mindBillAgingDays(bill, now = new Date()) {
|
|
285
|
+
if (bill.agingDays != null)
|
|
286
|
+
return Math.max(0, Math.floor(bill.agingDays));
|
|
287
|
+
const source = bill.submittedAt ?? bill.updatedAt;
|
|
288
|
+
if (!source)
|
|
289
|
+
return 0;
|
|
290
|
+
const time = new Date(source).getTime();
|
|
291
|
+
return Number.isFinite(time) ? Math.max(0, Math.floor((now.getTime() - time) / 86_400_000)) : 0;
|
|
292
|
+
}
|
|
293
|
+
function mindBillAgingBucket(days) {
|
|
294
|
+
if (days <= 30)
|
|
295
|
+
return "current";
|
|
296
|
+
if (days <= 60)
|
|
297
|
+
return "31-60";
|
|
298
|
+
if (days <= 90)
|
|
299
|
+
return "61-90";
|
|
300
|
+
return "91+";
|
|
301
|
+
}
|
|
302
|
+
function summarizeMindBillDashboard(bills, now = new Date()) {
|
|
303
|
+
const aging = [
|
|
304
|
+
{ id: "current", label: "0–30 days", count: 0, balance: 0 },
|
|
305
|
+
{ id: "31-60", label: "31–60 days", count: 0, balance: 0 },
|
|
306
|
+
{ id: "61-90", label: "61–90 days", count: 0, balance: 0 },
|
|
307
|
+
{ id: "91+", label: "91+ days", count: 0, balance: 0 },
|
|
308
|
+
];
|
|
309
|
+
for (const bill of bills) {
|
|
310
|
+
const bucket = aging.find((item) => item.id === mindBillAgingBucket(mindBillAgingDays(bill, now)));
|
|
311
|
+
bucket.count += 1;
|
|
312
|
+
bucket.balance += bill.balanceDue;
|
|
313
|
+
}
|
|
314
|
+
return {
|
|
315
|
+
totalBilled: bills.reduce((sum, item) => sum + item.totalCharge, 0),
|
|
316
|
+
totalPaid: bills.reduce((sum, item) => sum + item.totalPaid, 0),
|
|
317
|
+
outstanding: bills.reduce((sum, item) => sum + item.balanceDue, 0),
|
|
318
|
+
openCount: bills.filter((item) => !/closed|paid|written.off/i.test(item.state)).length,
|
|
319
|
+
bills,
|
|
320
|
+
aging,
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
function buildMindBillReportRows(bills, dimension) {
|
|
324
|
+
const rows = new Map();
|
|
325
|
+
for (const bill of bills) {
|
|
326
|
+
const key = dimension === "payer" ? bill.payerName || "Unassigned payer" : dimension === "aging" ? mindBillAgingBucket(mindBillAgingDays(bill)) : bill.state;
|
|
327
|
+
const label = key.replace(/_/g, " ").replace(/\b\w/g, (value) => value.toUpperCase());
|
|
328
|
+
const row = rows.get(key) ?? { key, label, billCount: 0, totalBilled: 0, totalPaid: 0, balanceDue: 0 };
|
|
329
|
+
row.billCount += 1;
|
|
330
|
+
row.totalBilled += bill.totalCharge;
|
|
331
|
+
row.totalPaid += bill.totalPaid;
|
|
332
|
+
row.balanceDue += bill.balanceDue;
|
|
333
|
+
rows.set(key, row);
|
|
334
|
+
}
|
|
335
|
+
return [...rows.values()].sort((a, b) => b.balanceDue - a.balanceDue || a.label.localeCompare(b.label));
|
|
336
|
+
}
|
|
337
|
+
function buildMindBillReportCsv(rows) {
|
|
338
|
+
const quote = (value) => `"${String(value).replace(/"/g, '""')}"`;
|
|
339
|
+
return ["Group,Bills,Total billed,Total paid,Balance due", ...rows.map((row) => [row.label, row.billCount, row.totalBilled, row.totalPaid, row.balanceDue].map(quote).join(","))].join("\n");
|
|
340
|
+
}
|
|
341
|
+
class DashboardBase {
|
|
342
|
+
appearance = { preset: "mindbill" };
|
|
343
|
+
get themeStyle() {
|
|
344
|
+
const base = THEME[this.appearance.preset ?? "mindbill"] ?? THEME["mindbill"];
|
|
345
|
+
return {
|
|
346
|
+
"--a": this.appearance.accentColor ?? base["a"], "--ac": this.appearance.accentTextColor ?? base["ac"],
|
|
347
|
+
"--bg": this.appearance.backgroundColor ?? base["bg"], "--s": this.appearance.surfaceColor ?? base["s"],
|
|
348
|
+
"--t": this.appearance.textColor ?? base["t"], "--m": this.appearance.mutedColor ?? base["m"],
|
|
349
|
+
"--b": this.appearance.borderColor ?? base["b"], "--r": this.appearance.borderRadius ?? base["r"],
|
|
350
|
+
"--cr": this.appearance.controlRadius ?? base["cr"], "--font": this.appearance.fontFamily ?? base["font"],
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: DashboardBase, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
354
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.22", type: DashboardBase, isStandalone: true, inputs: { appearance: "appearance" }, ngImport: i0 });
|
|
355
|
+
}
|
|
356
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: DashboardBase, decorators: [{
|
|
357
|
+
type: Directive
|
|
358
|
+
}], propDecorators: { appearance: [{
|
|
359
|
+
type: Input
|
|
360
|
+
}] } });
|
|
361
|
+
const sharedStyles = `
|
|
362
|
+
:host{display:block}.mbd{font-family:var(--font);color:var(--t)}button,input,select{font:inherit}.card{background:var(--s);border:1px solid var(--b);border-radius:var(--r)}
|
|
363
|
+
.money{font-variant-numeric:tabular-nums}.muted{color:var(--m)}.pill{display:inline-flex;border-radius:999px;background:color-mix(in srgb,var(--a) 12%,var(--s));color:var(--a);font-size:12px;font-weight:750;padding:5px 9px}
|
|
364
|
+
`;
|
|
365
|
+
class MindBillBillAgingSummaryComponent extends DashboardBase {
|
|
366
|
+
buckets = [];
|
|
367
|
+
width(balance) { const max = Math.max(1, ...this.buckets.map((item) => item.balance)); return Math.max(balance ? 8 : 0, balance / max * 100); }
|
|
368
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: MindBillBillAgingSummaryComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
369
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: MindBillBillAgingSummaryComponent, isStandalone: true, selector: "mindbill-bill-aging-summary", inputs: { buckets: "buckets" }, usesInheritance: true, ngImport: i0, template: `<section class="mbd aging" [ngStyle]="themeStyle" aria-label="Accounts receivable aging">@for (bucket of buckets; track bucket.id) { <article class="card"><div><strong>{{ bucket.label }}</strong><span>{{ bucket.count }} bill{{ bucket.count === 1 ? '' : 's' }}</span></div><b class="money">{{ bucket.balance | currency }}</b><i><em [style.width.%]="width(bucket.balance)"></em></i></article> }</section>`, isInline: true, styles: [":host{display:block}.mbd{font-family:var(--font);color:var(--t)}button,input,select{font:inherit}.card{background:var(--s);border:1px solid var(--b);border-radius:var(--r)}.money{font-variant-numeric:tabular-nums}.muted{color:var(--m)}.pill{display:inline-flex;border-radius:999px;background:color-mix(in srgb,var(--a) 12%,var(--s));color:var(--a);font-size:12px;font-weight:750;padding:5px 9px}\n", ".aging{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px}.aging article{padding:16px}.aging article>div{display:flex;justify-content:space-between;gap:8px}.aging span{color:var(--m);font-size:12px}.aging b{display:block;font-size:20px;margin:14px 0 12px}.aging i{display:block;height:5px;border-radius:99px;background:color-mix(in srgb,var(--b) 70%,transparent);overflow:hidden}.aging em{display:block;height:100%;background:var(--a)}@media(max-width:760px){.aging{grid-template-columns:1fr 1fr}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: i1.CurrencyPipe, name: "currency" }] });
|
|
370
|
+
}
|
|
371
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: MindBillBillAgingSummaryComponent, decorators: [{
|
|
372
|
+
type: Component,
|
|
373
|
+
args: [{ selector: "mindbill-bill-aging-summary", standalone: true, imports: [CommonModule], template: `<section class="mbd aging" [ngStyle]="themeStyle" aria-label="Accounts receivable aging">@for (bucket of buckets; track bucket.id) { <article class="card"><div><strong>{{ bucket.label }}</strong><span>{{ bucket.count }} bill{{ bucket.count === 1 ? '' : 's' }}</span></div><b class="money">{{ bucket.balance | currency }}</b><i><em [style.width.%]="width(bucket.balance)"></em></i></article> }</section>`, styles: [":host{display:block}.mbd{font-family:var(--font);color:var(--t)}button,input,select{font:inherit}.card{background:var(--s);border:1px solid var(--b);border-radius:var(--r)}.money{font-variant-numeric:tabular-nums}.muted{color:var(--m)}.pill{display:inline-flex;border-radius:999px;background:color-mix(in srgb,var(--a) 12%,var(--s));color:var(--a);font-size:12px;font-weight:750;padding:5px 9px}\n", ".aging{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px}.aging article{padding:16px}.aging article>div{display:flex;justify-content:space-between;gap:8px}.aging span{color:var(--m);font-size:12px}.aging b{display:block;font-size:20px;margin:14px 0 12px}.aging i{display:block;height:5px;border-radius:99px;background:color-mix(in srgb,var(--b) 70%,transparent);overflow:hidden}.aging em{display:block;height:100%;background:var(--a)}@media(max-width:760px){.aging{grid-template-columns:1fr 1fr}}\n"] }]
|
|
374
|
+
}], propDecorators: { buckets: [{
|
|
375
|
+
type: Input
|
|
376
|
+
}] } });
|
|
377
|
+
class MindBillBillListComponent extends DashboardBase {
|
|
378
|
+
bills = [];
|
|
379
|
+
billSelected = new EventEmitter();
|
|
380
|
+
age(bill) { return mindBillAgingDays(bill); }
|
|
381
|
+
label(value) { return value.replace(/_/g, " ").replace(/\b\w/g, (letter) => letter.toUpperCase()); }
|
|
382
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: MindBillBillListComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
383
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: MindBillBillListComponent, isStandalone: true, selector: "mindbill-bill-list", inputs: { bills: "bills" }, outputs: { billSelected: "billSelected" }, usesInheritance: true, ngImport: i0, template: `<section class="mbd list card" [ngStyle]="themeStyle"><div class="head"><strong>Bill</strong><strong>Payer</strong><strong>Status</strong><strong>Age</strong><strong>Balance</strong></div>@for (bill of bills; track bill.id) { <button type="button" (click)="billSelected.emit(bill)"><span><b>{{ bill.patientName }}</b><small>{{ bill.claimNumber || bill.workItemLabel || bill.externalId || bill.id }}</small></span><span>{{ bill.payerName || '—' }}</span><span><i class="pill">{{ label(bill.state) }}</i></span><span>{{ age(bill) }} days</span><span class="money"><b>{{ bill.balanceDue | currency }}</b><small>{{ bill.totalPaid | currency }} paid</small></span></button> } @empty { <p class="empty">No bills match these filters.</p> }</section>`, isInline: true, styles: [":host{display:block}.mbd{font-family:var(--font);color:var(--t)}button,input,select{font:inherit}.card{background:var(--s);border:1px solid var(--b);border-radius:var(--r)}.money{font-variant-numeric:tabular-nums}.muted{color:var(--m)}.pill{display:inline-flex;border-radius:999px;background:color-mix(in srgb,var(--a) 12%,var(--s));color:var(--a);font-size:12px;font-weight:750;padding:5px 9px}\n", ".list{overflow:hidden}.head,.list button{display:grid;grid-template-columns:1.6fr 1.2fr .85fr .55fr .8fr;gap:18px;align-items:center;text-align:left}.head{padding:11px 16px;background:color-mix(in srgb,var(--bg) 78%,var(--s));color:var(--m);font-size:11px;letter-spacing:.08em;text-transform:uppercase}.list button{width:100%;border:0;border-top:1px solid var(--b);background:var(--s);color:var(--t);padding:15px 16px;cursor:pointer}.list button:hover{background:color-mix(in srgb,var(--a) 5%,var(--s))}.list span,.list small{min-width:0}.list small{display:block;color:var(--m);margin-top:4px}.money{text-align:right}.empty{padding:24px;text-align:center;color:var(--m)}@media(max-width:760px){.head{display:none}.list button{grid-template-columns:1fr auto;gap:10px}.list button>span:nth-child(2){grid-column:1}.list button>span:nth-child(3){grid-row:1;grid-column:2}.list button>span:nth-child(4){grid-column:1}.money{grid-column:2;grid-row:2/4}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: i1.CurrencyPipe, name: "currency" }] });
|
|
384
|
+
}
|
|
385
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: MindBillBillListComponent, decorators: [{
|
|
386
|
+
type: Component,
|
|
387
|
+
args: [{ selector: "mindbill-bill-list", standalone: true, imports: [CommonModule], template: `<section class="mbd list card" [ngStyle]="themeStyle"><div class="head"><strong>Bill</strong><strong>Payer</strong><strong>Status</strong><strong>Age</strong><strong>Balance</strong></div>@for (bill of bills; track bill.id) { <button type="button" (click)="billSelected.emit(bill)"><span><b>{{ bill.patientName }}</b><small>{{ bill.claimNumber || bill.workItemLabel || bill.externalId || bill.id }}</small></span><span>{{ bill.payerName || '—' }}</span><span><i class="pill">{{ label(bill.state) }}</i></span><span>{{ age(bill) }} days</span><span class="money"><b>{{ bill.balanceDue | currency }}</b><small>{{ bill.totalPaid | currency }} paid</small></span></button> } @empty { <p class="empty">No bills match these filters.</p> }</section>`, styles: [":host{display:block}.mbd{font-family:var(--font);color:var(--t)}button,input,select{font:inherit}.card{background:var(--s);border:1px solid var(--b);border-radius:var(--r)}.money{font-variant-numeric:tabular-nums}.muted{color:var(--m)}.pill{display:inline-flex;border-radius:999px;background:color-mix(in srgb,var(--a) 12%,var(--s));color:var(--a);font-size:12px;font-weight:750;padding:5px 9px}\n", ".list{overflow:hidden}.head,.list button{display:grid;grid-template-columns:1.6fr 1.2fr .85fr .55fr .8fr;gap:18px;align-items:center;text-align:left}.head{padding:11px 16px;background:color-mix(in srgb,var(--bg) 78%,var(--s));color:var(--m);font-size:11px;letter-spacing:.08em;text-transform:uppercase}.list button{width:100%;border:0;border-top:1px solid var(--b);background:var(--s);color:var(--t);padding:15px 16px;cursor:pointer}.list button:hover{background:color-mix(in srgb,var(--a) 5%,var(--s))}.list span,.list small{min-width:0}.list small{display:block;color:var(--m);margin-top:4px}.money{text-align:right}.empty{padding:24px;text-align:center;color:var(--m)}@media(max-width:760px){.head{display:none}.list button{grid-template-columns:1fr auto;gap:10px}.list button>span:nth-child(2){grid-column:1}.list button>span:nth-child(3){grid-row:1;grid-column:2}.list button>span:nth-child(4){grid-column:1}.money{grid-column:2;grid-row:2/4}}\n"] }]
|
|
388
|
+
}], propDecorators: { bills: [{
|
|
389
|
+
type: Input
|
|
390
|
+
}], billSelected: [{
|
|
391
|
+
type: Output
|
|
392
|
+
}] } });
|
|
393
|
+
class MindBillBillingDashboardComponent extends DashboardBase {
|
|
394
|
+
bills = [];
|
|
395
|
+
heading = "Billing dashboard";
|
|
396
|
+
description = "Track every submitted bill from payer acceptance through payment.";
|
|
397
|
+
billSelected = new EventEmitter();
|
|
398
|
+
createBill = new EventEmitter();
|
|
399
|
+
query = "";
|
|
400
|
+
state = "";
|
|
401
|
+
get summary() { return summarizeMindBillDashboard(this.bills); }
|
|
402
|
+
get states() { return [...new Set(this.bills.map((bill) => bill.state))].sort(); }
|
|
403
|
+
get filteredBills() { const query = this.query.trim().toLowerCase(); return this.bills.filter((bill) => (!this.state || bill.state === this.state) && (!query || [bill.patientName, bill.claimNumber, bill.payerName, bill.externalId, bill.billNumber].some((value) => String(value ?? "").toLowerCase().includes(query)))); }
|
|
404
|
+
label(value) { return value.replace(/_/g, " ").replace(/\b\w/g, (letter) => letter.toUpperCase()); }
|
|
405
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: MindBillBillingDashboardComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
406
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: MindBillBillingDashboardComponent, isStandalone: true, selector: "mindbill-billing-dashboard", inputs: { bills: "bills", heading: "heading", description: "description" }, outputs: { billSelected: "billSelected", createBill: "createBill" }, usesInheritance: true, ngImport: i0, template: `<section class="mbd dashboard" [ngStyle]="themeStyle"><header><div><p>Billing operations</p><h2>{{ heading }}</h2><span class="muted">{{ description }}</span></div><button type="button" (click)="createBill.emit()">+ New bill</button></header><div class="metrics"><article class="card"><span>Total billed</span><b>{{ summary.totalBilled | currency }}</b></article><article class="card"><span>Collected</span><b>{{ summary.totalPaid | currency }}</b></article><article class="card"><span>Outstanding</span><b>{{ summary.outstanding | currency }}</b></article><article class="card"><span>Open bills</span><b>{{ summary.openCount }}</b></article></div><mindbill-bill-aging-summary [buckets]="summary.aging" [appearance]="appearance"/><div class="filters"><input [(ngModel)]="query" placeholder="Search patient, claim, or payer" aria-label="Search bills"><select [(ngModel)]="state"><option value="">All statuses</option>@for (option of states; track option) { <option [value]="option">{{ label(option) }}</option> }</select></div><mindbill-bill-list [bills]="filteredBills" [appearance]="appearance" (billSelected)="billSelected.emit($event)"/></section>`, isInline: true, styles: [":host{display:block}.mbd{font-family:var(--font);color:var(--t)}button,input,select{font:inherit}.card{background:var(--s);border:1px solid var(--b);border-radius:var(--r)}.money{font-variant-numeric:tabular-nums}.muted{color:var(--m)}.pill{display:inline-flex;border-radius:999px;background:color-mix(in srgb,var(--a) 12%,var(--s));color:var(--a);font-size:12px;font-weight:750;padding:5px 9px}\n", ".dashboard{display:grid;gap:18px}.dashboard header{display:flex;justify-content:space-between;align-items:end;gap:20px}.dashboard h2{font-size:28px;margin:2px 0 5px}.dashboard header p{margin:0;color:var(--a);font-size:12px;font-weight:800;letter-spacing:.12em;text-transform:uppercase}.dashboard header button{border:0;border-radius:var(--cr);background:var(--a);color:var(--ac);padding:11px 16px;font-weight:750;cursor:pointer}.metrics{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}.metrics article{padding:18px}.metrics span{display:block;color:var(--m);font-size:12px}.metrics b{display:block;margin-top:8px;font-size:24px}.filters{display:grid;grid-template-columns:1fr 190px;gap:10px}.filters input,.filters select{border:1px solid var(--b);border-radius:var(--cr);background:var(--s);color:var(--t);padding:11px 13px}@media(max-width:760px){.dashboard header{align-items:start}.metrics{grid-template-columns:1fr 1fr}.filters{grid-template-columns:1fr}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: MindBillBillAgingSummaryComponent, selector: "mindbill-bill-aging-summary", inputs: ["buckets"] }, { kind: "component", type: MindBillBillListComponent, selector: "mindbill-bill-list", inputs: ["bills"], outputs: ["billSelected"] }, { kind: "pipe", type: i1.CurrencyPipe, name: "currency" }] });
|
|
407
|
+
}
|
|
408
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: MindBillBillingDashboardComponent, decorators: [{
|
|
409
|
+
type: Component,
|
|
410
|
+
args: [{ selector: "mindbill-billing-dashboard", standalone: true, imports: [CommonModule, FormsModule, MindBillBillAgingSummaryComponent, MindBillBillListComponent], template: `<section class="mbd dashboard" [ngStyle]="themeStyle"><header><div><p>Billing operations</p><h2>{{ heading }}</h2><span class="muted">{{ description }}</span></div><button type="button" (click)="createBill.emit()">+ New bill</button></header><div class="metrics"><article class="card"><span>Total billed</span><b>{{ summary.totalBilled | currency }}</b></article><article class="card"><span>Collected</span><b>{{ summary.totalPaid | currency }}</b></article><article class="card"><span>Outstanding</span><b>{{ summary.outstanding | currency }}</b></article><article class="card"><span>Open bills</span><b>{{ summary.openCount }}</b></article></div><mindbill-bill-aging-summary [buckets]="summary.aging" [appearance]="appearance"/><div class="filters"><input [(ngModel)]="query" placeholder="Search patient, claim, or payer" aria-label="Search bills"><select [(ngModel)]="state"><option value="">All statuses</option>@for (option of states; track option) { <option [value]="option">{{ label(option) }}</option> }</select></div><mindbill-bill-list [bills]="filteredBills" [appearance]="appearance" (billSelected)="billSelected.emit($event)"/></section>`, styles: [":host{display:block}.mbd{font-family:var(--font);color:var(--t)}button,input,select{font:inherit}.card{background:var(--s);border:1px solid var(--b);border-radius:var(--r)}.money{font-variant-numeric:tabular-nums}.muted{color:var(--m)}.pill{display:inline-flex;border-radius:999px;background:color-mix(in srgb,var(--a) 12%,var(--s));color:var(--a);font-size:12px;font-weight:750;padding:5px 9px}\n", ".dashboard{display:grid;gap:18px}.dashboard header{display:flex;justify-content:space-between;align-items:end;gap:20px}.dashboard h2{font-size:28px;margin:2px 0 5px}.dashboard header p{margin:0;color:var(--a);font-size:12px;font-weight:800;letter-spacing:.12em;text-transform:uppercase}.dashboard header button{border:0;border-radius:var(--cr);background:var(--a);color:var(--ac);padding:11px 16px;font-weight:750;cursor:pointer}.metrics{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}.metrics article{padding:18px}.metrics span{display:block;color:var(--m);font-size:12px}.metrics b{display:block;margin-top:8px;font-size:24px}.filters{display:grid;grid-template-columns:1fr 190px;gap:10px}.filters input,.filters select{border:1px solid var(--b);border-radius:var(--cr);background:var(--s);color:var(--t);padding:11px 13px}@media(max-width:760px){.dashboard header{align-items:start}.metrics{grid-template-columns:1fr 1fr}.filters{grid-template-columns:1fr}}\n"] }]
|
|
411
|
+
}], propDecorators: { bills: [{
|
|
412
|
+
type: Input
|
|
413
|
+
}], heading: [{
|
|
414
|
+
type: Input
|
|
415
|
+
}], description: [{
|
|
416
|
+
type: Input
|
|
417
|
+
}], billSelected: [{
|
|
418
|
+
type: Output
|
|
419
|
+
}], createBill: [{
|
|
420
|
+
type: Output
|
|
421
|
+
}] } });
|
|
422
|
+
class MindBillBillingReportComponent extends DashboardBase {
|
|
423
|
+
bills = [];
|
|
424
|
+
heading = "Billing report";
|
|
425
|
+
dimension = "status";
|
|
426
|
+
get rows() { return buildMindBillReportRows(this.bills, this.dimension); }
|
|
427
|
+
downloadCsv() { const blob = new Blob([buildMindBillReportCsv(this.rows)], { type: "text/csv;charset=utf-8" }); const url = URL.createObjectURL(blob); const link = document.createElement("a"); link.href = url; link.download = `mindbill-${this.dimension}-report.csv`; link.click(); setTimeout(() => URL.revokeObjectURL(url), 1000); }
|
|
428
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: MindBillBillingReportComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
429
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: MindBillBillingReportComponent, isStandalone: true, selector: "mindbill-billing-report", inputs: { bills: "bills", heading: "heading" }, usesInheritance: true, ngImport: i0, template: `<section class="mbd report card" [ngStyle]="themeStyle"><header><div><h2>{{ heading }}</h2><p>Operational totals grouped for reconciliation and follow-up.</p></div><div><select [(ngModel)]="dimension"><option value="status">Status</option><option value="payer">Payer</option><option value="aging">Aging</option></select><button type="button" (click)="downloadCsv()">Export CSV</button></div></header><div class="thead"><b>Group</b><b>Bills</b><b>Total billed</b><b>Total paid</b><b>Balance due</b></div>@for (row of rows; track row.key) { <div class="row"><strong>{{ row.label }}</strong><span>{{ row.billCount }}</span><span>{{ row.totalBilled | currency }}</span><span>{{ row.totalPaid | currency }}</span><b>{{ row.balanceDue | currency }}</b></div> }</section>`, isInline: true, styles: [":host{display:block}.mbd{font-family:var(--font);color:var(--t)}button,input,select{font:inherit}.card{background:var(--s);border:1px solid var(--b);border-radius:var(--r)}.money{font-variant-numeric:tabular-nums}.muted{color:var(--m)}.pill{display:inline-flex;border-radius:999px;background:color-mix(in srgb,var(--a) 12%,var(--s));color:var(--a);font-size:12px;font-weight:750;padding:5px 9px}\n", ".report{overflow:hidden}.report header{display:flex;justify-content:space-between;align-items:center;padding:18px}.report h2{margin:0;font-size:22px}.report p{margin:4px 0 0;color:var(--m)}.report header div:last-child{display:flex;gap:8px}.report select,.report button{border:1px solid var(--b);border-radius:var(--cr);background:var(--s);color:var(--t);padding:9px 12px}.report button{background:var(--a);border-color:var(--a);color:var(--ac);font-weight:750;cursor:pointer}.thead,.row{display:grid;grid-template-columns:1.5fr .5fr 1fr 1fr 1fr;gap:14px;padding:12px 18px;border-top:1px solid var(--b);align-items:center}.thead{background:color-mix(in srgb,var(--bg) 78%,var(--s));color:var(--m);font-size:11px;text-transform:uppercase}.row span,.row b:not(:first-child){text-align:right;font-variant-numeric:tabular-nums}@media(max-width:700px){.report header{align-items:flex-start}.thead{display:none}.row{grid-template-columns:1fr 1fr}.row>*:nth-child(n+2){text-align:right}.row strong{grid-column:1}.row span:nth-child(2){grid-column:2}.row span:nth-child(3):before{content:\"Billed \";color:var(--m)}.row span:nth-child(4):before{content:\"Paid \";color:var(--m)}.row b:before{content:\"Due \";color:var(--m)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: i1.CurrencyPipe, name: "currency" }] });
|
|
430
|
+
}
|
|
431
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: MindBillBillingReportComponent, decorators: [{
|
|
432
|
+
type: Component,
|
|
433
|
+
args: [{ selector: "mindbill-billing-report", standalone: true, imports: [CommonModule, FormsModule], template: `<section class="mbd report card" [ngStyle]="themeStyle"><header><div><h2>{{ heading }}</h2><p>Operational totals grouped for reconciliation and follow-up.</p></div><div><select [(ngModel)]="dimension"><option value="status">Status</option><option value="payer">Payer</option><option value="aging">Aging</option></select><button type="button" (click)="downloadCsv()">Export CSV</button></div></header><div class="thead"><b>Group</b><b>Bills</b><b>Total billed</b><b>Total paid</b><b>Balance due</b></div>@for (row of rows; track row.key) { <div class="row"><strong>{{ row.label }}</strong><span>{{ row.billCount }}</span><span>{{ row.totalBilled | currency }}</span><span>{{ row.totalPaid | currency }}</span><b>{{ row.balanceDue | currency }}</b></div> }</section>`, styles: [":host{display:block}.mbd{font-family:var(--font);color:var(--t)}button,input,select{font:inherit}.card{background:var(--s);border:1px solid var(--b);border-radius:var(--r)}.money{font-variant-numeric:tabular-nums}.muted{color:var(--m)}.pill{display:inline-flex;border-radius:999px;background:color-mix(in srgb,var(--a) 12%,var(--s));color:var(--a);font-size:12px;font-weight:750;padding:5px 9px}\n", ".report{overflow:hidden}.report header{display:flex;justify-content:space-between;align-items:center;padding:18px}.report h2{margin:0;font-size:22px}.report p{margin:4px 0 0;color:var(--m)}.report header div:last-child{display:flex;gap:8px}.report select,.report button{border:1px solid var(--b);border-radius:var(--cr);background:var(--s);color:var(--t);padding:9px 12px}.report button{background:var(--a);border-color:var(--a);color:var(--ac);font-weight:750;cursor:pointer}.thead,.row{display:grid;grid-template-columns:1.5fr .5fr 1fr 1fr 1fr;gap:14px;padding:12px 18px;border-top:1px solid var(--b);align-items:center}.thead{background:color-mix(in srgb,var(--bg) 78%,var(--s));color:var(--m);font-size:11px;text-transform:uppercase}.row span,.row b:not(:first-child){text-align:right;font-variant-numeric:tabular-nums}@media(max-width:700px){.report header{align-items:flex-start}.thead{display:none}.row{grid-template-columns:1fr 1fr}.row>*:nth-child(n+2){text-align:right}.row strong{grid-column:1}.row span:nth-child(2){grid-column:2}.row span:nth-child(3):before{content:\"Billed \";color:var(--m)}.row span:nth-child(4):before{content:\"Paid \";color:var(--m)}.row b:before{content:\"Due \";color:var(--m)}}\n"] }]
|
|
434
|
+
}], propDecorators: { bills: [{
|
|
435
|
+
type: Input
|
|
436
|
+
}], heading: [{
|
|
437
|
+
type: Input
|
|
438
|
+
}] } });
|
|
439
|
+
|
|
278
440
|
/**
|
|
279
441
|
* Generated bundle index. Do not edit.
|
|
280
442
|
*/
|
|
281
443
|
|
|
282
|
-
export { MindBillBillLifecycleComponent, MindBillLifecycleStore, ensureTrailingProcedureLine, isEmptyProcedureLine };
|
|
444
|
+
export { MindBillBillAgingSummaryComponent, MindBillBillLifecycleComponent, MindBillBillListComponent, MindBillBillingDashboardComponent, MindBillBillingReportComponent, MindBillLifecycleStore, buildMindBillReportCsv, buildMindBillReportRows, ensureTrailingProcedureLine, isEmptyProcedureLine, mindBillAgingBucket, mindBillAgingDays, summarizeMindBillDashboard };
|
|
283
445
|
//# sourceMappingURL=mindbill-angular.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mindbill-angular.mjs","sources":["../../src/lib/lifecycle-store.ts","../../src/lib/bill-lifecycle.component.ts","../../src/lib/procedure-lines.ts","../../src/mindbill-angular.ts"],"sourcesContent":["import { computed, signal } from \"@angular/core\";\nimport {\n createBillLifecycleClient,\n type BillLifecycleClient,\n type BillLifecycleClientOptions,\n type BillLifecycleData,\n type CloseBillInput,\n type PostBillPaymentInput,\n type SubmitSecondReviewInput,\n} from \"@mindbill/browser\";\n\nexport class MindBillLifecycleStore {\n readonly billId = signal(\"\");\n readonly data = signal<BillLifecycleData | null>(null);\n readonly error = signal<Error | null>(null);\n readonly loading = signal(false);\n readonly mutating = signal(false);\n readonly ready = computed(() => this.data() !== null && !this.loading());\n private client: BillLifecycleClient | null = null;\n private refreshTimer: ReturnType<typeof setInterval> | null = null;\n\n connect(\n options: BillLifecycleClientOptions,\n refreshInterval = 60_000,\n ): void {\n this.disconnect();\n this.billId.set(options.billId);\n this.client = createBillLifecycleClient(options);\n void this.refresh();\n if (refreshInterval > 0) {\n this.refreshTimer = setInterval(() => void this.refresh(), refreshInterval);\n }\n }\n\n disconnect(): void {\n if (this.refreshTimer) clearInterval(this.refreshTimer);\n this.refreshTimer = null;\n this.client?.clearSession();\n this.client = null;\n }\n\n async refresh(): Promise<BillLifecycleData | null> {\n if (!this.client) return null;\n this.loading.set(this.data() === null);\n try {\n const data = await this.client.getLifecycle();\n this.data.set(data);\n this.error.set(null);\n return data;\n } catch (cause) {\n this.error.set(cause instanceof Error ? cause : new Error(\"Bill could not be loaded.\"));\n return null;\n } finally {\n this.loading.set(false);\n }\n }\n\n getDeliveryOptions() { return this.requireClient().getDeliveryOptions(); }\n getAttachment(id: string) { return this.requireClient().getAttachment(id); }\n getEor(id: string) { return this.requireClient().getEor(id); }\n closeBill(input: CloseBillInput) { return this.mutate(() => this.requireClient().closeBill(input)); }\n postPayment(input: PostBillPaymentInput) { return this.mutate(() => this.requireClient().postPayment(input)); }\n submitSecondReview(input: SubmitSecondReviewInput) { return this.mutate(() => this.requireClient().submitSecondReview(input)); }\n\n private requireClient(): BillLifecycleClient {\n if (!this.client) throw new Error(\"Connect the lifecycle store before using it.\");\n return this.client;\n }\n\n private async mutate(task: () => Promise<BillLifecycleData>): Promise<BillLifecycleData> {\n this.mutating.set(true);\n this.error.set(null);\n try {\n const data = await task();\n this.data.set(data);\n return data;\n } catch (cause) {\n const error = cause instanceof Error ? cause : new Error(\"The billing request could not be completed.\");\n this.error.set(error);\n throw error;\n } finally {\n this.mutating.set(false);\n }\n }\n}\n","import { CommonModule } from \"@angular/common\";\nimport { Component, EventEmitter, Input, OnChanges, OnDestroy, Output, SimpleChanges, effect } from \"@angular/core\";\nimport { FormsModule } from \"@angular/forms\";\nimport type { BillLifecycleData, BillLifecycleSessionProvider } from \"@mindbill/browser\";\nimport { MindBillLifecycleStore } from \"./lifecycle-store\";\n\nexport type MindBillAngularThemePreset = \"mindbill\" | \"qme-companion\" | \"orange-bright\" | \"clinical-blue\";\nexport type MindBillAngularAppearance = {\n preset?: MindBillAngularThemePreset;\n accentColor?: string;\n accentTextColor?: string;\n backgroundColor?: string;\n surfaceColor?: string;\n textColor?: string;\n mutedColor?: string;\n borderColor?: string;\n borderRadius?: string;\n controlRadius?: string;\n fontFamily?: string;\n};\n\nconst THEMES: Record<MindBillAngularThemePreset, Required<MindBillAngularAppearance>> = {\n mindbill: { preset: \"mindbill\", accentColor: \"#238dbd\", accentTextColor: \"#fff\", backgroundColor: \"#f3f8fa\", surfaceColor: \"#fff\", textColor: \"#203743\", mutedColor: \"#657982\", borderColor: \"#dbe6ea\", borderRadius: \"14px\", controlRadius: \"8px\", fontFamily: \"Inter,system-ui,sans-serif\" },\n \"qme-companion\": { preset: \"qme-companion\", accentColor: \"#53b5dc\", accentTextColor: \"#173542\", backgroundColor: \"#f2f8fb\", surfaceColor: \"#fff\", textColor: \"#1d3440\", mutedColor: \"#617783\", borderColor: \"#d7e5eb\", borderRadius: \"12px\", controlRadius: \"8px\", fontFamily: \"Inter,system-ui,sans-serif\" },\n \"orange-bright\": { preset: \"orange-bright\", accentColor: \"#f4510b\", accentTextColor: \"#fff\", backgroundColor: \"#fffaf6\", surfaceColor: \"#fffefd\", textColor: \"#090f1f\", mutedColor: \"#626a73\", borderColor: \"#e7e1da\", borderRadius: \"16px\", controlRadius: \"10px\", fontFamily: \"Inter,system-ui,sans-serif\" },\n \"clinical-blue\": { preset: \"clinical-blue\", accentColor: \"#1677ff\", accentTextColor: \"#fff\", backgroundColor: \"#f5f7fa\", surfaceColor: \"#fff\", textColor: \"#1f2d3d\", mutedColor: \"#66788a\", borderColor: \"#d9e2ec\", borderRadius: \"8px\", controlRadius: \"6px\", fontFamily: \"Inter,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif\" },\n};\n\n@Component({\n selector: \"mindbill-bill-lifecycle\",\n standalone: true,\n imports: [CommonModule, FormsModule],\n template: `\n <section class=\"mb\" [ngStyle]=\"themeStyle\">\n @if (!billId) {\n <div class=\"state error\"><strong>A submitted bill ID is required.</strong></div>\n } @else if (store.loading() && !store.data()) {\n <div class=\"state\">Loading billing…</div>\n } @else if (store.error() && !store.data()) {\n <div class=\"state error\"><strong>Billing is temporarily unavailable</strong><span>{{ store.error()?.message }}</span><button type=\"button\" (click)=\"store.refresh()\">Try again</button></div>\n } @else if (store.data(); as data) {\n <header class=\"summary\">\n <div><span class=\"eyebrow\">Bill {{ data.bill.billNumber }}</span><h2>{{ stateLabel(data) }}</h2><p>{{ lifecycleDetail(data) }}</p></div>\n <div class=\"money\"><span>{{ data.bill.balanceDue | currency }}</span><small>balance</small></div>\n </header>\n\n <section class=\"card progress\" aria-label=\"Bill lifecycle\">\n <ol>@for (stage of lifecycleStages; track stage.id; let i=$index) { <li [class.complete]=\"i < currentStageIndex(data)\" [class.current]=\"i === currentStageIndex(data)\"><b>{{ i < currentStageIndex(data) ? '✓' : i + 1 }}</b><span>{{ stage.label }}</span></li> }</ol>\n </section>\n\n <section class=\"card snapshot\" aria-label=\"Bill snapshot\">\n <div class=\"card-title\"><div><h3>Bill snapshot</h3><p>The immutable values submitted to the payer.</p></div></div>\n <dl><div><dt>Patient</dt><dd>{{ data.patient.name }}</dd></div><div><dt>Claim</dt><dd>{{ data.injury.claimNumber || '—' }}</dd></div><div><dt>Payer</dt><dd>{{ data.delivery.payerName || data.injury.claimsAdminName || '—' }}</dd></div><div><dt>Date of service</dt><dd>{{ data.bill.dos || '—' }}</dd></div><div><dt>Charged</dt><dd>{{ data.bill.totalCharge | currency }}</dd></div><div><dt>Balance</dt><dd>{{ data.bill.balanceDue | currency }}</dd></div></dl>\n </section>\n\n <div class=\"columns\">\n <section class=\"card\"><div class=\"card-title\"><div><h3>Remittance</h3><p>Amounts reported by the payer and posted to this bill.</p></div></div><dl><div><dt>Payer reported</dt><dd>{{ data.remittance.payerReportedPaid == null ? '—' : (data.remittance.payerReportedPaid | currency) }}</dd></div><div><dt>Posted</dt><dd>{{ data.remittance.totalPaid | currency }}</dd></div><div><dt>Balance</dt><dd>{{ data.remittance.balanceDue | currency }}</dd></div></dl></section>\n <section class=\"card\"><div class=\"card-title\"><div><h3>{{ data.delivery.payerName || 'Payer' }}</h3><p>Billing and follow-up contacts.</p></div></div><p class=\"muted\">{{ payerContact(data) }}</p></section>\n </div>\n\n <section class=\"card\"><div class=\"card-title\"><div><h3>Documents</h3><p>Documents preserved with the submitted bill.</p></div><span>{{ data.bill.attachments.length }}</span></div>@if (data.bill.attachments.length) { <ul class=\"rows\">@for (doc of data.bill.attachments; track doc.id) { <li><div><strong>{{ doc.filename }}</strong><small>{{ doc.description || doc.documentType }}</small></div><button type=\"button\" (click)=\"openAttachment(doc.id, doc.filename)\">View</button></li> }</ul> } @else { <p class=\"muted\">No documents available.</p> }</section>\n\n <section class=\"card\"><div class=\"card-title\"><div><h3>Payments</h3><p>Payments posted to this bill.</p></div><span>{{ data.payments.length }}</span></div>@if (data.payments.length) { <ul class=\"rows\">@for (payment of data.payments; track payment.id) { <li><div><strong>{{ payment.amount | currency }}</strong><small>{{ payment.method | uppercase }} · {{ payment.depositDate || payment.postedAt }}</small></div></li> }</ul> } @else { <p class=\"muted\">No payments posted.</p> }</section>\n\n <section class=\"card\"><div class=\"card-title\"><div><h3>Bill history</h3><p>Submission, payer responses, follow-up, and payments.</p></div><span>{{ data.activity.length }}</span></div><ul class=\"timeline\">@for (event of data.activity; track event.id) { <li><i></i><div><strong>{{ activityLabel(event.type) }}</strong><p>{{ event.description }}</p><small>{{ event.createdAt | date:'medium' }}</small></div></li> }</ul></section>\n\n @if (notice) { <p class=\"notice\">{{ notice }}</p> }\n <div class=\"actions\">@for (action of data.lifecycle.actions; track action.id) { @if (action.id !== 'view_eor' || data.eors.length) { <button type=\"button\" [class.primary]=\"action.primary\" [disabled]=\"!action.enabled || store.mutating()\" (click)=\"beginAction(action.id, data)\">{{ action.label }}</button> } }</div>\n\n @if (panel === 'payment') { <form class=\"card action-form\" (submit)=\"$event.preventDefault(); postPayment()\"><h3>Post payment</h3><label>Amount<input required type=\"number\" min=\"0.01\" step=\"0.01\" [(ngModel)]=\"payment.amount\" name=\"amount\"></label><label>Method<select [(ngModel)]=\"payment.method\" name=\"method\"><option value=\"check\">Check</option><option value=\"eft\">EFT</option></select></label><label>Deposit date<input required type=\"date\" [(ngModel)]=\"payment.depositDate\" name=\"depositDate\"></label><div><button type=\"button\" (click)=\"panel=''\">Cancel</button><button class=\"primary\" type=\"submit\">Post payment</button></div></form> }\n @if (panel === 'review') { <form class=\"card action-form\" (submit)=\"$event.preventDefault(); submitReview()\"><h3>Submit Second Bill Review</h3><label>Reason<textarea required [(ngModel)]=\"review.reason\" name=\"reason\"></textarea></label><label>Payer claim control number<input required [(ngModel)]=\"review.payerClaimControlNumber\" name=\"control\"></label><label>Disputed amount<input type=\"number\" min=\"0\" step=\"0.01\" [(ngModel)]=\"review.disputedAmount\" name=\"disputed\"></label><div><button type=\"button\" (click)=\"panel=''\">Cancel</button><button class=\"primary\" type=\"submit\">Submit review</button></div></form> }\n @if (panel === 'close') { <form class=\"card action-form\" (submit)=\"$event.preventDefault(); closeBill()\"><h3>Close bill</h3><label>Reason<textarea required [(ngModel)]=\"closeReason\" name=\"closeReason\"></textarea></label><div><button type=\"button\" (click)=\"panel=''\">Cancel</button><button class=\"primary\" type=\"submit\">Close bill</button></div></form> }\n }\n </section>\n `,\n styles: [`\n :host{display:block}.mb{font-family:var(--font);color:var(--t);background:var(--bg);padding:20px}.summary,.card,.columns{max-width:1120px;margin:0 auto 16px}.summary{display:flex;justify-content:space-between;align-items:end}.summary h2{margin:4px 0}.summary p,.muted{color:var(--m)}.eyebrow,dt{font-size:12px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--m)}.money{text-align:right}.money span{display:block;font-size:28px;font-weight:800}.money small{color:var(--m)}.card{background:var(--s);border:1px solid var(--b);border-radius:var(--r);padding:20px}.card-title{display:flex;justify-content:space-between;gap:20px}.card-title h3{margin:0}.card-title p{margin:5px 0;color:var(--m)}.progress ol{display:flex;list-style:none;padding:0;margin:0}.progress li{flex:1;text-align:center;position:relative;color:var(--m)}.progress li:before{content:\"\";position:absolute;top:16px;left:0;right:0;border-top:2px solid var(--b)}.progress li:first-child:before{left:50%}.progress li:last-child:before{right:50%}.progress b{position:relative;z-index:1;display:grid;place-items:center;width:32px;height:32px;margin:auto;border:2px solid var(--b);border-radius:50%;background:var(--s)}.progress .complete b,.progress .current b{border-color:var(--a);background:var(--a);color:var(--ac)}.progress span{display:block;margin-top:8px;font-size:12px;font-weight:700}.snapshot dl,.columns dl{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}.snapshot dd,.columns dd{font-weight:700;margin:6px 0}.columns{display:grid;grid-template-columns:1fr 1fr;gap:16px}.columns .card{margin:0}.rows,.timeline{list-style:none;margin:12px 0 0;padding:0}.rows li{display:flex;justify-content:space-between;align-items:center;padding:12px 0;border-top:1px solid var(--b)}.rows small{display:block;color:var(--m);margin-top:3px}.timeline li{display:flex;gap:14px;padding:10px 0}.timeline i{width:10px;height:10px;margin-top:5px;border:3px solid var(--a);border-radius:50%}.timeline p{margin:4px 0}.timeline small{color:var(--m)}button,input,select,textarea{font:inherit;border:1px solid var(--b);border-radius:var(--cr);padding:9px 12px;background:var(--s);color:var(--t)}button{cursor:pointer;font-weight:700}.primary{background:var(--a);border-color:var(--a);color:var(--ac)}.actions{max-width:1120px;margin:0 auto;display:flex;justify-content:flex-end;gap:10px}.action-form{display:grid;gap:12px}.action-form label{display:grid;gap:5px;font-weight:700}.action-form div{display:flex;justify-content:flex-end;gap:10px}.state{max-width:720px;margin:auto;padding:32px;text-align:center}.state span{display:block;margin:8px}.error{color:#9b1c1c}.notice{max-width:1120px;margin:0 auto 12px;color:var(--m)}@media(max-width:760px){.mb{padding:12px}.summary,.columns{display:block}.money{text-align:left;margin-top:12px}.columns .card{margin-bottom:12px}.snapshot dl,.columns dl{grid-template-columns:1fr 1fr}.progress span{font-size:10px}.card{padding:15px}}\n `],\n})\nexport class MindBillBillLifecycleComponent implements OnChanges, OnDestroy {\n @Input() billId = \"\";\n @Input() sessionEndpoint = \"/api/mindbill/session\";\n @Input() apiBaseUrl = \"https://app.mindbill.org\";\n @Input() getSession?: BillLifecycleSessionProvider;\n @Input() refreshInterval = 60_000;\n @Input() appearance: MindBillAngularAppearance = { preset: \"mindbill\" };\n @Output() billingError = new EventEmitter<Error>();\n\n readonly store = new MindBillLifecycleStore();\n readonly lifecycleStages = [\n { id: \"submitted\", label: \"Submitted\" }, { id: \"accepted\", label: \"Accepted\" },\n { id: \"response\", label: \"Payer response\" }, { id: \"follow_up\", label: \"Follow-up\" },\n { id: \"closed\", label: \"Closed\" },\n ];\n panel = \"\";\n notice = \"\";\n closeReason = \"\";\n payment = { amount: 0, method: \"check\" as \"check\" | \"eft\", depositDate: new Date().toISOString().slice(0, 10) };\n review = { reason: \"\", payerClaimControlNumber: \"\", disputedAmount: 0 };\n\n constructor() { effect(() => { const error = this.store.error(); if (error) this.billingError.emit(error); }); }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes[\"billId\"] || changes[\"sessionEndpoint\"] || changes[\"apiBaseUrl\"] || changes[\"getSession\"]) {\n if (!this.billId.trim()) { this.store.disconnect(); return; }\n this.store.connect({ billId: this.billId, sessionEndpoint: this.sessionEndpoint, apiBaseUrl: this.apiBaseUrl, ...(this.getSession ? { getSession: this.getSession } : {}) }, this.refreshInterval);\n }\n }\n ngOnDestroy(): void { this.store.disconnect(); }\n\n get themeStyle(): Record<string, string> {\n const base = THEMES[this.appearance.preset ?? \"mindbill\"];\n return { \"--a\": this.appearance.accentColor ?? base.accentColor, \"--ac\": this.appearance.accentTextColor ?? base.accentTextColor, \"--bg\": this.appearance.backgroundColor ?? base.backgroundColor, \"--s\": this.appearance.surfaceColor ?? base.surfaceColor, \"--t\": this.appearance.textColor ?? base.textColor, \"--m\": this.appearance.mutedColor ?? base.mutedColor, \"--b\": this.appearance.borderColor ?? base.borderColor, \"--r\": this.appearance.borderRadius ?? base.borderRadius, \"--cr\": this.appearance.controlRadius ?? base.controlRadius, \"--font\": this.appearance.fontFamily ?? base.fontFamily };\n }\n stateLabel(data: BillLifecycleData): string { return data.lifecycle.state.replace(/_/g, \" \").replace(/\\b\\w/g, (value) => value.toUpperCase()); }\n lifecycleDetail(data: BillLifecycleData): string { return data.lifecycle.submittedAt ? `Submitted ${new Date(data.lifecycle.submittedAt).toLocaleDateString()}${data.lifecycle.agingDays != null ? ` · ${data.lifecycle.agingDays} days old` : \"\"}` : \"Submitted bill\"; }\n currentStageIndex(data: BillLifecycleData): number { const value = data.lifecycle.state.toLowerCase(); if (value.includes(\"closed\") || value.includes(\"written_off\")) return 4; if (value.includes(\"second_review\") || value.includes(\"ibr\") || value.includes(\"lien\") || value.includes(\"appeal\")) return 3; if (value.includes(\"processed\") || value.includes(\"paid\") || value.includes(\"denied\") || value.includes(\"rejected\") || value.includes(\"response\")) return 2; if (value.includes(\"accepted\")) return 1; return 0; }\n activityLabel(type: string): string { return type.replace(/[._-]+/g, \" \").replace(/\\b\\w/g, (value) => value.toUpperCase()); }\n payerContact(data: BillLifecycleData): string { const contacts = data.delivery.contacts; return contacts.adjusterName || contacts.adjusterPhone || contacts.adjusterEmail || contacts.claimsEmail || contacts.faxNumber || contacts.mailingAddress || \"No payer contact details are available.\"; }\n beginAction(action: string, data: BillLifecycleData): void { if (action === \"post_payment\") this.panel = \"payment\"; else if (action === \"second_review\" || action === \"independent_bill_review\") this.panel = \"review\"; else if (action === \"close\") this.panel = \"close\"; else if (action === \"view_eor\" && data.eors[0]) void this.openEor(data.eors[0].id, data.eors[0].filename); }\n async openAttachment(id: string, filename: string): Promise<void> { this.openBlob(await this.store.getAttachment(id), filename); }\n async openEor(id: string, filename: string): Promise<void> { this.openBlob(await this.store.getEor(id), filename); }\n async postPayment(): Promise<void> { await this.store.postPayment(this.payment); this.panel = \"\"; this.notice = \"Payment posted.\"; }\n async submitReview(): Promise<void> { await this.store.submitSecondReview({ ...this.review, disputedAmount: this.review.disputedAmount > 0 ? this.review.disputedAmount : undefined, attachmentIds: this.store.data()?.bill.attachments.map((document) => document.id) ?? [], route: \"ebill\" }); this.panel = \"\"; this.notice = \"Second Review submitted.\"; }\n async closeBill(): Promise<void> { if (!this.closeReason.trim()) return; await this.store.closeBill({ reason: this.closeReason }); this.panel = \"\"; this.notice = \"Bill closed.\"; }\n private openBlob(blob: Blob, filename: string): void { const url = URL.createObjectURL(blob); const link = document.createElement(\"a\"); link.href = url; link.target = \"_blank\"; link.rel = \"noopener\"; link.download = filename; link.click(); setTimeout(() => URL.revokeObjectURL(url), 60_000); }\n}\n","export type ProcedureLine = {\n id?: string;\n code: string;\n modifiers: string[];\n units: number;\n charge: number;\n feeSchedule?: number;\n serviceDate?: string | null;\n serviceDateEnd?: string | null;\n diagnosisPointers?: number[];\n};\n\nconst EMPTY_PROCEDURE_LINE: ProcedureLine = {\n code: \"\",\n modifiers: [],\n units: 1,\n charge: 0,\n};\n\nexport function isEmptyProcedureLine(line: ProcedureLine): boolean {\n return !line.code.trim()\n && line.modifiers.length === 0\n && line.units === 1\n && !line.serviceDate\n && !line.serviceDateEnd\n && !(line.diagnosisPointers?.length)\n && !line.charge;\n}\n\n/** Keeps completed/partial lines plus one keyboard-ready empty row. */\nexport function ensureTrailingProcedureLine(\n lines: readonly ProcedureLine[],\n): ProcedureLine[] {\n const entered = lines\n .filter((line) => !isEmptyProcedureLine(line))\n .map((line) => ({ ...line, modifiers: [...line.modifiers] }));\n\n return entered.length < 50\n ? [...entered, { ...EMPTY_PROCEDURE_LINE, modifiers: [] }]\n : entered;\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"mindbill-angular.mjs","sources":["../../src/lib/lifecycle-store.ts","../../src/lib/bill-lifecycle.component.ts","../../src/lib/procedure-lines.ts","../../src/lib/billing-dashboard.component.ts","../../src/mindbill-angular.ts"],"sourcesContent":["import { computed, signal } from \"@angular/core\";\nimport {\n createBillLifecycleClient,\n type BillLifecycleClient,\n type BillLifecycleClientOptions,\n type BillLifecycleData,\n type CloseBillInput,\n type PostBillPaymentInput,\n type SubmitSecondReviewInput,\n} from \"@mindbill/browser\";\n\nexport class MindBillLifecycleStore {\n readonly billId = signal(\"\");\n readonly data = signal<BillLifecycleData | null>(null);\n readonly error = signal<Error | null>(null);\n readonly loading = signal(false);\n readonly mutating = signal(false);\n readonly ready = computed(() => this.data() !== null && !this.loading());\n private client: BillLifecycleClient | null = null;\n private refreshTimer: ReturnType<typeof setInterval> | null = null;\n\n connect(\n options: BillLifecycleClientOptions,\n refreshInterval = 60_000,\n ): void {\n this.disconnect();\n this.billId.set(options.billId);\n this.client = createBillLifecycleClient(options);\n void this.refresh();\n if (refreshInterval > 0) {\n this.refreshTimer = setInterval(() => void this.refresh(), refreshInterval);\n }\n }\n\n disconnect(): void {\n if (this.refreshTimer) clearInterval(this.refreshTimer);\n this.refreshTimer = null;\n this.client?.clearSession();\n this.client = null;\n }\n\n async refresh(): Promise<BillLifecycleData | null> {\n if (!this.client) return null;\n this.loading.set(this.data() === null);\n try {\n const data = await this.client.getLifecycle();\n this.data.set(data);\n this.error.set(null);\n return data;\n } catch (cause) {\n this.error.set(cause instanceof Error ? cause : new Error(\"Bill could not be loaded.\"));\n return null;\n } finally {\n this.loading.set(false);\n }\n }\n\n getDeliveryOptions() { return this.requireClient().getDeliveryOptions(); }\n getAttachment(id: string) { return this.requireClient().getAttachment(id); }\n getEor(id: string) { return this.requireClient().getEor(id); }\n closeBill(input: CloseBillInput) { return this.mutate(() => this.requireClient().closeBill(input)); }\n postPayment(input: PostBillPaymentInput) { return this.mutate(() => this.requireClient().postPayment(input)); }\n submitSecondReview(input: SubmitSecondReviewInput) { return this.mutate(() => this.requireClient().submitSecondReview(input)); }\n\n private requireClient(): BillLifecycleClient {\n if (!this.client) throw new Error(\"Connect the lifecycle store before using it.\");\n return this.client;\n }\n\n private async mutate(task: () => Promise<BillLifecycleData>): Promise<BillLifecycleData> {\n this.mutating.set(true);\n this.error.set(null);\n try {\n const data = await task();\n this.data.set(data);\n return data;\n } catch (cause) {\n const error = cause instanceof Error ? cause : new Error(\"The billing request could not be completed.\");\n this.error.set(error);\n throw error;\n } finally {\n this.mutating.set(false);\n }\n }\n}\n","import { CommonModule } from \"@angular/common\";\nimport { Component, EventEmitter, Input, OnChanges, OnDestroy, Output, SimpleChanges, effect } from \"@angular/core\";\nimport { FormsModule } from \"@angular/forms\";\nimport type { BillLifecycleData, BillLifecycleSessionProvider } from \"@mindbill/browser\";\nimport { MindBillLifecycleStore } from \"./lifecycle-store\";\n\nexport type MindBillAngularThemePreset = \"mindbill\" | \"qme-companion\" | \"orange-bright\" | \"clinical-blue\";\nexport type MindBillAngularAppearance = {\n preset?: MindBillAngularThemePreset;\n accentColor?: string;\n accentTextColor?: string;\n backgroundColor?: string;\n surfaceColor?: string;\n textColor?: string;\n mutedColor?: string;\n borderColor?: string;\n borderRadius?: string;\n controlRadius?: string;\n fontFamily?: string;\n};\n\nconst THEMES: Record<MindBillAngularThemePreset, Required<MindBillAngularAppearance>> = {\n mindbill: { preset: \"mindbill\", accentColor: \"#238dbd\", accentTextColor: \"#fff\", backgroundColor: \"#f3f8fa\", surfaceColor: \"#fff\", textColor: \"#203743\", mutedColor: \"#657982\", borderColor: \"#dbe6ea\", borderRadius: \"14px\", controlRadius: \"8px\", fontFamily: \"Inter,system-ui,sans-serif\" },\n \"qme-companion\": { preset: \"qme-companion\", accentColor: \"#53b5dc\", accentTextColor: \"#173542\", backgroundColor: \"#f2f8fb\", surfaceColor: \"#fff\", textColor: \"#1d3440\", mutedColor: \"#617783\", borderColor: \"#d7e5eb\", borderRadius: \"12px\", controlRadius: \"8px\", fontFamily: \"Inter,system-ui,sans-serif\" },\n \"orange-bright\": { preset: \"orange-bright\", accentColor: \"#f4510b\", accentTextColor: \"#fff\", backgroundColor: \"#fffaf6\", surfaceColor: \"#fffefd\", textColor: \"#090f1f\", mutedColor: \"#626a73\", borderColor: \"#e7e1da\", borderRadius: \"16px\", controlRadius: \"10px\", fontFamily: \"Inter,system-ui,sans-serif\" },\n \"clinical-blue\": { preset: \"clinical-blue\", accentColor: \"#1677ff\", accentTextColor: \"#fff\", backgroundColor: \"#f5f7fa\", surfaceColor: \"#fff\", textColor: \"#1f2d3d\", mutedColor: \"#66788a\", borderColor: \"#d9e2ec\", borderRadius: \"8px\", controlRadius: \"6px\", fontFamily: \"Inter,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif\" },\n};\n\n@Component({\n selector: \"mindbill-bill-lifecycle\",\n standalone: true,\n imports: [CommonModule, FormsModule],\n template: `\n <section class=\"mb\" [ngStyle]=\"themeStyle\">\n @if (!billId) {\n <div class=\"state error\"><strong>A submitted bill ID is required.</strong></div>\n } @else if (store.loading() && !store.data()) {\n <div class=\"state\">Loading billing…</div>\n } @else if (store.error() && !store.data()) {\n <div class=\"state error\"><strong>Billing is temporarily unavailable</strong><span>{{ store.error()?.message }}</span><button type=\"button\" (click)=\"store.refresh()\">Try again</button></div>\n } @else if (store.data(); as data) {\n <header class=\"summary\">\n <div><span class=\"eyebrow\">Bill {{ data.bill.billNumber }}</span><h2>{{ stateLabel(data) }}</h2><p>{{ lifecycleDetail(data) }}</p></div>\n <div class=\"money\"><span>{{ data.bill.balanceDue | currency }}</span><small>balance</small></div>\n </header>\n\n <section class=\"card progress\" aria-label=\"Bill lifecycle\">\n <ol>@for (stage of lifecycleStages; track stage.id; let i=$index) { <li [class.complete]=\"i < currentStageIndex(data)\" [class.current]=\"i === currentStageIndex(data)\"><b>{{ i < currentStageIndex(data) ? '✓' : i + 1 }}</b><span>{{ stage.label }}</span></li> }</ol>\n </section>\n\n <section class=\"card snapshot\" aria-label=\"Bill snapshot\">\n <div class=\"card-title\"><div><h3>Bill snapshot</h3><p>The immutable values submitted to the payer.</p></div></div>\n <dl><div><dt>Patient</dt><dd>{{ data.patient.name }}</dd></div><div><dt>Claim</dt><dd>{{ data.injury.claimNumber || '—' }}</dd></div><div><dt>Payer</dt><dd>{{ data.delivery.payerName || data.injury.claimsAdminName || '—' }}</dd></div><div><dt>Date of service</dt><dd>{{ data.bill.dos || '—' }}</dd></div><div><dt>Charged</dt><dd>{{ data.bill.totalCharge | currency }}</dd></div><div><dt>Balance</dt><dd>{{ data.bill.balanceDue | currency }}</dd></div></dl>\n </section>\n\n <div class=\"columns\">\n <section class=\"card\"><div class=\"card-title\"><div><h3>Remittance</h3><p>Amounts reported by the payer and posted to this bill.</p></div></div><dl><div><dt>Billed</dt><dd>{{ data.remittance.billedAmount | currency }}</dd></div><div><dt>Payer reported</dt><dd>{{ data.remittance.payerReportedPaid == null ? '—' : (data.remittance.payerReportedPaid | currency) }}</dd></div><div><dt>Principal posted</dt><dd>{{ data.remittance.postedPrincipal | currency }}</dd></div><div><dt>Penalty & interest</dt><dd>{{ data.remittance.postedAdditional | currency }}</dd></div><div><dt>Total received</dt><dd>{{ data.remittance.totalPostedCash | currency }}</dd></div><div><dt>Balance</dt><dd>{{ data.remittance.balanceDue | currency }}</dd></div></dl></section>\n <section class=\"card\"><div class=\"card-title\"><div><h3>{{ data.delivery.payerName || 'Payer' }}</h3><p>Billing and follow-up contacts.</p></div></div><p class=\"muted\">{{ payerContact(data) }}</p></section>\n </div>\n\n <section class=\"card\"><div class=\"card-title\"><div><h3>Documents</h3><p>Documents preserved with the submitted bill.</p></div><span>{{ data.bill.attachments.length }}</span></div>@if (data.bill.attachments.length) { <ul class=\"rows\">@for (doc of data.bill.attachments; track doc.id) { <li><div><strong>{{ doc.filename }}</strong><small>{{ doc.description || doc.documentType }}</small></div><button type=\"button\" (click)=\"openAttachment(doc.id, doc.filename)\">View</button></li> }</ul> } @else { <p class=\"muted\">No documents available.</p> }</section>\n\n <section class=\"card\"><div class=\"card-title\"><div><h3>Payments</h3><p>Payments posted to this bill.</p></div><span>{{ data.payments.length }}</span></div>@if (data.payments.length) { <ul class=\"rows\">@for (payment of data.payments; track payment.id) { <li><div><strong>{{ payment.amount | currency }}</strong><small>{{ payment.method | uppercase }} · {{ payment.depositDate || payment.postedAt }}</small></div></li> }</ul> } @else { <p class=\"muted\">No payments posted.</p> }</section>\n\n <section class=\"card\"><div class=\"card-title\"><div><h3>Bill history</h3><p>Submission, payer responses, follow-up, and payments.</p></div><span>{{ data.activity.length }}</span></div><ul class=\"timeline\">@for (event of data.activity; track event.id) { <li><i></i><div><strong>{{ activityLabel(event.type) }}</strong><p>{{ event.description }}</p><small>{{ event.createdAt | date:'medium' }}</small></div></li> }</ul></section>\n\n @if (notice) { <p class=\"notice\">{{ notice }}</p> }\n <div class=\"actions\">@for (action of data.lifecycle.actions; track action.id) { @if (action.id !== 'view_eor' || data.eors.length) { <button type=\"button\" [class.primary]=\"action.primary\" [disabled]=\"!action.enabled || store.mutating()\" (click)=\"beginAction(action.id, data)\">{{ action.label }}</button> } }</div>\n\n @if (panel === 'payment') { <form class=\"card action-form\" (submit)=\"$event.preventDefault(); postPayment()\"><h3>Post payment</h3><label>Amount<input required type=\"number\" min=\"0.01\" step=\"0.01\" [(ngModel)]=\"payment.amount\" name=\"amount\"></label><label>Method<select [(ngModel)]=\"payment.method\" name=\"method\"><option value=\"check\">Check</option><option value=\"eft\">EFT</option></select></label><label>Deposit date<input required type=\"date\" [(ngModel)]=\"payment.depositDate\" name=\"depositDate\"></label><div><button type=\"button\" (click)=\"panel=''\">Cancel</button><button class=\"primary\" type=\"submit\">Post payment</button></div></form> }\n @if (panel === 'review') { <form class=\"card action-form\" (submit)=\"$event.preventDefault(); submitReview()\"><h3>Submit Second Bill Review</h3><label>Reason<textarea required [(ngModel)]=\"review.reason\" name=\"reason\"></textarea></label><label>Payer claim control number<input required [(ngModel)]=\"review.payerClaimControlNumber\" name=\"control\"></label><label>Disputed amount<input type=\"number\" min=\"0\" step=\"0.01\" [(ngModel)]=\"review.disputedAmount\" name=\"disputed\"></label><div><button type=\"button\" (click)=\"panel=''\">Cancel</button><button class=\"primary\" type=\"submit\">Submit review</button></div></form> }\n @if (panel === 'close') { <form class=\"card action-form\" (submit)=\"$event.preventDefault(); closeBill()\"><h3>Close bill</h3><label>Reason<textarea required [(ngModel)]=\"closeReason\" name=\"closeReason\"></textarea></label><div><button type=\"button\" (click)=\"panel=''\">Cancel</button><button class=\"primary\" type=\"submit\">Close bill</button></div></form> }\n }\n </section>\n `,\n styles: [`\n :host{display:block}.mb{font-family:var(--font);color:var(--t);background:var(--bg);padding:20px}.summary,.card,.columns{max-width:1120px;margin:0 auto 16px}.summary{display:flex;justify-content:space-between;align-items:end}.summary h2{margin:4px 0}.summary p,.muted{color:var(--m)}.eyebrow,dt{font-size:12px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--m)}.money{text-align:right}.money span{display:block;font-size:28px;font-weight:800}.money small{color:var(--m)}.card{background:var(--s);border:1px solid var(--b);border-radius:var(--r);padding:20px}.card-title{display:flex;justify-content:space-between;gap:20px}.card-title h3{margin:0}.card-title p{margin:5px 0;color:var(--m)}.progress ol{display:flex;list-style:none;padding:0;margin:0}.progress li{flex:1;text-align:center;position:relative;color:var(--m)}.progress li:before{content:\"\";position:absolute;top:16px;left:0;right:0;border-top:2px solid var(--b)}.progress li:first-child:before{left:50%}.progress li:last-child:before{right:50%}.progress b{position:relative;z-index:1;display:grid;place-items:center;width:32px;height:32px;margin:auto;border:2px solid var(--b);border-radius:50%;background:var(--s)}.progress .complete b,.progress .current b{border-color:var(--a);background:var(--a);color:var(--ac)}.progress span{display:block;margin-top:8px;font-size:12px;font-weight:700}.snapshot dl,.columns dl{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}.snapshot dd,.columns dd{font-weight:700;margin:6px 0}.columns{display:grid;grid-template-columns:1fr 1fr;gap:16px}.columns .card{margin:0}.rows,.timeline{list-style:none;margin:12px 0 0;padding:0}.rows li{display:flex;justify-content:space-between;align-items:center;padding:12px 0;border-top:1px solid var(--b)}.rows small{display:block;color:var(--m);margin-top:3px}.timeline li{display:flex;gap:14px;padding:10px 0}.timeline i{width:10px;height:10px;margin-top:5px;border:3px solid var(--a);border-radius:50%}.timeline p{margin:4px 0}.timeline small{color:var(--m)}button,input,select,textarea{font:inherit;border:1px solid var(--b);border-radius:var(--cr);padding:9px 12px;background:var(--s);color:var(--t)}button{cursor:pointer;font-weight:700}.primary{background:var(--a);border-color:var(--a);color:var(--ac)}.actions{max-width:1120px;margin:0 auto;display:flex;justify-content:flex-end;gap:10px}.action-form{display:grid;gap:12px}.action-form label{display:grid;gap:5px;font-weight:700}.action-form div{display:flex;justify-content:flex-end;gap:10px}.state{max-width:720px;margin:auto;padding:32px;text-align:center}.state span{display:block;margin:8px}.error{color:#9b1c1c}.notice{max-width:1120px;margin:0 auto 12px;color:var(--m)}@media(max-width:760px){.mb{padding:12px}.summary,.columns{display:block}.money{text-align:left;margin-top:12px}.columns .card{margin-bottom:12px}.snapshot dl,.columns dl{grid-template-columns:1fr 1fr}.progress span{font-size:10px}.card{padding:15px}}\n `],\n})\nexport class MindBillBillLifecycleComponent implements OnChanges, OnDestroy {\n @Input() billId = \"\";\n @Input() sessionEndpoint = \"/api/mindbill/session\";\n @Input() apiBaseUrl = \"https://app.mindbill.org\";\n @Input() getSession?: BillLifecycleSessionProvider;\n @Input() refreshInterval = 60_000;\n @Input() appearance: MindBillAngularAppearance = { preset: \"mindbill\" };\n @Output() billingError = new EventEmitter<Error>();\n\n readonly store = new MindBillLifecycleStore();\n readonly lifecycleStages = [\n { id: \"submitted\", label: \"Submitted\" }, { id: \"accepted\", label: \"Accepted\" },\n { id: \"response\", label: \"Payer response\" }, { id: \"follow_up\", label: \"Follow-up\" },\n { id: \"closed\", label: \"Closed\" },\n ];\n panel = \"\";\n notice = \"\";\n closeReason = \"\";\n payment = { amount: 0, method: \"check\" as \"check\" | \"eft\", depositDate: new Date().toISOString().slice(0, 10) };\n review = { reason: \"\", payerClaimControlNumber: \"\", disputedAmount: 0 };\n\n constructor() { effect(() => { const error = this.store.error(); if (error) this.billingError.emit(error); }); }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes[\"billId\"] || changes[\"sessionEndpoint\"] || changes[\"apiBaseUrl\"] || changes[\"getSession\"]) {\n if (!this.billId.trim()) { this.store.disconnect(); return; }\n this.store.connect({ billId: this.billId, sessionEndpoint: this.sessionEndpoint, apiBaseUrl: this.apiBaseUrl, ...(this.getSession ? { getSession: this.getSession } : {}) }, this.refreshInterval);\n }\n }\n ngOnDestroy(): void { this.store.disconnect(); }\n\n get themeStyle(): Record<string, string> {\n const base = THEMES[this.appearance.preset ?? \"mindbill\"];\n return { \"--a\": this.appearance.accentColor ?? base.accentColor, \"--ac\": this.appearance.accentTextColor ?? base.accentTextColor, \"--bg\": this.appearance.backgroundColor ?? base.backgroundColor, \"--s\": this.appearance.surfaceColor ?? base.surfaceColor, \"--t\": this.appearance.textColor ?? base.textColor, \"--m\": this.appearance.mutedColor ?? base.mutedColor, \"--b\": this.appearance.borderColor ?? base.borderColor, \"--r\": this.appearance.borderRadius ?? base.borderRadius, \"--cr\": this.appearance.controlRadius ?? base.controlRadius, \"--font\": this.appearance.fontFamily ?? base.fontFamily };\n }\n stateLabel(data: BillLifecycleData): string { return data.lifecycle.state.replace(/_/g, \" \").replace(/\\b\\w/g, (value) => value.toUpperCase()); }\n lifecycleDetail(data: BillLifecycleData): string { return data.lifecycle.submittedAt ? `Submitted ${new Date(data.lifecycle.submittedAt).toLocaleDateString()}${data.lifecycle.agingDays != null ? ` · ${data.lifecycle.agingDays} days old` : \"\"}` : \"Submitted bill\"; }\n currentStageIndex(data: BillLifecycleData): number { const value = data.lifecycle.state.toLowerCase(); if (value.includes(\"closed\") || value.includes(\"written_off\")) return 4; if (value.includes(\"second_review\") || value.includes(\"ibr\") || value.includes(\"lien\") || value.includes(\"appeal\")) return 3; if (value.includes(\"processed\") || value.includes(\"paid\") || value.includes(\"denied\") || value.includes(\"rejected\") || value.includes(\"response\")) return 2; if (value.includes(\"accepted\")) return 1; return 0; }\n activityLabel(type: string): string { return type.replace(/[._-]+/g, \" \").replace(/\\b\\w/g, (value) => value.toUpperCase()); }\n payerContact(data: BillLifecycleData): string { const contacts = data.delivery.contacts; return contacts.adjusterName || contacts.adjusterPhone || contacts.adjusterEmail || contacts.claimsEmail || contacts.faxNumber || contacts.mailingAddress || \"No payer contact details are available.\"; }\n beginAction(action: string, data: BillLifecycleData): void { if (action === \"post_payment\") this.panel = \"payment\"; else if (action === \"second_review\" || action === \"independent_bill_review\") this.panel = \"review\"; else if (action === \"close\") this.panel = \"close\"; else if (action === \"view_eor\" && data.eors[0]) void this.openEor(data.eors[0].id, data.eors[0].filename); }\n async openAttachment(id: string, filename: string): Promise<void> { this.openBlob(await this.store.getAttachment(id), filename); }\n async openEor(id: string, filename: string): Promise<void> { this.openBlob(await this.store.getEor(id), filename); }\n async postPayment(): Promise<void> { await this.store.postPayment(this.payment); this.panel = \"\"; this.notice = \"Payment posted.\"; }\n async submitReview(): Promise<void> { await this.store.submitSecondReview({ ...this.review, disputedAmount: this.review.disputedAmount > 0 ? this.review.disputedAmount : undefined, attachmentIds: this.store.data()?.bill.attachments.map((document) => document.id) ?? [], route: \"ebill\" }); this.panel = \"\"; this.notice = \"Second Review submitted.\"; }\n async closeBill(): Promise<void> { if (!this.closeReason.trim()) return; await this.store.closeBill({ reason: this.closeReason }); this.panel = \"\"; this.notice = \"Bill closed.\"; }\n private openBlob(blob: Blob, filename: string): void { const url = URL.createObjectURL(blob); const link = document.createElement(\"a\"); link.href = url; link.target = \"_blank\"; link.rel = \"noopener\"; link.download = filename; link.click(); setTimeout(() => URL.revokeObjectURL(url), 60_000); }\n}\n","export type ProcedureLine = {\n id?: string;\n code: string;\n modifiers: string[];\n units: number;\n charge: number;\n feeSchedule?: number;\n serviceDate?: string | null;\n serviceDateEnd?: string | null;\n diagnosisPointers?: number[];\n};\n\nconst EMPTY_PROCEDURE_LINE: ProcedureLine = {\n code: \"\",\n modifiers: [],\n units: 1,\n charge: 0,\n};\n\nexport function isEmptyProcedureLine(line: ProcedureLine): boolean {\n return !line.code.trim()\n && line.modifiers.length === 0\n && line.units === 1\n && !line.serviceDate\n && !line.serviceDateEnd\n && !(line.diagnosisPointers?.length)\n && !line.charge;\n}\n\n/** Keeps completed/partial lines plus one keyboard-ready empty row. */\nexport function ensureTrailingProcedureLine(\n lines: readonly ProcedureLine[],\n): ProcedureLine[] {\n const entered = lines\n .filter((line) => !isEmptyProcedureLine(line))\n .map((line) => ({ ...line, modifiers: [...line.modifiers] }));\n\n return entered.length < 50\n ? [...entered, { ...EMPTY_PROCEDURE_LINE, modifiers: [] }]\n : entered;\n}\n","import { CommonModule } from \"@angular/common\";\nimport { Component, Directive, EventEmitter, Input, Output } from \"@angular/core\";\nimport { FormsModule } from \"@angular/forms\";\nimport type { MindBillAngularAppearance } from \"./bill-lifecycle.component\";\n\nexport type MindBillDashboardBill = {\n id: string;\n billNumber?: string | number;\n externalId?: string;\n patientName: string;\n claimNumber?: string;\n payerName?: string;\n state: string;\n submittedAt?: string;\n updatedAt?: string;\n agingDays?: number;\n totalCharge: number;\n totalPaid: number;\n balanceDue: number;\n href?: string;\n workItemLabel?: string;\n};\n\nexport type MindBillAgingBucketId = \"current\" | \"31-60\" | \"61-90\" | \"91+\";\nexport type MindBillAgingBucket = { id: MindBillAgingBucketId; label: string; count: number; balance: number };\nexport type MindBillDashboardSummary = {\n totalBilled: number;\n totalPaid: number;\n outstanding: number;\n openCount: number;\n bills: MindBillDashboardBill[];\n aging: MindBillAgingBucket[];\n};\nexport type MindBillReportDimension = \"status\" | \"payer\" | \"aging\";\nexport type MindBillReportRow = { key: string; label: string; billCount: number; totalBilled: number; totalPaid: number; balanceDue: number };\n\nconst THEME: Record<string, Record<string, string>> = {\n mindbill: { a: \"#238dbd\", ac: \"#fff\", bg: \"#f3f8fa\", s: \"#fff\", t: \"#203743\", m: \"#657982\", b: \"#dbe6ea\", r: \"14px\", cr: \"8px\", font: \"Inter,system-ui,sans-serif\" },\n \"qme-companion\": { a: \"#53b5dc\", ac: \"#173542\", bg: \"#f2f8fb\", s: \"#fff\", t: \"#1d3440\", m: \"#617783\", b: \"#d7e5eb\", r: \"12px\", cr: \"8px\", font: \"Inter,system-ui,sans-serif\" },\n \"orange-bright\": { a: \"#f4510b\", ac: \"#fff\", bg: \"#fffaf6\", s: \"#fffefd\", t: \"#090f1f\", m: \"#626a73\", b: \"#e7e1da\", r: \"16px\", cr: \"10px\", font: \"Inter,system-ui,sans-serif\" },\n \"clinical-blue\": { a: \"#1677ff\", ac: \"#fff\", bg: \"#f5f7fa\", s: \"#fff\", t: \"#1f2d3d\", m: \"#66788a\", b: \"#d9e2ec\", r: \"8px\", cr: \"6px\", font: \"Inter,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif\" },\n};\n\nexport function mindBillAgingDays(bill: MindBillDashboardBill, now = new Date()): number {\n if (bill.agingDays != null) return Math.max(0, Math.floor(bill.agingDays));\n const source = bill.submittedAt ?? bill.updatedAt;\n if (!source) return 0;\n const time = new Date(source).getTime();\n return Number.isFinite(time) ? Math.max(0, Math.floor((now.getTime() - time) / 86_400_000)) : 0;\n}\n\nexport function mindBillAgingBucket(days: number): MindBillAgingBucketId {\n if (days <= 30) return \"current\";\n if (days <= 60) return \"31-60\";\n if (days <= 90) return \"61-90\";\n return \"91+\";\n}\n\nexport function summarizeMindBillDashboard(bills: MindBillDashboardBill[], now = new Date()): MindBillDashboardSummary {\n const aging: MindBillAgingBucket[] = [\n { id: \"current\", label: \"0–30 days\", count: 0, balance: 0 },\n { id: \"31-60\", label: \"31–60 days\", count: 0, balance: 0 },\n { id: \"61-90\", label: \"61–90 days\", count: 0, balance: 0 },\n { id: \"91+\", label: \"91+ days\", count: 0, balance: 0 },\n ];\n for (const bill of bills) {\n const bucket = aging.find((item) => item.id === mindBillAgingBucket(mindBillAgingDays(bill, now)))!;\n bucket.count += 1;\n bucket.balance += bill.balanceDue;\n }\n return {\n totalBilled: bills.reduce((sum, item) => sum + item.totalCharge, 0),\n totalPaid: bills.reduce((sum, item) => sum + item.totalPaid, 0),\n outstanding: bills.reduce((sum, item) => sum + item.balanceDue, 0),\n openCount: bills.filter((item) => !/closed|paid|written.off/i.test(item.state)).length,\n bills,\n aging,\n };\n}\n\nexport function buildMindBillReportRows(bills: MindBillDashboardBill[], dimension: MindBillReportDimension): MindBillReportRow[] {\n const rows = new Map<string, MindBillReportRow>();\n for (const bill of bills) {\n const key = dimension === \"payer\" ? bill.payerName || \"Unassigned payer\" : dimension === \"aging\" ? mindBillAgingBucket(mindBillAgingDays(bill)) : bill.state;\n const label = key.replace(/_/g, \" \").replace(/\\b\\w/g, (value) => value.toUpperCase());\n const row = rows.get(key) ?? { key, label, billCount: 0, totalBilled: 0, totalPaid: 0, balanceDue: 0 };\n row.billCount += 1; row.totalBilled += bill.totalCharge; row.totalPaid += bill.totalPaid; row.balanceDue += bill.balanceDue;\n rows.set(key, row);\n }\n return [...rows.values()].sort((a, b) => b.balanceDue - a.balanceDue || a.label.localeCompare(b.label));\n}\n\nexport function buildMindBillReportCsv(rows: MindBillReportRow[]): string {\n const quote = (value: string | number) => `\"${String(value).replace(/\"/g, '\"\"')}\"`;\n return [\"Group,Bills,Total billed,Total paid,Balance due\", ...rows.map((row) => [row.label, row.billCount, row.totalBilled, row.totalPaid, row.balanceDue].map(quote).join(\",\"))].join(\"\\n\");\n}\n\n@Directive()\nabstract class DashboardBase {\n @Input() appearance: MindBillAngularAppearance = { preset: \"mindbill\" };\n get themeStyle(): Record<string, string> {\n const base = THEME[this.appearance.preset ?? \"mindbill\"] ?? THEME[\"mindbill\"]!;\n return {\n \"--a\": this.appearance.accentColor ?? base[\"a\"]!, \"--ac\": this.appearance.accentTextColor ?? base[\"ac\"]!,\n \"--bg\": this.appearance.backgroundColor ?? base[\"bg\"]!, \"--s\": this.appearance.surfaceColor ?? base[\"s\"]!,\n \"--t\": this.appearance.textColor ?? base[\"t\"]!, \"--m\": this.appearance.mutedColor ?? base[\"m\"]!,\n \"--b\": this.appearance.borderColor ?? base[\"b\"]!, \"--r\": this.appearance.borderRadius ?? base[\"r\"]!,\n \"--cr\": this.appearance.controlRadius ?? base[\"cr\"]!, \"--font\": this.appearance.fontFamily ?? base[\"font\"]!,\n };\n }\n}\n\nconst sharedStyles = `\n :host{display:block}.mbd{font-family:var(--font);color:var(--t)}button,input,select{font:inherit}.card{background:var(--s);border:1px solid var(--b);border-radius:var(--r)}\n .money{font-variant-numeric:tabular-nums}.muted{color:var(--m)}.pill{display:inline-flex;border-radius:999px;background:color-mix(in srgb,var(--a) 12%,var(--s));color:var(--a);font-size:12px;font-weight:750;padding:5px 9px}\n`;\n\n@Component({\n selector: \"mindbill-bill-aging-summary\", standalone: true, imports: [CommonModule],\n template: `<section class=\"mbd aging\" [ngStyle]=\"themeStyle\" aria-label=\"Accounts receivable aging\">@for (bucket of buckets; track bucket.id) { <article class=\"card\"><div><strong>{{ bucket.label }}</strong><span>{{ bucket.count }} bill{{ bucket.count === 1 ? '' : 's' }}</span></div><b class=\"money\">{{ bucket.balance | currency }}</b><i><em [style.width.%]=\"width(bucket.balance)\"></em></i></article> }</section>`,\n styles: [sharedStyles, `.aging{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px}.aging article{padding:16px}.aging article>div{display:flex;justify-content:space-between;gap:8px}.aging span{color:var(--m);font-size:12px}.aging b{display:block;font-size:20px;margin:14px 0 12px}.aging i{display:block;height:5px;border-radius:99px;background:color-mix(in srgb,var(--b) 70%,transparent);overflow:hidden}.aging em{display:block;height:100%;background:var(--a)}@media(max-width:760px){.aging{grid-template-columns:1fr 1fr}}`],\n})\nexport class MindBillBillAgingSummaryComponent extends DashboardBase {\n @Input() buckets: MindBillAgingBucket[] = [];\n width(balance: number): number { const max = Math.max(1, ...this.buckets.map((item) => item.balance)); return Math.max(balance ? 8 : 0, balance / max * 100); }\n}\n\n@Component({\n selector: \"mindbill-bill-list\", standalone: true, imports: [CommonModule],\n template: `<section class=\"mbd list card\" [ngStyle]=\"themeStyle\"><div class=\"head\"><strong>Bill</strong><strong>Payer</strong><strong>Status</strong><strong>Age</strong><strong>Balance</strong></div>@for (bill of bills; track bill.id) { <button type=\"button\" (click)=\"billSelected.emit(bill)\"><span><b>{{ bill.patientName }}</b><small>{{ bill.claimNumber || bill.workItemLabel || bill.externalId || bill.id }}</small></span><span>{{ bill.payerName || '—' }}</span><span><i class=\"pill\">{{ label(bill.state) }}</i></span><span>{{ age(bill) }} days</span><span class=\"money\"><b>{{ bill.balanceDue | currency }}</b><small>{{ bill.totalPaid | currency }} paid</small></span></button> } @empty { <p class=\"empty\">No bills match these filters.</p> }</section>`,\n styles: [sharedStyles, `.list{overflow:hidden}.head,.list button{display:grid;grid-template-columns:1.6fr 1.2fr .85fr .55fr .8fr;gap:18px;align-items:center;text-align:left}.head{padding:11px 16px;background:color-mix(in srgb,var(--bg) 78%,var(--s));color:var(--m);font-size:11px;letter-spacing:.08em;text-transform:uppercase}.list button{width:100%;border:0;border-top:1px solid var(--b);background:var(--s);color:var(--t);padding:15px 16px;cursor:pointer}.list button:hover{background:color-mix(in srgb,var(--a) 5%,var(--s))}.list span,.list small{min-width:0}.list small{display:block;color:var(--m);margin-top:4px}.money{text-align:right}.empty{padding:24px;text-align:center;color:var(--m)}@media(max-width:760px){.head{display:none}.list button{grid-template-columns:1fr auto;gap:10px}.list button>span:nth-child(2){grid-column:1}.list button>span:nth-child(3){grid-row:1;grid-column:2}.list button>span:nth-child(4){grid-column:1}.money{grid-column:2;grid-row:2/4}}`],\n})\nexport class MindBillBillListComponent extends DashboardBase {\n @Input() bills: MindBillDashboardBill[] = [];\n @Output() billSelected = new EventEmitter<MindBillDashboardBill>();\n age(bill: MindBillDashboardBill): number { return mindBillAgingDays(bill); }\n label(value: string): string { return value.replace(/_/g, \" \").replace(/\\b\\w/g, (letter) => letter.toUpperCase()); }\n}\n\n@Component({\n selector: \"mindbill-billing-dashboard\", standalone: true, imports: [CommonModule, FormsModule, MindBillBillAgingSummaryComponent, MindBillBillListComponent],\n template: `<section class=\"mbd dashboard\" [ngStyle]=\"themeStyle\"><header><div><p>Billing operations</p><h2>{{ heading }}</h2><span class=\"muted\">{{ description }}</span></div><button type=\"button\" (click)=\"createBill.emit()\">+ New bill</button></header><div class=\"metrics\"><article class=\"card\"><span>Total billed</span><b>{{ summary.totalBilled | currency }}</b></article><article class=\"card\"><span>Collected</span><b>{{ summary.totalPaid | currency }}</b></article><article class=\"card\"><span>Outstanding</span><b>{{ summary.outstanding | currency }}</b></article><article class=\"card\"><span>Open bills</span><b>{{ summary.openCount }}</b></article></div><mindbill-bill-aging-summary [buckets]=\"summary.aging\" [appearance]=\"appearance\"/><div class=\"filters\"><input [(ngModel)]=\"query\" placeholder=\"Search patient, claim, or payer\" aria-label=\"Search bills\"><select [(ngModel)]=\"state\"><option value=\"\">All statuses</option>@for (option of states; track option) { <option [value]=\"option\">{{ label(option) }}</option> }</select></div><mindbill-bill-list [bills]=\"filteredBills\" [appearance]=\"appearance\" (billSelected)=\"billSelected.emit($event)\"/></section>`,\n styles: [sharedStyles, `.dashboard{display:grid;gap:18px}.dashboard header{display:flex;justify-content:space-between;align-items:end;gap:20px}.dashboard h2{font-size:28px;margin:2px 0 5px}.dashboard header p{margin:0;color:var(--a);font-size:12px;font-weight:800;letter-spacing:.12em;text-transform:uppercase}.dashboard header button{border:0;border-radius:var(--cr);background:var(--a);color:var(--ac);padding:11px 16px;font-weight:750;cursor:pointer}.metrics{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}.metrics article{padding:18px}.metrics span{display:block;color:var(--m);font-size:12px}.metrics b{display:block;margin-top:8px;font-size:24px}.filters{display:grid;grid-template-columns:1fr 190px;gap:10px}.filters input,.filters select{border:1px solid var(--b);border-radius:var(--cr);background:var(--s);color:var(--t);padding:11px 13px}@media(max-width:760px){.dashboard header{align-items:start}.metrics{grid-template-columns:1fr 1fr}.filters{grid-template-columns:1fr}}`],\n})\nexport class MindBillBillingDashboardComponent extends DashboardBase {\n @Input() bills: MindBillDashboardBill[] = [];\n @Input() heading = \"Billing dashboard\";\n @Input() description = \"Track every submitted bill from payer acceptance through payment.\";\n @Output() billSelected = new EventEmitter<MindBillDashboardBill>();\n @Output() createBill = new EventEmitter<void>();\n query = \"\"; state = \"\";\n get summary(): MindBillDashboardSummary { return summarizeMindBillDashboard(this.bills); }\n get states(): string[] { return [...new Set(this.bills.map((bill) => bill.state))].sort(); }\n get filteredBills(): MindBillDashboardBill[] { const query = this.query.trim().toLowerCase(); return this.bills.filter((bill) => (!this.state || bill.state === this.state) && (!query || [bill.patientName, bill.claimNumber, bill.payerName, bill.externalId, bill.billNumber].some((value) => String(value ?? \"\").toLowerCase().includes(query)))); }\n label(value: string): string { return value.replace(/_/g, \" \").replace(/\\b\\w/g, (letter) => letter.toUpperCase()); }\n}\n\n@Component({\n selector: \"mindbill-billing-report\", standalone: true, imports: [CommonModule, FormsModule],\n template: `<section class=\"mbd report card\" [ngStyle]=\"themeStyle\"><header><div><h2>{{ heading }}</h2><p>Operational totals grouped for reconciliation and follow-up.</p></div><div><select [(ngModel)]=\"dimension\"><option value=\"status\">Status</option><option value=\"payer\">Payer</option><option value=\"aging\">Aging</option></select><button type=\"button\" (click)=\"downloadCsv()\">Export CSV</button></div></header><div class=\"thead\"><b>Group</b><b>Bills</b><b>Total billed</b><b>Total paid</b><b>Balance due</b></div>@for (row of rows; track row.key) { <div class=\"row\"><strong>{{ row.label }}</strong><span>{{ row.billCount }}</span><span>{{ row.totalBilled | currency }}</span><span>{{ row.totalPaid | currency }}</span><b>{{ row.balanceDue | currency }}</b></div> }</section>`,\n styles: [sharedStyles, `.report{overflow:hidden}.report header{display:flex;justify-content:space-between;align-items:center;padding:18px}.report h2{margin:0;font-size:22px}.report p{margin:4px 0 0;color:var(--m)}.report header div:last-child{display:flex;gap:8px}.report select,.report button{border:1px solid var(--b);border-radius:var(--cr);background:var(--s);color:var(--t);padding:9px 12px}.report button{background:var(--a);border-color:var(--a);color:var(--ac);font-weight:750;cursor:pointer}.thead,.row{display:grid;grid-template-columns:1.5fr .5fr 1fr 1fr 1fr;gap:14px;padding:12px 18px;border-top:1px solid var(--b);align-items:center}.thead{background:color-mix(in srgb,var(--bg) 78%,var(--s));color:var(--m);font-size:11px;text-transform:uppercase}.row span,.row b:not(:first-child){text-align:right;font-variant-numeric:tabular-nums}@media(max-width:700px){.report header{align-items:flex-start}.thead{display:none}.row{grid-template-columns:1fr 1fr}.row>*:nth-child(n+2){text-align:right}.row strong{grid-column:1}.row span:nth-child(2){grid-column:2}.row span:nth-child(3)::before{content:'Billed ';color:var(--m)}.row span:nth-child(4)::before{content:'Paid ';color:var(--m)}.row b::before{content:'Due ';color:var(--m)}}`],\n})\nexport class MindBillBillingReportComponent extends DashboardBase {\n @Input() bills: MindBillDashboardBill[] = [];\n @Input() heading = \"Billing report\";\n dimension: MindBillReportDimension = \"status\";\n get rows(): MindBillReportRow[] { return buildMindBillReportRows(this.bills, this.dimension); }\n downloadCsv(): void { const blob = new Blob([buildMindBillReportCsv(this.rows)], { type: \"text/csv;charset=utf-8\" }); const url = URL.createObjectURL(blob); const link = document.createElement(\"a\"); link.href = url; link.download = `mindbill-${this.dimension}-report.csv`; link.click(); setTimeout(() => URL.revokeObjectURL(url), 1000); }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mindbill/angular",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Native Angular components for
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "Native Angular components for bill submission, lifecycle, dashboards, aging, lists, and reporting",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"peerDependencies": {
|
|
7
7
|
"@angular/common": ">=18 <22",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"rxjs": ">=7.8 <9"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@mindbill/browser": "^0.
|
|
13
|
+
"@mindbill/browser": "^0.12.0",
|
|
14
14
|
"tslib": "^2.8.1"
|
|
15
15
|
},
|
|
16
16
|
"keywords": [
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
2
|
import { OnChanges, OnDestroy, EventEmitter, SimpleChanges } from '@angular/core';
|
|
3
3
|
import { BillLifecycleClientOptions, BillLifecycleData, CloseBillInput, PostBillPaymentInput, SubmitSecondReviewInput, BillLifecycleSessionProvider } from '@mindbill/browser';
|
|
4
4
|
export { BillLifecycleAction, BillLifecycleActionId, BillLifecycleClient, BillLifecycleClientOptions, BillLifecycleData, BillLifecycleSession, BillLifecycleSessionProvider, BillReviewData, BillSubmissionRoute, CloseBillInput, PostBillPaymentInput, SubmitSecondReviewInput } from '@mindbill/browser';
|
|
5
5
|
|
|
6
6
|
declare class MindBillLifecycleStore {
|
|
7
|
-
readonly billId:
|
|
8
|
-
readonly data:
|
|
9
|
-
readonly error:
|
|
10
|
-
readonly loading:
|
|
11
|
-
readonly mutating:
|
|
12
|
-
readonly ready:
|
|
7
|
+
readonly billId: i0.WritableSignal<string>;
|
|
8
|
+
readonly data: i0.WritableSignal<any>;
|
|
9
|
+
readonly error: i0.WritableSignal<Error>;
|
|
10
|
+
readonly loading: i0.WritableSignal<boolean>;
|
|
11
|
+
readonly mutating: i0.WritableSignal<boolean>;
|
|
12
|
+
readonly ready: i0.Signal<boolean>;
|
|
13
13
|
private client;
|
|
14
14
|
private refreshTimer;
|
|
15
15
|
connect(options: BillLifecycleClientOptions, refreshInterval?: number): void;
|
|
@@ -81,8 +81,8 @@ declare class MindBillBillLifecycleComponent implements OnChanges, OnDestroy {
|
|
|
81
81
|
submitReview(): Promise<void>;
|
|
82
82
|
closeBill(): Promise<void>;
|
|
83
83
|
private openBlob;
|
|
84
|
-
static ɵfac:
|
|
85
|
-
static ɵcmp:
|
|
84
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<MindBillBillLifecycleComponent, never>;
|
|
85
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<MindBillBillLifecycleComponent, "mindbill-bill-lifecycle", never, { "billId": { "alias": "billId"; "required": false; }; "sessionEndpoint": { "alias": "sessionEndpoint"; "required": false; }; "apiBaseUrl": { "alias": "apiBaseUrl"; "required": false; }; "getSession": { "alias": "getSession"; "required": false; }; "refreshInterval": { "alias": "refreshInterval"; "required": false; }; "appearance": { "alias": "appearance"; "required": false; }; }, { "billingError": "billingError"; }, never, never, true, never>;
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
type ProcedureLine = {
|
|
@@ -100,5 +100,96 @@ declare function isEmptyProcedureLine(line: ProcedureLine): boolean;
|
|
|
100
100
|
/** Keeps completed/partial lines plus one keyboard-ready empty row. */
|
|
101
101
|
declare function ensureTrailingProcedureLine(lines: readonly ProcedureLine[]): ProcedureLine[];
|
|
102
102
|
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
type MindBillDashboardBill = {
|
|
104
|
+
id: string;
|
|
105
|
+
billNumber?: string | number;
|
|
106
|
+
externalId?: string;
|
|
107
|
+
patientName: string;
|
|
108
|
+
claimNumber?: string;
|
|
109
|
+
payerName?: string;
|
|
110
|
+
state: string;
|
|
111
|
+
submittedAt?: string;
|
|
112
|
+
updatedAt?: string;
|
|
113
|
+
agingDays?: number;
|
|
114
|
+
totalCharge: number;
|
|
115
|
+
totalPaid: number;
|
|
116
|
+
balanceDue: number;
|
|
117
|
+
href?: string;
|
|
118
|
+
workItemLabel?: string;
|
|
119
|
+
};
|
|
120
|
+
type MindBillAgingBucketId = "current" | "31-60" | "61-90" | "91+";
|
|
121
|
+
type MindBillAgingBucket = {
|
|
122
|
+
id: MindBillAgingBucketId;
|
|
123
|
+
label: string;
|
|
124
|
+
count: number;
|
|
125
|
+
balance: number;
|
|
126
|
+
};
|
|
127
|
+
type MindBillDashboardSummary = {
|
|
128
|
+
totalBilled: number;
|
|
129
|
+
totalPaid: number;
|
|
130
|
+
outstanding: number;
|
|
131
|
+
openCount: number;
|
|
132
|
+
bills: MindBillDashboardBill[];
|
|
133
|
+
aging: MindBillAgingBucket[];
|
|
134
|
+
};
|
|
135
|
+
type MindBillReportDimension = "status" | "payer" | "aging";
|
|
136
|
+
type MindBillReportRow = {
|
|
137
|
+
key: string;
|
|
138
|
+
label: string;
|
|
139
|
+
billCount: number;
|
|
140
|
+
totalBilled: number;
|
|
141
|
+
totalPaid: number;
|
|
142
|
+
balanceDue: number;
|
|
143
|
+
};
|
|
144
|
+
declare function mindBillAgingDays(bill: MindBillDashboardBill, now?: Date): number;
|
|
145
|
+
declare function mindBillAgingBucket(days: number): MindBillAgingBucketId;
|
|
146
|
+
declare function summarizeMindBillDashboard(bills: MindBillDashboardBill[], now?: Date): MindBillDashboardSummary;
|
|
147
|
+
declare function buildMindBillReportRows(bills: MindBillDashboardBill[], dimension: MindBillReportDimension): MindBillReportRow[];
|
|
148
|
+
declare function buildMindBillReportCsv(rows: MindBillReportRow[]): string;
|
|
149
|
+
declare abstract class DashboardBase {
|
|
150
|
+
appearance: MindBillAngularAppearance;
|
|
151
|
+
get themeStyle(): Record<string, string>;
|
|
152
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<DashboardBase, never>;
|
|
153
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<DashboardBase, never, never, { "appearance": { "alias": "appearance"; "required": false; }; }, {}, never, never, true, never>;
|
|
154
|
+
}
|
|
155
|
+
declare class MindBillBillAgingSummaryComponent extends DashboardBase {
|
|
156
|
+
buckets: MindBillAgingBucket[];
|
|
157
|
+
width(balance: number): number;
|
|
158
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<MindBillBillAgingSummaryComponent, never>;
|
|
159
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<MindBillBillAgingSummaryComponent, "mindbill-bill-aging-summary", never, { "buckets": { "alias": "buckets"; "required": false; }; }, {}, never, never, true, never>;
|
|
160
|
+
}
|
|
161
|
+
declare class MindBillBillListComponent extends DashboardBase {
|
|
162
|
+
bills: MindBillDashboardBill[];
|
|
163
|
+
billSelected: EventEmitter<MindBillDashboardBill>;
|
|
164
|
+
age(bill: MindBillDashboardBill): number;
|
|
165
|
+
label(value: string): string;
|
|
166
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<MindBillBillListComponent, never>;
|
|
167
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<MindBillBillListComponent, "mindbill-bill-list", never, { "bills": { "alias": "bills"; "required": false; }; }, { "billSelected": "billSelected"; }, never, never, true, never>;
|
|
168
|
+
}
|
|
169
|
+
declare class MindBillBillingDashboardComponent extends DashboardBase {
|
|
170
|
+
bills: MindBillDashboardBill[];
|
|
171
|
+
heading: string;
|
|
172
|
+
description: string;
|
|
173
|
+
billSelected: EventEmitter<MindBillDashboardBill>;
|
|
174
|
+
createBill: EventEmitter<void>;
|
|
175
|
+
query: string;
|
|
176
|
+
state: string;
|
|
177
|
+
get summary(): MindBillDashboardSummary;
|
|
178
|
+
get states(): string[];
|
|
179
|
+
get filteredBills(): MindBillDashboardBill[];
|
|
180
|
+
label(value: string): string;
|
|
181
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<MindBillBillingDashboardComponent, never>;
|
|
182
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<MindBillBillingDashboardComponent, "mindbill-billing-dashboard", never, { "bills": { "alias": "bills"; "required": false; }; "heading": { "alias": "heading"; "required": false; }; "description": { "alias": "description"; "required": false; }; }, { "billSelected": "billSelected"; "createBill": "createBill"; }, never, never, true, never>;
|
|
183
|
+
}
|
|
184
|
+
declare class MindBillBillingReportComponent extends DashboardBase {
|
|
185
|
+
bills: MindBillDashboardBill[];
|
|
186
|
+
heading: string;
|
|
187
|
+
dimension: MindBillReportDimension;
|
|
188
|
+
get rows(): MindBillReportRow[];
|
|
189
|
+
downloadCsv(): void;
|
|
190
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<MindBillBillingReportComponent, never>;
|
|
191
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<MindBillBillingReportComponent, "mindbill-billing-report", never, { "bills": { "alias": "bills"; "required": false; }; "heading": { "alias": "heading"; "required": false; }; }, {}, never, never, true, never>;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export { MindBillBillAgingSummaryComponent, MindBillBillLifecycleComponent, MindBillBillListComponent, MindBillBillingDashboardComponent, MindBillBillingReportComponent, MindBillLifecycleStore, buildMindBillReportCsv, buildMindBillReportRows, ensureTrailingProcedureLine, isEmptyProcedureLine, mindBillAgingBucket, mindBillAgingDays, summarizeMindBillDashboard };
|
|
195
|
+
export type { MindBillAgingBucket, MindBillAgingBucketId, MindBillAngularAppearance, MindBillAngularThemePreset, MindBillDashboardBill, MindBillDashboardSummary, MindBillReportDimension, MindBillReportRow, ProcedureLine };
|