@mindbill/react 0.77.63 → 0.77.64
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/dist/index.d.ts +6 -1
- package/dist/index.js +25 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -439,6 +439,11 @@ type BillSubmissionFormProps = {
|
|
|
439
439
|
procedureOptions?: BillSubmissionProcedureOption[];
|
|
440
440
|
/** Extend the existing procedure picker with treatment codes and authoritative fee quotes. */
|
|
441
441
|
treatmentBilling?: boolean;
|
|
442
|
+
/** Lines added when a procedure is chosen, keyed by that procedure's code. A code already on the bill is not added again. */
|
|
443
|
+
companionLines?: Readonly<Record<string, readonly {
|
|
444
|
+
code: string;
|
|
445
|
+
units?: number;
|
|
446
|
+
}[]>>;
|
|
442
447
|
/** Opt in to editable treatment billed charges; fee quotes remain separate estimates. */
|
|
443
448
|
editableTreatmentCharges?: boolean;
|
|
444
449
|
onSearchProcedureCodes?: (input?: BillProcedureCodeSearchInput) => Promise<BillProcedureCodePage>;
|
|
@@ -524,7 +529,7 @@ declare function BillSubmissionProvidersSection(): ReactElement;
|
|
|
524
529
|
declare function BillSubmissionServiceLinesSection(): ReactElement;
|
|
525
530
|
declare function BillSubmissionAttachmentsSection(): ReactElement;
|
|
526
531
|
declare function BillSubmissionActions(): ReactElement;
|
|
527
|
-
declare function BillSubmissionForm({ initialBill, idempotencyKey, attachments, onSubmit, onSubmitted, getSession, sessionEndpoint, apiBaseUrl, profileOptions, billingSettings, reportAutofill, profileDisplay, fetch: fetchOverride, onListMedicalProviderNetworks, onListClaimsAdministrators, onSearchClaimsAdministrators, onGetClaimsAdministratorDirectory, claimsAdministratorSources, claimsAdministratorHint, diagnosisOptions, onSearchDiagnoses, onLookupPostalCode, procedureOptions, treatmentBilling, editableTreatmentCharges, onSearchProcedureCodes, onQuoteFee, modifierOptions, taxonomyOptions, deliveryRoutePicker, deliveryRouteDialogTitle, attachmentReportTypeMode, attachmentReportTypes, defaultAttachmentReportType, appearance, className, style, disabled, submitLabel, heading, description, attentionFields, attentionMessage, children, }: BillSubmissionFormProps): ReactElement;
|
|
532
|
+
declare function BillSubmissionForm({ initialBill, idempotencyKey, attachments, onSubmit, onSubmitted, getSession, sessionEndpoint, apiBaseUrl, profileOptions, billingSettings, reportAutofill, profileDisplay, fetch: fetchOverride, onListMedicalProviderNetworks, onListClaimsAdministrators, onSearchClaimsAdministrators, onGetClaimsAdministratorDirectory, claimsAdministratorSources, claimsAdministratorHint, diagnosisOptions, onSearchDiagnoses, onLookupPostalCode, procedureOptions, treatmentBilling, companionLines, editableTreatmentCharges, onSearchProcedureCodes, onQuoteFee, modifierOptions, taxonomyOptions, deliveryRoutePicker, deliveryRouteDialogTitle, attachmentReportTypeMode, attachmentReportTypes, defaultAttachmentReportType, appearance, className, style, disabled, submitLabel, heading, description, attentionFields, attentionMessage, children, }: BillSubmissionFormProps): ReactElement;
|
|
528
533
|
|
|
529
534
|
type BillSubmissionProfileOption<K extends "billingProvider" | "renderingProvider" | "serviceLocation"> = {
|
|
530
535
|
id: string;
|
package/dist/index.js
CHANGED
|
@@ -8220,6 +8220,7 @@ function billSubmissionCalculationContext(code, placeOfService, details, saved =
|
|
|
8220
8220
|
return context;
|
|
8221
8221
|
}
|
|
8222
8222
|
var isMedicalLegalCode = (code) => /^ML/i.test(code.trim());
|
|
8223
|
+
var billingModeForLines = (lines) => lines.some((line) => isMedicalLegalCode(line.code)) ? "med_legal" : "professional";
|
|
8223
8224
|
function billSubmissionFeeRequest(bill, line, context = line.feeContext ?? {}) {
|
|
8224
8225
|
const dateOfService = parseBillSubmissionDate(line.serviceDate ?? bill.service.date) ?? "";
|
|
8225
8226
|
const sameDayServices = bill.serviceLines.filter((candidate) => candidate.code.trim() && parseBillSubmissionDate(candidate.serviceDate ?? bill.service.date) === dateOfService);
|
|
@@ -8383,6 +8384,19 @@ function blankLine() {
|
|
|
8383
8384
|
function lineHasContent(line) {
|
|
8384
8385
|
return Boolean(line.code.trim() || line.modifiers?.length || line.charge != null || line.drug || line.formData);
|
|
8385
8386
|
}
|
|
8387
|
+
function withAddedBillSubmissionLines(lines, added) {
|
|
8388
|
+
if (!added?.length) return lines;
|
|
8389
|
+
const entered = [...lines];
|
|
8390
|
+
while (entered.length && !lineHasContent(entered.at(-1))) entered.pop();
|
|
8391
|
+
const present = new Set(entered.map((line) => line.code.trim().toUpperCase()));
|
|
8392
|
+
for (const line of added) {
|
|
8393
|
+
const code = line.code.trim().toUpperCase();
|
|
8394
|
+
if (!code || present.has(code)) continue;
|
|
8395
|
+
present.add(code);
|
|
8396
|
+
entered.push({ code, modifiers: [], units: line.units ?? 1 });
|
|
8397
|
+
}
|
|
8398
|
+
return entered;
|
|
8399
|
+
}
|
|
8386
8400
|
function ensureTrailingBillSubmissionLine(lines) {
|
|
8387
8401
|
const normalized = lines.length ? lines.map((line) => ({ ...line, modifiers: [...line.modifiers ?? []], units: line.units ?? 1 })) : [];
|
|
8388
8402
|
while (normalized.length > 1 && !lineHasContent(normalized.at(-1)) && !lineHasContent(normalized.at(-2))) normalized.pop();
|
|
@@ -8492,7 +8506,7 @@ function setBillSubmissionLineDiagnoses(bill, index, codes2) {
|
|
|
8492
8506
|
}
|
|
8493
8507
|
function cloneInitialBill(bill, treatmentBilling = false) {
|
|
8494
8508
|
const cloned = cloneBill(bill);
|
|
8495
|
-
if (treatmentBilling && cloned.serviceLines.some((line) => line.code.trim()
|
|
8509
|
+
if (treatmentBilling && cloned.serviceLines.some((line) => line.code.trim())) cloned.billingMode = billingModeForLines(cloned.serviceLines);
|
|
8496
8510
|
if (cloned.billingMode !== "professional") cloned.diagnoses = applyBillSubmissionEvaluationDiagnoses(cloned.diagnoses, initialEvaluationType(bill));
|
|
8497
8511
|
return billSubmissionUsesSharedDiagnoses(cloned) ? setBillSubmissionSharedDiagnoses(cloned, cloned.diagnoses ?? []) : cloned;
|
|
8498
8512
|
}
|
|
@@ -8581,14 +8595,13 @@ function validateBillSubmission(bill) {
|
|
|
8581
8595
|
if (bill.renderingProvider?.taxonomy && !/^[A-Za-z0-9]{10}$/.test(bill.renderingProvider.taxonomy.trim())) errors["renderingProvider.taxonomy"] = "Enter a valid 10-character taxonomy code.";
|
|
8582
8596
|
if (bill.serviceLocation?.placeOfServiceCode && !/^\d{2}$/.test(bill.serviceLocation.placeOfServiceCode.trim())) errors["serviceLocation.placeOfServiceCode"] = "Enter a valid 2-digit place of service code.";
|
|
8583
8597
|
const lines = submittedLines(bill.serviceLines);
|
|
8584
|
-
if (lines.some((line) => isMedicalLegalCode(line.code)) && lines.some((line) => line.code && !isMedicalLegalCode(line.code))) errors.serviceLines = "Submit medical-legal and treatment services on separate bills.";
|
|
8585
8598
|
if (!lines.length) errors.serviceLines = "Add at least one service line";
|
|
8586
8599
|
lines.forEach((line, index) => {
|
|
8587
8600
|
required2(`serviceLines.${index}.code`, line.code, "Select a procedure code.");
|
|
8588
8601
|
const pointers = line.diagnosisPointers ?? [];
|
|
8589
8602
|
if (pointers.length > 4 || new Set(pointers).size !== pointers.length || pointers.some((pointer) => !Number.isInteger(pointer) || pointer < 1 || pointer > (bill.diagnoses?.length ?? 0)) || bill.billingMode === "professional" && !pointers.length) errors[`serviceLines.${index}.diagnosisPointers`] = "Select up to four diagnoses for this service line.";
|
|
8590
8603
|
if (!Number.isInteger(line.units) || (line.units ?? 0) < 1) errors[`serviceLines.${index}.units`] = "Enter at least 1 unit";
|
|
8591
|
-
if (bill.billingMode === "professional" && (!Number.isFinite(line.charge) || (line.charge ?? 0) <= 0)) errors[`serviceLines.${index}.charge`] = "Enter the billed charge";
|
|
8604
|
+
if ((bill.billingMode === "professional" || !isMedicalLegalCode(line.code) && lines.some((other) => isMedicalLegalCode(other.code))) && (!Number.isFinite(line.charge) || (line.charge ?? 0) <= 0)) errors[`serviceLines.${index}.charge`] = "Enter the billed charge";
|
|
8592
8605
|
});
|
|
8593
8606
|
return { valid: Object.keys(errors).length === 0, fieldErrors: errors };
|
|
8594
8607
|
}
|
|
@@ -8815,6 +8828,7 @@ function BillSubmissionForm({
|
|
|
8815
8828
|
onLookupPostalCode,
|
|
8816
8829
|
procedureOptions,
|
|
8817
8830
|
treatmentBilling = false,
|
|
8831
|
+
companionLines,
|
|
8818
8832
|
editableTreatmentCharges = false,
|
|
8819
8833
|
onSearchProcedureCodes,
|
|
8820
8834
|
onQuoteFee,
|
|
@@ -9036,7 +9050,8 @@ function BillSubmissionForm({
|
|
|
9036
9050
|
if (Object.hasOwn(patch, "modifiers")) setFeeDetails((current) => ({ ...current, [index]: { ...detailsForLine(index), interpretationLocation: "", professionalComponentBasis: "" } }));
|
|
9037
9051
|
if (Object.hasOwn(patch, "code")) setFeeDetails((current) => ({ ...current, [index]: {} }));
|
|
9038
9052
|
setBill((current) => {
|
|
9039
|
-
const
|
|
9053
|
+
const added = patch.code != null && patch.code !== current.serviceLines[index]?.code ? Object.entries(companionLines ?? {}).find(([code]) => code.trim().toUpperCase() === patch.code.trim().toUpperCase())?.[1] : void 0;
|
|
9054
|
+
const serviceLines = ensureTrailingBillSubmissionLine(withAddedBillSubmissionLines(current.serviceLines.map((line, lineIndex) => {
|
|
9040
9055
|
if (lineIndex !== index) return line;
|
|
9041
9056
|
const next = { ...line, ...patch };
|
|
9042
9057
|
if (patch.code != null && patch.code !== line.code) {
|
|
@@ -9056,9 +9071,9 @@ function BillSubmissionForm({
|
|
|
9056
9071
|
if (charge != null) return { ...next, charge };
|
|
9057
9072
|
if (Object.hasOwn(patch, "code")) delete next.charge;
|
|
9058
9073
|
return next;
|
|
9059
|
-
}));
|
|
9074
|
+
}), added));
|
|
9060
9075
|
const populated = serviceLines.filter((line) => line.code.trim());
|
|
9061
|
-
return { ...sharedDiagnoses ? setBillSubmissionSharedDiagnoses(replaceBillSubmissionServiceLines(current, serviceLines), current.diagnoses ?? []) : replaceBillSubmissionServiceLines(current, serviceLines), ...treatmentBilling && populated.length ? { billingMode: populated
|
|
9076
|
+
return { ...sharedDiagnoses ? setBillSubmissionSharedDiagnoses(replaceBillSubmissionServiceLines(current, serviceLines), current.diagnoses ?? []) : replaceBillSubmissionServiceLines(current, serviceLines), ...treatmentBilling && populated.length ? { billingMode: billingModeForLines(populated) } : {} };
|
|
9062
9077
|
});
|
|
9063
9078
|
};
|
|
9064
9079
|
const setLineCharge = (index, charge) => setBill((current) => ({
|
|
@@ -9416,7 +9431,7 @@ function BillSubmissionForm({
|
|
|
9416
9431
|
} else if (charge != null) next.charge = charge;
|
|
9417
9432
|
return next;
|
|
9418
9433
|
}).filter(lineHasContent);
|
|
9419
|
-
const clean = { ...cloneBill(bill), serviceLines: pricedLines, ...treatmentBilling && pricedLines.length ? { billingMode: pricedLines
|
|
9434
|
+
const clean = { ...cloneBill(bill), serviceLines: pricedLines, ...treatmentBilling && pricedLines.length ? { billingMode: billingModeForLines(pricedLines) } : {} };
|
|
9420
9435
|
const previewBillKey = JSON.stringify(clean);
|
|
9421
9436
|
const previewCurrent = cmsPreview?.billKey === previewBillKey;
|
|
9422
9437
|
const liveErrors = JSON.stringify(validateBillSubmission(clean).fieldErrors);
|
|
@@ -20067,7 +20082,7 @@ function ConnectedBillLifecycle({
|
|
|
20067
20082
|
initialBill: correctionInitialBill,
|
|
20068
20083
|
profileOptions: data.options ? organizationProfileOptions(data.options) : {},
|
|
20069
20084
|
...billingSettings ? { billingSettings } : {},
|
|
20070
|
-
treatmentBilling: data.bill.billingMode === "professional",
|
|
20085
|
+
treatmentBilling: data.bill.billingMode === "professional" || data.bill.lineItems.some((line) => !/^ML/i.test(line.code.trim())),
|
|
20071
20086
|
attachments: correctionAttachments,
|
|
20072
20087
|
onSubmit: submitCorrection,
|
|
20073
20088
|
onListMedicalProviderNetworks: lifecycle.listMedicalProviderNetworks,
|
|
@@ -20108,7 +20123,7 @@ function ConnectedBillLifecycle({
|
|
|
20108
20123
|
initialBill: correctionInitialBill,
|
|
20109
20124
|
profileOptions: data.options ? organizationProfileOptions(data.options) : {},
|
|
20110
20125
|
...billingSettings ? { billingSettings } : {},
|
|
20111
|
-
treatmentBilling: data.bill.billingMode === "professional",
|
|
20126
|
+
treatmentBilling: data.bill.billingMode === "professional" || data.bill.lineItems.some((line) => !/^ML/i.test(line.code.trim())),
|
|
20112
20127
|
attachments: correctionAttachments,
|
|
20113
20128
|
onSubmit: submitNewBillFromForm,
|
|
20114
20129
|
onListMedicalProviderNetworks: lifecycle.listMedicalProviderNetworks,
|
|
@@ -20232,7 +20247,7 @@ function ConnectedBillLifecycle({
|
|
|
20232
20247
|
initialBill: correctionInitialBill,
|
|
20233
20248
|
profileOptions: data.options ? organizationProfileOptions(data.options) : {},
|
|
20234
20249
|
...billingSettings ? { billingSettings } : {},
|
|
20235
|
-
treatmentBilling: data.bill.billingMode === "professional",
|
|
20250
|
+
treatmentBilling: data.bill.billingMode === "professional" || data.bill.lineItems.some((line) => !/^ML/i.test(line.code.trim())),
|
|
20236
20251
|
attachments: correctionAttachments,
|
|
20237
20252
|
onSubmit: submitDuplicateFromForm,
|
|
20238
20253
|
onListMedicalProviderNetworks: lifecycle.listMedicalProviderNetworks,
|