@mindbill/react 0.37.0 → 0.38.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 CHANGED
@@ -123,6 +123,15 @@ the next immutable attempt under the same logical `billId`; the original
123
123
  attempt and rejection remain in history. The host application does not build a
124
124
  second correction form or pass bill seed data back into the lifecycle.
125
125
 
126
+ For a **closed** bill the server authorizes exactly two actions — **Reopen**
127
+ and **Submit New Bill**. Submit New Bill opens the same `BillSubmissionForm`,
128
+ prefilled from the closed bill's snapshot with its documents carried forward,
129
+ and a Cancel button returns to the closed-bill view. Submitting creates a
130
+ fresh original bill linked to the closed predecessor: the closed bill stays
131
+ closed and keeps its record, and the submissions ribbon/timeline chains both
132
+ bills. Failures surface inline in the dialog, exactly like the correction
133
+ flow.
134
+
126
135
  ## Lifecycle actions
127
136
 
128
137
  MindBill returns the actions that are valid for the bill's current state. Render that server-authoritative list instead of duplicating rejection, EOR, denial, review, payment, and closure rules in your application.
package/dist/index.d.ts CHANGED
@@ -1054,6 +1054,7 @@ type UseBillLifecycleResult = {
1054
1054
  postPayment: BillLifecycleClient["postPayment"];
1055
1055
  submitSecondReview: BillLifecycleClient["submitSecondReview"];
1056
1056
  resubmitBill: BillLifecycleClient["resubmitBill"];
1057
+ submitNewBill: BillLifecycleClient["submitNewBill"];
1057
1058
  sendDuplicateBill: BillLifecycleClient["sendDuplicateBill"];
1058
1059
  reportBillStatus: BillLifecycleClient["reportBillStatus"];
1059
1060
  simulateSandbox: BillLifecycleClient["simulateSandbox"];
package/dist/index.js CHANGED
@@ -5064,6 +5064,7 @@ function useBillLifecycle({
5064
5064
  postPayment: (input) => mutate(() => client.postPayment(input)),
5065
5065
  submitSecondReview: (input) => mutate(() => client.submitSecondReview(input)),
5066
5066
  resubmitBill: (input) => mutate(() => client.resubmitBill(input)),
5067
+ submitNewBill: (input) => mutate(() => client.submitNewBill(input)),
5067
5068
  sendDuplicateBill: (input) => mutate(() => client.sendDuplicateBill(input)),
5068
5069
  reportBillStatus: (input) => mutate(() => client.reportBillStatus(input)),
5069
5070
  simulateSandbox: (input) => mutate(() => client.simulateSandbox(input))
@@ -5175,6 +5176,7 @@ function usDate(isoDate) {
5175
5176
  }
5176
5177
  function actionPanel(action) {
5177
5178
  if (action.id === "resubmit") return "resubmit";
5179
+ if (action.id === "submit_new_bill") return "submit_new_bill";
5178
5180
  if (action.id === "second_review") return "second_review";
5179
5181
  if (action.id === "post_payment") return "payment";
5180
5182
  if (action.id === "close") return "close";
@@ -5204,6 +5206,8 @@ function ConnectedBillLifecycle({ appearance, sandboxControls = false, className
5204
5206
  const [panel, setPanel] = useState10("");
5205
5207
  const [notice, setNotice] = useState10("");
5206
5208
  const [reason, setReason] = useState10("");
5209
+ const [correctionError, setCorrectionError] = useState10("");
5210
+ const [newBillError, setNewBillError] = useState10("");
5207
5211
  const [payment, setPayment] = useState10({ amount: 0, penaltyAmount: 0, interestAmount: 0, method: "check", checkNumber: "", depositDate: today(), note: "" });
5208
5212
  const [review, setReview] = useState10({ reason: "", payerClaimControlNumber: "", disputedAmount: void 0, attachmentIds: [], route: "ebill" });
5209
5213
  const [duplicateDelivery, setDuplicateDelivery] = useState10(null);
@@ -5262,29 +5266,63 @@ function ConnectedBillLifecycle({ appearance, sandboxControls = false, className
5262
5266
  };
5263
5267
  const submitCorrection = async (value) => {
5264
5268
  setNotice("");
5265
- const documents = await prepareBillSubmissionDocuments({
5266
- attachments: correctionAttachments,
5267
- selectedIds: value.sourceAttachmentIds,
5268
- reportTypeCodeByAttachmentId: value.sourceAttachmentReportTypes,
5269
- uploads: value.uploads,
5270
- ...options.fetch ? { fetch: options.fetch } : {}
5271
- });
5272
- await lifecycle.resubmitBill({
5273
- bill: value.bill,
5274
- ...documents.length ? { documents } : {},
5275
- ...reason.trim() ? { reason: reason.trim() } : {}
5276
- });
5269
+ setCorrectionError("");
5270
+ try {
5271
+ const documents = await prepareBillSubmissionDocuments({
5272
+ attachments: correctionAttachments,
5273
+ selectedIds: value.sourceAttachmentIds,
5274
+ reportTypeCodeByAttachmentId: value.sourceAttachmentReportTypes,
5275
+ uploads: value.uploads,
5276
+ ...options.fetch ? { fetch: options.fetch } : {}
5277
+ });
5278
+ await lifecycle.resubmitBill({
5279
+ bill: value.bill,
5280
+ ...documents.length ? { documents } : {},
5281
+ ...reason.trim() ? { reason: reason.trim() } : {}
5282
+ });
5283
+ } catch (cause) {
5284
+ setCorrectionError(
5285
+ cause instanceof Error && cause.message ? cause.message : "The corrected bill could not be resubmitted."
5286
+ );
5287
+ return;
5288
+ }
5277
5289
  setPanel("");
5278
5290
  setReason("");
5279
5291
  setNotice("Corrected submission sent.");
5280
5292
  };
5293
+ const submitNewBillFromForm = async (value) => {
5294
+ setNotice("");
5295
+ setNewBillError("");
5296
+ try {
5297
+ const documents = await prepareBillSubmissionDocuments({
5298
+ attachments: correctionAttachments,
5299
+ selectedIds: value.sourceAttachmentIds,
5300
+ reportTypeCodeByAttachmentId: value.sourceAttachmentReportTypes,
5301
+ uploads: value.uploads,
5302
+ ...options.fetch ? { fetch: options.fetch } : {}
5303
+ });
5304
+ await lifecycle.submitNewBill({
5305
+ bill: value.bill,
5306
+ ...documents.length ? { documents } : {},
5307
+ ...reason.trim() ? { reason: reason.trim() } : {}
5308
+ });
5309
+ } catch (cause) {
5310
+ setNewBillError(
5311
+ cause instanceof Error && cause.message ? cause.message : "The new bill could not be submitted."
5312
+ );
5313
+ return;
5314
+ }
5315
+ setPanel("");
5316
+ setReason("");
5317
+ setNotice("New bill submitted.");
5318
+ };
5281
5319
  const loadDuplicateDelivery = () => {
5282
5320
  setDuplicateDeliveryError("");
5283
5321
  if (duplicateDelivery) return;
5284
5322
  lifecycle.getDeliveryOptions().then((options2) => setDuplicateDelivery(options2)).catch((cause) => setDuplicateDeliveryError(cause instanceof Error ? cause.message : "Delivery options could not be loaded."));
5285
5323
  };
5286
5324
  const viewEor = data.lifecycle.actions.find((action) => action.id === "view_eor" && action.enabled);
5287
- const supportedActions = /* @__PURE__ */ new Set(["resubmit", "second_review", "post_payment", "close", "reopen", "send_duplicate", "report_bill_status"]);
5325
+ const supportedActions = /* @__PURE__ */ new Set(["resubmit", "submit_new_bill", "second_review", "post_payment", "close", "reopen", "send_duplicate", "report_bill_status"]);
5288
5326
  const actions = data.lifecycle.actions.filter((action) => action.enabled && supportedActions.has(action.id));
5289
5327
  const showSandboxControls = shouldShowSandboxControls(data.environment, sandboxControls);
5290
5328
  const simulations = showSandboxControls ? sandboxScenarios(data.lifecycle.state) : [];
@@ -5334,6 +5372,8 @@ function ConnectedBillLifecycle({ appearance, sandboxControls = false, className
5334
5372
  actions.map((action) => /* @__PURE__ */ jsx13("button", { type: "button", className: action.primary ? "mb-lifecycle-button primary" : "mb-lifecycle-button secondary", onClick: () => {
5335
5373
  const next = actionPanel(action);
5336
5374
  if (!next) return;
5375
+ if (next === "resubmit") setCorrectionError("");
5376
+ if (next === "submit_new_bill") setNewBillError("");
5337
5377
  if (next === "send_duplicate") loadDuplicateDelivery();
5338
5378
  if (next === "second_review") setReview((current) => current.reason.trim() ? current : { ...current, reason: SECOND_REVIEW_REASON_TEMPLATE });
5339
5379
  setPanel(next);
@@ -5387,7 +5427,41 @@ function ConnectedBillLifecycle({ appearance, sandboxControls = false, className
5387
5427
  ...options.fetch ? { fetch: options.fetch } : {},
5388
5428
  ...appearance ? { appearance } : {}
5389
5429
  }
5390
- )
5430
+ ),
5431
+ correctionError ? /* @__PURE__ */ jsx13("div", { className: "mb-lifecycle-message error", role: "alert", children: correctionError }) : null
5432
+ ] }) }) : null,
5433
+ panel === "submit_new_bill" && correctionInitialBill ? /* @__PURE__ */ jsx13(LifecycleDialog, { title: "Submit New Bill", wide: true, onClose: () => setPanel(""), children: /* @__PURE__ */ jsxs13("section", { className: "mb-lifecycle-correction", children: [
5434
+ /* @__PURE__ */ jsxs13("header", { children: [
5435
+ /* @__PURE__ */ jsxs13("div", { children: [
5436
+ /* @__PURE__ */ jsx13("h3", { children: "Submit New Bill" }),
5437
+ /* @__PURE__ */ jsx13("p", { children: "This closed bill stays closed and keeps its record. Review the carried-over snapshot below and submit a fresh bill \u2014 both bills stay linked in the submissions timeline." })
5438
+ ] }),
5439
+ /* @__PURE__ */ jsx13("button", { type: "button", className: "mb-lifecycle-button secondary", onClick: () => setPanel(""), children: "Cancel" })
5440
+ ] }),
5441
+ /* @__PURE__ */ jsxs13("label", { className: "mb-lifecycle-correction-note", children: [
5442
+ /* @__PURE__ */ jsx13("span", { children: "Submission note (optional)" }),
5443
+ /* @__PURE__ */ jsx13("textarea", { value: reason, placeholder: "Why is a new bill being submitted?", onChange: (event) => setReason(event.target.value) })
5444
+ ] }),
5445
+ /* @__PURE__ */ jsx13(
5446
+ BillSubmissionForm,
5447
+ {
5448
+ initialBill: correctionInitialBill,
5449
+ attachments: correctionAttachments,
5450
+ onSubmit: submitNewBillFromForm,
5451
+ onSearchClaimsAdministrators: lifecycle.searchClaimsAdministrators,
5452
+ attentionMessage: "Confirm every value carried over from the closed bill before submitting the new bill.",
5453
+ submitLabel: lifecycle.isMutating ? "Submitting\u2026" : "Submit New Bill",
5454
+ heading: "New bill information",
5455
+ description: "The closed bill stays unchanged. This form submits a fresh bill linked to it.",
5456
+ disabled: lifecycle.isMutating,
5457
+ ...options.getSession ? { getSession: options.getSession } : {},
5458
+ ...options.sessionEndpoint ? { sessionEndpoint: options.sessionEndpoint } : {},
5459
+ ...options.apiBaseUrl ? { apiBaseUrl: options.apiBaseUrl } : {},
5460
+ ...options.fetch ? { fetch: options.fetch } : {},
5461
+ ...appearance ? { appearance } : {}
5462
+ }
5463
+ ),
5464
+ newBillError ? /* @__PURE__ */ jsx13("div", { className: "mb-lifecycle-message error", role: "alert", children: newBillError }) : null
5391
5465
  ] }) }) : null,
5392
5466
  panel === "second_review" ? /* @__PURE__ */ jsx13(LifecycleDialog, { title: "Submit Second Review", onClose: () => setPanel(""), children: /* @__PURE__ */ jsxs13("section", { className: "mb-lifecycle-panel", children: [
5393
5467
  /* @__PURE__ */ jsxs13("div", { children: [