@mindbill/angular 0.15.0 → 0.16.1

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 CHANGED
@@ -170,7 +170,7 @@ The operations surfaces consume a normalized list of bills, so they can be used
170
170
 
171
171
  `summarizeMindBillDashboard`, `buildMindBillReportRows`, `buildMindBillReportCsv`, `buildMindBillStatusAgingMatrix`, and `buildMindBillStatusAgingCsv` are also exported for custom layouts and server-side reporting.
172
172
 
173
- `mindbill-bill-tasks-dashboard` is the daisyBill-style Bill Tasks worklist: one tone-colored card per task section, rows bucketed by age in days with clickable counts, and a grand-total card. Aggregate your own work items with `buildBillTasksDashboard` from `@mindbill/browser` (types re-exported here) and pass the result as `[data]`:
173
+ `mindbill-bill-tasks-dashboard` is a Bill Tasks worklist: one tone-colored card per task section, rows bucketed by age in days with clickable counts, and a grand-total card. Aggregate your own work items with `buildBillTasksDashboard` from `@mindbill/browser` (types re-exported here) and pass the result as `[data]`:
174
174
 
175
175
  ```html
176
176
  <mindbill-bill-tasks-dashboard
@@ -1,7 +1,7 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { signal, computed, Input, Component, EventEmitter, Output, inject, ChangeDetectorRef, HostListener, effect, Directive } from '@angular/core';
3
- import { createBillLifecycleClient, createBillReferenceClient, createBillSubmissionClient, REPORT_BILL_STATUS_OPTIONS, reportBillStatusContacts, BILL_TASKS_AGING_BUCKETS, createOrganizationClient } from '@mindbill/browser';
4
- export { REPORT_BILL_STATUS_OPTIONS, reportBillStatusContacts } from '@mindbill/browser';
3
+ import { createBillLifecycleClient, createBillReferenceClient, defaultBillReviewPayerOption, createBillSubmissionClient, REPORT_BILL_STATUS_OPTIONS, reportBillStatusContacts, BILL_TASKS_AGING_BUCKETS, createOrganizationClient } from '@mindbill/browser';
4
+ export { REPORT_BILL_STATUS_OPTIONS, defaultBillReviewPayerOption, reportBillStatusContacts } from '@mindbill/browser';
5
5
  import * as i1 from '@angular/common';
6
6
  import { CommonModule } from '@angular/common';
7
7
  import * as i2 from '@angular/forms';
@@ -583,6 +583,9 @@ class MindBillBillSubmissionComponent {
583
583
  payerQuery = "";
584
584
  payerResults = [];
585
585
  payerBusy = false;
586
+ /** Payer (subpayor) choices for the selected claims administrator. */
587
+ subpayorOptions = [];
588
+ payerSelectionRequired = false;
586
589
  diagnosisQuery = "";
587
590
  diagnosisResults = [];
588
591
  diagnosisOffset = 0;
@@ -611,6 +614,8 @@ class MindBillBillSubmissionComponent {
611
614
  this.bill.serviceLines = [{ code: "", units: 1 }];
612
615
  this.ensureTrailingLine();
613
616
  this.payerQuery = this.bill.claim.claimsAdministrator.name ?? "";
617
+ this.subpayorOptions = [];
618
+ this.payerSelectionRequired = false;
614
619
  }
615
620
  if (changes["attachments"])
616
621
  this.workingAttachments = this.attachments.map((item) => ({ ...item }));
@@ -696,10 +701,36 @@ class MindBillBillSubmissionComponent {
696
701
  }, 180);
697
702
  }
698
703
  selectPayer(payer) {
699
- this.bill.claim.claimsAdministrator = { id: payer.id, name: payer.name };
704
+ this.payerSelectionRequired = payer.payerSelectionRequired === true;
705
+ this.subpayorOptions = this.payerSelectionRequired
706
+ ? (payer.payers ?? []).map((option) => ({ ...option }))
707
+ : [];
708
+ const preselected = defaultBillReviewPayerOption(payer);
709
+ this.bill.claim.claimsAdministrator = {
710
+ id: payer.id,
711
+ name: payer.name,
712
+ ...(preselected ? { payerId: preselected.id } : {}),
713
+ };
700
714
  this.payerQuery = payer.name;
701
715
  this.payerResults = [];
702
716
  this.invalidFields.delete("claim.claimsAdministrator");
717
+ this.invalidFields.delete("claim.claimsAdministrator.payerId");
718
+ this.billChange.emit(this.bill);
719
+ }
720
+ get subpayorComboOptions() {
721
+ return this.subpayorOptions.map((option) => ({
722
+ id: option.id,
723
+ label: option.label,
724
+ ...(option.default ? { detail: "Default" } : {}),
725
+ }));
726
+ }
727
+ get subpayorLabel() {
728
+ const payerId = this.bill.claim?.claimsAdministrator?.payerId;
729
+ return this.subpayorOptions.find((option) => option.id === payerId)?.label ?? "";
730
+ }
731
+ selectSubpayor(option) {
732
+ this.bill.claim.claimsAdministrator = { ...this.bill.claim.claimsAdministrator, payerId: option.id };
733
+ this.invalidFields.delete("claim.claimsAdministrator.payerId");
703
734
  this.billChange.emit(this.bill);
704
735
  }
705
736
  searchDiagnoses(reset) {
@@ -861,7 +892,9 @@ class MindBillBillSubmissionComponent {
861
892
  ["patient.firstName", this.bill.patient.firstName], ["patient.lastName", this.bill.patient.lastName], ["patient.dateOfBirth", parseMindBillSubmissionDate(this.bill.patient.dateOfBirth ?? "")],
862
893
  ["patient.address.line1", this.bill.patient.address.line1], ["patient.address.city", this.bill.patient.address.city], ["patient.address.state", this.bill.patient.address.state], ["patient.address.postalCode", this.bill.patient.address.postalCode],
863
894
  ["service.date", parseMindBillSubmissionDate(this.bill.service.date ?? "")], ["claim.dateOfInjury", parseMindBillSubmissionDate(this.bill.claim.dateOfInjury ?? "")], ["claim.claimNumber", this.bill.claim.claimNumber], ["claim.employer", this.bill.claim.employer],
864
- ["claim.claimsAdministrator", this.bill.claim.claimsAdministrator.id], ["diagnoses", this.bill.diagnoses.length],
895
+ ["claim.claimsAdministrator", this.bill.claim.claimsAdministrator.id],
896
+ ["claim.claimsAdministrator.payerId", !this.payerSelectionRequired || this.bill.claim.claimsAdministrator.payerId],
897
+ ["diagnoses", this.bill.diagnoses.length],
865
898
  ["billingProvider.name", this.bill.billingProvider.name], ["billingProvider.taxId", this.bill.billingProvider.taxId], ["billingProvider.npi", this.bill.billingProvider.npi], ["billingProvider.phone", this.bill.billingProvider.phone],
866
899
  ["billingProvider.address.line1", this.bill.billingProvider.address.line1], ["billingProvider.address.city", this.bill.billingProvider.address.city], ["billingProvider.address.state", this.bill.billingProvider.address.state], ["billingProvider.address.postalCode", this.bill.billingProvider.address.postalCode],
867
900
  ["renderingProvider.name", this.bill.renderingProvider.name], ["renderingProvider.npi", this.bill.renderingProvider.npi], ["renderingProvider.taxonomy", this.bill.renderingProvider.taxonomy],
@@ -962,6 +995,13 @@ class MindBillBillSubmissionComponent {
962
995
  @if (payerResults.length) { <div class="options">@for (payer of payerResults; track payer.id) { <button type="button" (click)="selectPayer(payer)"><strong>{{ payer.name }}</strong><span>{{ payer.hasElectronic ? 'Electronic routing' : 'Paper / fax' }}@if (payer.confidence) { · {{ payer.confidence }} match }</span></button> }</div> }
963
996
  @if (bill.claim.claimsAdministrator.id) { <small class="selected">✓ Routed to {{ bill.claim.claimsAdministrator.name }}</small> }
964
997
  </div>
998
+ @if (payerSelectionRequired && subpayorOptions.length) {
999
+ <div class="wide lookup" [class.invalid]="bad('claim.claimsAdministrator.payerId')"><label>Payer <b>*</b></label>
1000
+ <mindbill-combo-box ariaLabel="Payer" [value]="subpayorLabel" [invalid]="bad('claim.claimsAdministrator.payerId')" [preserveValueOnOpen]="true" placeholder="Select the payer for this claims administrator…" [options]="subpayorComboOptions" (selected)="selectSubpayor($event)"/>
1001
+ @if (subpayorLabel) { <small class="selected">✓ Payer set: {{ subpayorLabel }}</small> }
1002
+ @else { <small>This claims administrator routes bills per payer. Choose the payer that should receive this bill.</small> }
1003
+ </div>
1004
+ }
965
1005
  <label class="wide">Injury description (optional)<input name="description" [(ngModel)]="bill.claim.description"></label>
966
1006
  <div class="wide diagnosis" [class.invalid]="bad('diagnoses')"><label>Diagnosis codes (ICD-10) <b>*</b></label>
967
1007
  <div class="quick">@for (item of quickDiagnoses; track item.code) { <button type="button" [class.on]="hasDiagnosis(item.code)" (click)="toggleDiagnosis(item)">{{ hasDiagnosis(item.code) ? '✓' : '+' }} {{ item.label }}</button> }</div>
@@ -1064,6 +1104,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
1064
1104
  @if (payerResults.length) { <div class="options">@for (payer of payerResults; track payer.id) { <button type="button" (click)="selectPayer(payer)"><strong>{{ payer.name }}</strong><span>{{ payer.hasElectronic ? 'Electronic routing' : 'Paper / fax' }}@if (payer.confidence) { · {{ payer.confidence }} match }</span></button> }</div> }
1065
1105
  @if (bill.claim.claimsAdministrator.id) { <small class="selected">✓ Routed to {{ bill.claim.claimsAdministrator.name }}</small> }
1066
1106
  </div>
1107
+ @if (payerSelectionRequired && subpayorOptions.length) {
1108
+ <div class="wide lookup" [class.invalid]="bad('claim.claimsAdministrator.payerId')"><label>Payer <b>*</b></label>
1109
+ <mindbill-combo-box ariaLabel="Payer" [value]="subpayorLabel" [invalid]="bad('claim.claimsAdministrator.payerId')" [preserveValueOnOpen]="true" placeholder="Select the payer for this claims administrator…" [options]="subpayorComboOptions" (selected)="selectSubpayor($event)"/>
1110
+ @if (subpayorLabel) { <small class="selected">✓ Payer set: {{ subpayorLabel }}</small> }
1111
+ @else { <small>This claims administrator routes bills per payer. Choose the payer that should receive this bill.</small> }
1112
+ </div>
1113
+ }
1067
1114
  <label class="wide">Injury description (optional)<input name="description" [(ngModel)]="bill.claim.description"></label>
1068
1115
  <div class="wide diagnosis" [class.invalid]="bad('diagnoses')"><label>Diagnosis codes (ICD-10) <b>*</b></label>
1069
1116
  <div class="quick">@for (item of quickDiagnoses; track item.code) { <button type="button" [class.on]="hasDiagnosis(item.code)" (click)="toggleDiagnosis(item)">{{ hasDiagnosis(item.code) ? '✓' : '+' }} {{ item.label }}</button> }</div>
@@ -1438,7 +1485,7 @@ class MindBillBillLifecycleComponent {
1438
1485
 
1439
1486
  <section class="card"><div class="card-title"><div><h3>Bill history</h3><p>Submissions, payer responses, follow-up, and payments.</p></div><span>{{ data.history?.length ?? data.activity.length }}</span></div>
1440
1487
  @if (data.history?.length) {
1441
- <!-- daisyBill-style Date/Action/User/Details table: submissions are pale-blue
1488
+ <!-- Date/Action/User/Details table: submissions are pale-blue
1442
1489
  expandable rows (documents + compliance due dates), notes pale-yellow,
1443
1490
  277 responses expand into decoded status-code sentences. Rows arrive
1444
1491
  pre-worded from the MindBill API (BillLifecycleData.history). -->
@@ -1611,7 +1658,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImpo
1611
1658
 
1612
1659
  <section class="card"><div class="card-title"><div><h3>Bill history</h3><p>Submissions, payer responses, follow-up, and payments.</p></div><span>{{ data.history?.length ?? data.activity.length }}</span></div>
1613
1660
  @if (data.history?.length) {
1614
- <!-- daisyBill-style Date/Action/User/Details table: submissions are pale-blue
1661
+ <!-- Date/Action/User/Details table: submissions are pale-blue
1615
1662
  expandable rows (documents + compliance due dates), notes pale-yellow,
1616
1663
  277 responses expand into decoded status-code sentences. Rows arrive
1617
1664
  pre-worded from the MindBill API (BillLifecycleData.history). -->
@@ -2203,7 +2250,7 @@ function mindBillBillTasksCell(section, row, bucketIndex, buckets) {
2203
2250
  };
2204
2251
  }
2205
2252
 
2206
- // daisyBill-style "Bill Tasks" dashboard: one rounded, tone-colored card per
2253
+ // "Bill Tasks" dashboard: one rounded, tone-colored card per
2207
2254
  // task section, rows bucketed by age in days with colored bucket header pills,
2208
2255
  // per-cell click-through counts, and a closing grand-total card. The pure
2209
2256
  // aggregation lives in @mindbill/browser (buildBillTasksDashboard) so React