@cosyte/x12 0.0.11 → 0.0.13
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/CHANGELOG.md +275 -0
- package/KNOWN-LIMITATIONS.md +183 -27
- package/README.md +2 -2
- package/dist/index.cjs +179 -61
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +326 -43
- package/dist/index.d.ts +326 -43
- package/dist/index.mjs +176 -62
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -145,7 +145,11 @@ var WARNING_CODES = {
|
|
|
145
145
|
X12_837_SERVICE_LINE_NOT_DECODED: "X12_837_SERVICE_LINE_NOT_DECODED",
|
|
146
146
|
X12_837_SERVICE_LINE_DROPPED: "X12_837_SERVICE_LINE_DROPPED",
|
|
147
147
|
X12_837_SERVICE_SEGMENT_WITHOUT_LX: "X12_837_SERVICE_SEGMENT_WITHOUT_LX",
|
|
148
|
-
X12_837_ENTITY_SEGMENT_DISCARDED_AFTER_LX: "X12_837_ENTITY_SEGMENT_DISCARDED_AFTER_LX"
|
|
148
|
+
X12_837_ENTITY_SEGMENT_DISCARDED_AFTER_LX: "X12_837_ENTITY_SEGMENT_DISCARDED_AFTER_LX",
|
|
149
|
+
X12_837_PAY_TO_ADDRESS_REPEATED: "X12_837_PAY_TO_ADDRESS_REPEATED",
|
|
150
|
+
X12_835_BALANCE_NOT_EVALUABLE: "X12_835_BALANCE_NOT_EVALUABLE",
|
|
151
|
+
X12_AMOUNT_ROW_DROPPED: "X12_AMOUNT_ROW_DROPPED",
|
|
152
|
+
X12_STATED_AMOUNT_DISCARDED: "X12_STATED_AMOUNT_DISCARDED"
|
|
149
153
|
};
|
|
150
154
|
var CONTROL_NUMBER_PAIRS = {
|
|
151
155
|
/** ISA-13 against IEA-02. */
|
|
@@ -206,6 +210,9 @@ var WARNING_MESSAGES = {
|
|
|
206
210
|
X12_835_REMIT_BALANCE_MISMATCH_CLAIM: "835 balance invariant violated [CLP-04 + \u03A3(claim CAS + line CAS) == CLP-03]: the claim does not balance. Every amount is preserved verbatim on the model as an X12Decimal and is NEVER silently rebalanced.",
|
|
207
211
|
X12_835_REMIT_BALANCE_MISMATCH_SERVICE_LINE: "835 balance invariant violated [SVC-03 + \u03A3(line CAS) == SVC-02]: the service line does not balance. Every amount is preserved verbatim on the model as an X12Decimal and is NEVER silently rebalanced.",
|
|
208
212
|
X12_835_REMIT_BALANCE_MISMATCH_REMIT_TOTAL: "835 balance invariant violated [\u03A3(CLP-04) - \u03A3(PLB amounts) == BPR-02]: the remittance total does not balance. Every amount is preserved verbatim on the model as an X12Decimal and is NEVER silently rebalanced.",
|
|
213
|
+
X12_835_BALANCE_NOT_EVALUABLE_CLAIM: "835 balance invariant [CLP-04 + \u03A3(claim CAS + line CAS) == CLP-03] could not be evaluated: at least one term of it is `undefined` on the model, meaning this library decoded no value from that element. The equation is NOT reported as violated and NOT reported as satisfied, because an absent term has no value to compare - substituting 0 for it would be this library asserting a total the sender never sent. Which term is missing is read off the model, never from this message. Compare `X12_835_REMIT_BALANCE_MISMATCH`, which is raised only where every term decoded and the equation is genuinely out of balance.",
|
|
214
|
+
X12_835_BALANCE_NOT_EVALUABLE_SERVICE_LINE: "835 balance invariant [SVC-03 + \u03A3(line CAS) == SVC-02] could not be evaluated: at least one term of it is `undefined` on the model, meaning this library decoded no value from that element. The equation is NOT reported as violated and NOT reported as satisfied, because an absent term has no value to compare - substituting 0 for it would be this library asserting a total the sender never sent. Which term is missing is read off the model, never from this message. Compare `X12_835_REMIT_BALANCE_MISMATCH`, which is raised only where every term decoded and the equation is genuinely out of balance.",
|
|
215
|
+
X12_835_BALANCE_NOT_EVALUABLE_REMIT_TOTAL: "835 balance invariant [\u03A3(CLP-04) - \u03A3(PLB amounts) == BPR-02] could not be evaluated: at least one term of it is `undefined` on the model, meaning this library decoded no value from that element. The equation is NOT reported as violated and NOT reported as satisfied, because an absent term has no value to compare - substituting 0 for it would be this library asserting a total the sender never sent. Which term is missing is read off the model, never from this message. Compare `X12_835_REMIT_BALANCE_MISMATCH`, which is raised only where every term decoded and the equation is genuinely out of balance.",
|
|
209
216
|
X12_UNKNOWN_CARC: "Unknown CARC: the claim adjustment reason code is outside the bundled snapshot. The verbatim code is preserved on the adjustment; only its description is unavailable.",
|
|
210
217
|
X12_UNKNOWN_RARC: "Unknown RARC: the remittance advice remark code is outside the bundled snapshot. The verbatim code is preserved on the remark; only its description is unavailable.",
|
|
211
218
|
X12_HL_PARENT_MISMATCH: "HL-02 declares a parent id that no earlier HL in this transaction set emitted as its HL-01. The declared pointer is preserved verbatim and the hierarchy is NEVER silently re-numbered.",
|
|
@@ -220,10 +227,13 @@ var WARNING_MESSAGES = {
|
|
|
220
227
|
X12_UNKNOWN_CLAIM_STATUS: "Unknown claim status code (CSC): the STC composite's second component is outside the bundled snapshot. The verbatim code is preserved on the status; only its description is unavailable.",
|
|
221
228
|
X12_834_UNKNOWN_MAINTENANCE_TYPE: "Unknown 834 maintenance type: the INS-03/HD-01 code is outside the bundled snapshot. The verbatim code is preserved on the enrollment and the action is NEVER inferred.",
|
|
222
229
|
X12_UNPARSEABLE_DECIMAL: "Unparseable decimal: the element at `position.elementIndex` held bytes this library could not decode as a decimal, so NO value was decoded from it. Whatever occupies that slot on the model, including 0 and undefined, is a stand-in and is NOT a value the sender supplied. The verbatim bytes are preserved on the segment; read them there before acting on the amount, quantity or percent.",
|
|
223
|
-
X12_837_SERVICE_LINE_NOT_DECODED: "837 service line with no decoded service segment: the Loop 2400 line opened at `position.segmentIndex` is followed by no SV1 / SV2 / SV3 matching the variant this submission resolved to, so NOTHING carried by the service segment was read. The line's `charge` and `units`
|
|
230
|
+
X12_837_SERVICE_LINE_NOT_DECODED: "837 service line with no decoded service segment: the Loop 2400 line opened at `position.segmentIndex` is followed by no SV1 / SV2 / SV3 matching the variant this submission resolved to, so NOTHING carried by the service segment was read. The line's `charge` and `units` are `undefined`, which is what this library puts on a decimal slot it decoded no value into; its procedure code, modifiers, unit of measure and place of service are equally undecoded. Two common causes: the line carries no SVx at all, or it carries one for a different 837 variant than ST-03 (or the caller's `type` option) named. Which side is wrong is NOT decided here, because a caller-supplied `type` can disagree with a perfectly conformant document. The verbatim segments are preserved on the transaction set; read them there before acting on the charge or the quantity.",
|
|
224
231
|
X12_837_SERVICE_LINE_DROPPED: "837 service line dropped from the typed model: the LX at `position.segmentIndex` opened no Loop 2400, so no line appears on any claim's `serviceLines` for it and the SV1 / SV2 / SV3 that followed - its charge, units, procedure code and modifiers - was read into nothing. Compare `X12_837_SERVICE_LINE_NOT_DECODED`, where the line IS on the model and only its service segment went unread. Two causes: no Loop 2300 (CLM) is open at this LX, so there is no claim to attach a line to; or the submission's variant is not one of P / I / D, so no variant-specific line shape could be built. Read `submission.variant` and `submission.claims` to tell them apart; do NOT expect `X12_837_UNKNOWN_VARIANT` alongside this code, because a caller-supplied `type` outside P / I / D reaches the second cause without it. Nothing is fabricated to stand in for the missing line and no claim is synthesized. What becomes of a DTP / AMT / NTE / REF that follows the dropped LX depends on the route and this message does not say; see KNOWN-LIMITATIONS.md. The verbatim segments are preserved on the transaction set; read them there before concluding the claim had no service lines.",
|
|
225
232
|
X12_837_SERVICE_SEGMENT_WITHOUT_LX: "837 service segment with no Loop 2400 to read it into: no service line was open at the SV1 / SV2 / SV3 at `position.segmentIndex`, so NOTHING it carries - its charge, units, procedure code, modifiers, unit of measure and place of service - was read. Read that literally: an LX may well appear earlier in the transaction, and what this reports is that none of them had opened a Loop 2400 still current at this segment. No line appears on any claim's `serviceLines` for it and nothing is fabricated to stand in. Compare the two codes anchored at an LX: `X12_837_SERVICE_LINE_DROPPED`, where an LX IS present and opened no line, and `X12_837_SERVICE_LINE_NOT_DECODED`, where the line is on the model and only its service segment went unread. Neither of those can report the SAME service segment as this code, because both are raised at an LX and this one only where no Loop 2400 is open; a document with several claims can still carry all three. This says NOTHING about how the submission's variant resolved: absent a caller-supplied `type` option, and where ST-03 names no known implementation convention, the reader falls back to the first SV1 / SV2 / SV3 in the transaction, and a segment reported here is eligible for that fallback like any other, so a stray one can decide the variant every line is read against. Read `submission.variant`. The verbatim segments are preserved on the transaction set; read them there before concluding the claim had no service lines.",
|
|
226
|
-
X12_837_ENTITY_SEGMENT_DISCARDED_AFTER_LX: "837 entity segment read into nothing after a dropped LX: the N3 / N4 / PER / REF at `position.segmentIndex` arrived while no entity loop was open, because an earlier LX in this transaction opened no Loop 2400 (no CLM was open at it) and closed the entity loop that was current there. NOTHING this segment carries reached the model: no party's `address`, `contacts` or `references` was written from it, and no party, claim or line was synthesized to hold it. This is the code that names THAT loss; `X12_837_SERVICE_LINE_DROPPED` is raised at the LX itself and names the SERVICE LINE's loss, never an entity segment, so the two report different things about the same stretch of the document. Read the bound literally, because this code does NOT report every unattached entity segment: it reports one discarded after such an LX and only while nothing since has opened a new loop, so an N3 / N4 / PER / REF that reaches no party by any other route is still silent, and one arriving after a later NM1 is outside this code's scope, whether or not this reader surfaces that segment kind on that party. It reports that the segment reached NO party; it does not claim it would have reached one had the LX been absent, because this reader does not surface every one of these segment kinds on every party (a PER on a patient or a pay-to address, for one). Which party a segment following a stray LX belongs to is not derivable from the TR3s in either direction, so it is discarded rather than attributed: see KNOWN-LIMITATIONS.md. The verbatim segments are preserved on the transaction set; read them there before concluding a party had no address, no secondary identifier or no contact."
|
|
233
|
+
X12_837_ENTITY_SEGMENT_DISCARDED_AFTER_LX: "837 entity segment read into nothing after a dropped LX: the N3 / N4 / PER / REF at `position.segmentIndex` arrived while no entity loop was open, because an earlier LX in this transaction opened no Loop 2400 (no CLM was open at it) and closed the entity loop that was current there. NOTHING this segment carries reached the model: no party's `address`, `contacts` or `references` was written from it, and no party, claim or line was synthesized to hold it. This is the code that names THAT loss; `X12_837_SERVICE_LINE_DROPPED` is raised at the LX itself and names the SERVICE LINE's loss, never an entity segment, so the two report different things about the same stretch of the document. Read the bound literally, because this code does NOT report every unattached entity segment: it reports one discarded after such an LX and only while nothing since has opened a new loop, so an N3 / N4 / PER / REF that reaches no party by any other route is still silent, and one arriving after a later NM1 is outside this code's scope, whether or not this reader surfaces that segment kind on that party. It reports that the segment reached NO party; it does not claim it would have reached one had the LX been absent, because this reader does not surface every one of these segment kinds on every party (a PER on a patient or a pay-to address, for one). Which party a segment following a stray LX belongs to is not derivable from the TR3s in either direction, so it is discarded rather than attributed: see KNOWN-LIMITATIONS.md. The verbatim segments are preserved on the transaction set; read them there before concluding a party had no address, no secondary identifier or no contact.",
|
|
234
|
+
X12_837_PAY_TO_ADDRESS_REPEATED: "837 pay-to address named more than once in one Loop 2000A: the NM1*87 at `position.segmentIndex` is not the first in this Loop 2000A, and the TR3s allow Loop 2010AB at most once there. The model has ONE pay-to address slot, so it cannot carry both, and this code is the only thing that tells you the document named more than one. The reader NEVER merges them: an N3 or N4 after this segment can no longer add a street line to, or fill a blank in, the address an earlier NM1*87 named, which is what this library did through 0.0.12 - it returned a fused address no sender sent, silently. What the slot carries instead is the LAST occurrence that stated an address of its own; an occurrence that states none - one carrying no N3 or N4 at all, or only a valueless N3 or N4 whose elements are empty - does NOT replace one that did, so nothing an earlier occurrence stated is blanked either. Where no occurrence states an address, the slot holds what the FIRST N3 or N4 to arrive under any of them produced, which may be an address with no elements at all, and which is not necessarily the first occurrence's: an occurrence that carries no N3 or N4 writes nothing, so a later one's valueless N3 is the first write and takes a slot still empty. Read that as the corner it is, and never restate it as the first OCCURRENCE winning. Which occurrence the sender meant is NOT decided here and is not derivable from the TR3s, and the losing occurrence's address is NOT on the model in any form. Read the bound literally: this reports repetition within one Loop 2000A, which is where the pay-to route lives, and an NM1*87 arriving while a CLM is open never reaches that route. The verbatim segments are preserved on the transaction set; read them there before acting on where a payment is to be sent.",
|
|
235
|
+
X12_AMOUNT_ROW_DROPPED: "Amount row dropped from the typed model: the AMT or ADX at `position.segmentIndex` carried no decodable amount (AMT-02, ADX-01), so NO row was built for it and the rest of the segment went with it - its qualifier or adjustment reason code, and any reference qualifier and id. Nothing is fabricated to stand in: a row is not built around a zero this library did not read, which is why the loss is reported rather than papered over. Two routes reach it and this code does not say which: the amount element was ABSENT, or it was present and held bytes that do not decode as a decimal. On this segment only the second route also raises `X12_UNPARSEABLE_DECIMAL`, carrying the failing element in its own `position.elementIndex`, so whether one is present at this `position.segmentIndex` is what separates them - and that code is unchanged by this one, which is raised alongside it rather than in place of it. Read the bound literally: this reports a row whose AMOUNT was read and decoded no value, and it is NOT a general report that an amount segment reached no model. A segment a reader discards before reading its amount is not on this channel, and neither is one whose amount decoded and then found no claim, service line, coverage or remittance open to attach the row to. An 820 RMR is not on it either, for its own reason: that row is dropped on open-item IDENTITY, RMR-01 and RMR-02 both empty, before the amount is read at all, so an RMR that states an open item and no amount keeps its row with amountPaid undefined while one that states an amount and no open item is dropped whole. That second case is a separate loss, and so is an 837 AMT that decoded while a Loop 2430 adjudication was open; `X12_STATED_AMOUNT_DISCARDED` reports both, and this code reports neither. The two can never name the same segment, because this one requires an amount element that decoded no value and that one requires the opposite. The verbatim segments are preserved on the transaction set; read them there before concluding the document stated no such amount.",
|
|
236
|
+
X12_STATED_AMOUNT_DISCARDED: "Stated amount discarded: the RMR or AMT at `position.segmentIndex` populated its amount element and this reader built NO row for it, for a reason that is not a failure to decode that amount. What the sender wrote reaches no part of the typed model, so an empty list of open items or amounts is not evidence the sender stated none. Read that as the only claim made here: this code does NOT assert the amount is decodable, and on the RMR route below it is raised without the bytes ever being DECODED, so they may be unreadable, blank-but-present, or a lone component separator. Two routes reach it and this code does not say which. First, an 820 RMR whose RMR-01 and RMR-02 are BOTH empty while a remittance loop is open: the open item is refused on identity before RMR-04 or RMR-05 is read at all, so a stated payment amount, a stated amount due and the payment action code beside them go together. Second, an 837 AMT arriving while a Loop 2430 line adjudication is open: AMT-02 decoded, and the v1 adjudication model carries no amount row to put it on, so the row is skipped. Compare `X12_AMOUNT_ROW_DROPPED`, which reports the other situation on the same segments: there the amount element decoded no value, so there was no row to build at all. The two can never name the same segment. Read the bound literally, as a property of the READ: this reports a segment whose amount element the sender populated, arriving while the loop that would carry its row was open. It does NOT report an AMT or ADX that reaches a reader with no such loop open, which stays silent and is recorded in KNOWN-LIMITATIONS.md. And on the RMR route it says nothing about whether that amount WOULD have decoded, because the row is refused before the decode is attempted, so no `X12_UNPARSEABLE_DECIMAL` accompanies it even where the bytes are unreadable. Nothing is fabricated to stand in. The verbatim segments are preserved on the transaction set; read them there before concluding the document stated no such amount."
|
|
227
237
|
};
|
|
228
238
|
var ALL_WARNING_MESSAGES = new Set(
|
|
229
239
|
Object.values(WARNING_MESSAGES)
|
|
@@ -245,6 +255,11 @@ var BALANCE_INVARIANT_MESSAGES = {
|
|
|
245
255
|
[BALANCE_INVARIANTS.SERVICE_LINE]: WARNING_MESSAGES.X12_835_REMIT_BALANCE_MISMATCH_SERVICE_LINE,
|
|
246
256
|
[BALANCE_INVARIANTS.REMIT_TOTAL]: WARNING_MESSAGES.X12_835_REMIT_BALANCE_MISMATCH_REMIT_TOTAL
|
|
247
257
|
};
|
|
258
|
+
var BALANCE_NOT_EVALUABLE_MESSAGES = {
|
|
259
|
+
[BALANCE_INVARIANTS.CLAIM]: WARNING_MESSAGES.X12_835_BALANCE_NOT_EVALUABLE_CLAIM,
|
|
260
|
+
[BALANCE_INVARIANTS.SERVICE_LINE]: WARNING_MESSAGES.X12_835_BALANCE_NOT_EVALUABLE_SERVICE_LINE,
|
|
261
|
+
[BALANCE_INVARIANTS.REMIT_TOTAL]: WARNING_MESSAGES.X12_835_BALANCE_NOT_EVALUABLE_REMIT_TOTAL
|
|
262
|
+
};
|
|
248
263
|
var REQUIRED_LOOP_MESSAGES = {
|
|
249
264
|
[REQUIRED_LOOPS.BILLING_PROVIDER_2000A]: WARNING_MESSAGES.X12_MISSING_REQUIRED_LOOP_2000A,
|
|
250
265
|
[REQUIRED_LOOPS.SUBSCRIBER_2000B]: WARNING_MESSAGES.X12_MISSING_REQUIRED_LOOP_2000B,
|
|
@@ -335,6 +350,13 @@ function remitBalanceMismatch(position, invariant) {
|
|
|
335
350
|
position
|
|
336
351
|
};
|
|
337
352
|
}
|
|
353
|
+
function balanceNotEvaluable(position, invariant) {
|
|
354
|
+
return {
|
|
355
|
+
code: WARNING_CODES.X12_835_BALANCE_NOT_EVALUABLE,
|
|
356
|
+
message: BALANCE_NOT_EVALUABLE_MESSAGES[invariant],
|
|
357
|
+
position
|
|
358
|
+
};
|
|
359
|
+
}
|
|
338
360
|
function unknownCarc(position) {
|
|
339
361
|
return {
|
|
340
362
|
code: WARNING_CODES.X12_UNKNOWN_CARC,
|
|
@@ -412,6 +434,13 @@ function entitySegmentDiscardedAfterLx(position) {
|
|
|
412
434
|
position
|
|
413
435
|
};
|
|
414
436
|
}
|
|
437
|
+
function payToAddressRepeated(position) {
|
|
438
|
+
return {
|
|
439
|
+
code: WARNING_CODES.X12_837_PAY_TO_ADDRESS_REPEATED,
|
|
440
|
+
message: WARNING_MESSAGES.X12_837_PAY_TO_ADDRESS_REPEATED,
|
|
441
|
+
position
|
|
442
|
+
};
|
|
443
|
+
}
|
|
415
444
|
function unknownClaimStatusCategory(position) {
|
|
416
445
|
return {
|
|
417
446
|
code: WARNING_CODES.X12_UNKNOWN_CLAIM_STATUS_CATEGORY,
|
|
@@ -440,6 +469,20 @@ function unparseableDecimal(position) {
|
|
|
440
469
|
position
|
|
441
470
|
};
|
|
442
471
|
}
|
|
472
|
+
function amountRowDropped(position) {
|
|
473
|
+
return {
|
|
474
|
+
code: WARNING_CODES.X12_AMOUNT_ROW_DROPPED,
|
|
475
|
+
message: WARNING_MESSAGES.X12_AMOUNT_ROW_DROPPED,
|
|
476
|
+
position
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
function statedAmountDiscarded(position) {
|
|
480
|
+
return {
|
|
481
|
+
code: WARNING_CODES.X12_STATED_AMOUNT_DISCARDED,
|
|
482
|
+
message: WARNING_MESSAGES.X12_STATED_AMOUNT_DISCARDED,
|
|
483
|
+
position
|
|
484
|
+
};
|
|
485
|
+
}
|
|
443
486
|
|
|
444
487
|
// src/parser/release.ts
|
|
445
488
|
var RELEASE_CHAR = "?";
|
|
@@ -1900,11 +1943,13 @@ function isProcedureQualifier(qualifier) {
|
|
|
1900
1943
|
// src/transactions/remit/balance.ts
|
|
1901
1944
|
function checkClaimBalance(claim, position) {
|
|
1902
1945
|
const claimCasSum = sumAmounts(claim.adjustments);
|
|
1903
|
-
const lineCasSum =
|
|
1904
|
-
(
|
|
1905
|
-
X12Decimal.ZERO
|
|
1946
|
+
const lineCasSum = sumOptional(
|
|
1947
|
+
claim.serviceLines.map((sl) => sumAmounts(sl.adjustments))
|
|
1906
1948
|
);
|
|
1907
|
-
const computed = claim.totalPaymentAmount
|
|
1949
|
+
const computed = sumOptional([claim.totalPaymentAmount, claimCasSum, lineCasSum]);
|
|
1950
|
+
if (computed === void 0 || claim.totalChargeAmount === void 0) {
|
|
1951
|
+
return balanceNotEvaluable(position, BALANCE_INVARIANTS.CLAIM);
|
|
1952
|
+
}
|
|
1908
1953
|
if (computed.equals(claim.totalChargeAmount)) return void 0;
|
|
1909
1954
|
return remitBalanceMismatch(position, BALANCE_INVARIANTS.CLAIM);
|
|
1910
1955
|
}
|
|
@@ -1914,35 +1959,37 @@ function checkServiceLineBalance(claim, position) {
|
|
|
1914
1959
|
const line = claim.serviceLines[i];
|
|
1915
1960
|
if (line === void 0) continue;
|
|
1916
1961
|
const lineCasSum = sumAmounts(line.adjustments);
|
|
1917
|
-
const
|
|
1962
|
+
const linePosition = { ...position, segmentIndex: position.segmentIndex + i + 1 };
|
|
1963
|
+
const computed = sumOptional([line.paymentAmount, lineCasSum]);
|
|
1964
|
+
if (computed === void 0 || line.chargeAmount === void 0) {
|
|
1965
|
+
out.push(balanceNotEvaluable(linePosition, BALANCE_INVARIANTS.SERVICE_LINE));
|
|
1966
|
+
continue;
|
|
1967
|
+
}
|
|
1918
1968
|
if (computed.equals(line.chargeAmount)) continue;
|
|
1919
|
-
out.push(
|
|
1920
|
-
remitBalanceMismatch(
|
|
1921
|
-
{ ...position, segmentIndex: position.segmentIndex + i + 1 },
|
|
1922
|
-
BALANCE_INVARIANTS.SERVICE_LINE
|
|
1923
|
-
)
|
|
1924
|
-
);
|
|
1969
|
+
out.push(remitBalanceMismatch(linePosition, BALANCE_INVARIANTS.SERVICE_LINE));
|
|
1925
1970
|
}
|
|
1926
1971
|
return out;
|
|
1927
1972
|
}
|
|
1928
1973
|
function checkRemitTotalBalance(bpr02, claims, providerAdjustments, position) {
|
|
1929
|
-
const claimSum = claims.
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
(acc, p) => acc.add(p.amount),
|
|
1935
|
-
X12Decimal.ZERO
|
|
1936
|
-
);
|
|
1974
|
+
const claimSum = sumOptional(claims.map((c) => c.totalPaymentAmount));
|
|
1975
|
+
const plbSum = sumOptional(providerAdjustments.map((p) => p.amount));
|
|
1976
|
+
if (bpr02 === void 0 || claimSum === void 0 || plbSum === void 0) {
|
|
1977
|
+
return balanceNotEvaluable(position, BALANCE_INVARIANTS.REMIT_TOTAL);
|
|
1978
|
+
}
|
|
1937
1979
|
const computed = claimSum.subtract(plbSum);
|
|
1938
1980
|
if (computed.equals(bpr02)) return void 0;
|
|
1939
1981
|
return remitBalanceMismatch(position, BALANCE_INVARIANTS.REMIT_TOTAL);
|
|
1940
1982
|
}
|
|
1941
1983
|
function sumAmounts(adjustments) {
|
|
1942
|
-
return adjustments.
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1984
|
+
return sumOptional(adjustments.map((a) => a.amount));
|
|
1985
|
+
}
|
|
1986
|
+
function sumOptional(terms) {
|
|
1987
|
+
let acc = X12Decimal.ZERO;
|
|
1988
|
+
for (const term of terms) {
|
|
1989
|
+
if (term === void 0) return void 0;
|
|
1990
|
+
acc = acc.add(term);
|
|
1991
|
+
}
|
|
1992
|
+
return acc;
|
|
1946
1993
|
}
|
|
1947
1994
|
|
|
1948
1995
|
// src/transactions/remit/get-835.ts
|
|
@@ -2108,7 +2155,10 @@ function get835(delimiters, tx) {
|
|
|
2108
2155
|
}
|
|
2109
2156
|
case "AMT": {
|
|
2110
2157
|
const amount = decodeAmt(seg, delimiters, sink);
|
|
2111
|
-
if (amount === void 0)
|
|
2158
|
+
if (amount === void 0) {
|
|
2159
|
+
warnings.push(amountRowDropped(position));
|
|
2160
|
+
break;
|
|
2161
|
+
}
|
|
2112
2162
|
if (currentServiceLine !== void 0) currentServiceLine.amounts.push(amount);
|
|
2113
2163
|
else if (currentClaim !== void 0) currentClaim.amounts.push(amount);
|
|
2114
2164
|
break;
|
|
@@ -2165,7 +2215,7 @@ function get835(delimiters, tx) {
|
|
|
2165
2215
|
function decodeBpr(seg, delimiters, sink) {
|
|
2166
2216
|
return Object.freeze({
|
|
2167
2217
|
transactionHandlingCode: elementValue(seg, 1, delimiters),
|
|
2168
|
-
totalActualPayment:
|
|
2218
|
+
totalActualPayment: elementDecimal(seg, 2, delimiters, sink),
|
|
2169
2219
|
creditDebitFlag: elementValue(seg, 3, delimiters),
|
|
2170
2220
|
method: elementValue(seg, 4, delimiters),
|
|
2171
2221
|
paymentFormatCode: elementOptional(seg, 5, delimiters),
|
|
@@ -2278,7 +2328,7 @@ function decodeCasAdjustments(seg, delimiters, warnings, position) {
|
|
|
2278
2328
|
groupCode,
|
|
2279
2329
|
reasonCode: code,
|
|
2280
2330
|
reasonDescription: entry?.description,
|
|
2281
|
-
amount
|
|
2331
|
+
amount,
|
|
2282
2332
|
quantity
|
|
2283
2333
|
})
|
|
2284
2334
|
);
|
|
@@ -2322,9 +2372,9 @@ function openClaim(seg, delimiters, clpSegmentIndex, sink) {
|
|
|
2322
2372
|
patientControlNumber: elementValue(seg, 1, delimiters),
|
|
2323
2373
|
claimStatusCode,
|
|
2324
2374
|
claimStatusDescription,
|
|
2325
|
-
totalChargeAmount:
|
|
2326
|
-
totalPaymentAmount:
|
|
2327
|
-
patientResponsibilityAmount:
|
|
2375
|
+
totalChargeAmount: elementDecimal(seg, 3, delimiters, sink),
|
|
2376
|
+
totalPaymentAmount: elementDecimal(seg, 4, delimiters, sink),
|
|
2377
|
+
patientResponsibilityAmount: elementDecimal(seg, 5, delimiters, sink),
|
|
2328
2378
|
claimFilingIndicatorCode: elementOptional(seg, 6, delimiters),
|
|
2329
2379
|
payerClaimControlNumber: elementOptional(seg, 7, delimiters),
|
|
2330
2380
|
facilityTypeCode,
|
|
@@ -2360,8 +2410,8 @@ function openServiceLine(seg, delimiters, sink) {
|
|
|
2360
2410
|
productServiceIdQualifier,
|
|
2361
2411
|
productServiceId,
|
|
2362
2412
|
modifiers,
|
|
2363
|
-
chargeAmount:
|
|
2364
|
-
paymentAmount:
|
|
2413
|
+
chargeAmount: elementDecimal(seg, 2, delimiters, sink),
|
|
2414
|
+
paymentAmount: elementDecimal(seg, 3, delimiters, sink),
|
|
2365
2415
|
revenueCode,
|
|
2366
2416
|
paidUnitsOfService,
|
|
2367
2417
|
originalUnitsOfService,
|
|
@@ -2406,7 +2456,7 @@ function decodePlb(seg, delimiters, sink) {
|
|
|
2406
2456
|
fiscalPeriodDate,
|
|
2407
2457
|
reasonCode: reasonCode ?? "",
|
|
2408
2458
|
subCode,
|
|
2409
|
-
amount
|
|
2459
|
+
amount
|
|
2410
2460
|
})
|
|
2411
2461
|
);
|
|
2412
2462
|
}
|
|
@@ -2421,7 +2471,7 @@ var EMPTY_ADDRESS = Object.freeze({
|
|
|
2421
2471
|
});
|
|
2422
2472
|
var EMPTY_HEADER = Object.freeze({
|
|
2423
2473
|
transactionHandlingCode: "",
|
|
2424
|
-
totalActualPayment:
|
|
2474
|
+
totalActualPayment: void 0,
|
|
2425
2475
|
creditDebitFlag: "",
|
|
2426
2476
|
method: "",
|
|
2427
2477
|
paymentFormatCode: void 0,
|
|
@@ -2841,12 +2891,24 @@ function enforceBalance(spec) {
|
|
|
2841
2891
|
for (const claim of claims) {
|
|
2842
2892
|
const claimWarn = checkClaimBalance(claim, position);
|
|
2843
2893
|
if (claimWarn !== void 0) {
|
|
2894
|
+
if (notEvaluable(claimWarn)) {
|
|
2895
|
+
throw new Remit835BuildError(
|
|
2896
|
+
REMIT_835_BUILD_ERROR_CODES.X12_835_BUILD_INVALID_SPEC,
|
|
2897
|
+
`build835 refuses a claim whose balance cannot be checked: ${claimWarn.message}`
|
|
2898
|
+
);
|
|
2899
|
+
}
|
|
2844
2900
|
throw new Remit835BuildError(
|
|
2845
2901
|
REMIT_835_BUILD_ERROR_CODES.X12_835_BUILD_BALANCE_MISMATCH,
|
|
2846
2902
|
`build835 refuses an out-of-balance claim: ${claimWarn.message}`
|
|
2847
2903
|
);
|
|
2848
2904
|
}
|
|
2849
2905
|
for (const lineWarn of checkServiceLineBalance(claim, position)) {
|
|
2906
|
+
if (notEvaluable(lineWarn)) {
|
|
2907
|
+
throw new Remit835BuildError(
|
|
2908
|
+
REMIT_835_BUILD_ERROR_CODES.X12_835_BUILD_INVALID_SPEC,
|
|
2909
|
+
`build835 refuses a service line whose balance cannot be checked: ${lineWarn.message}`
|
|
2910
|
+
);
|
|
2911
|
+
}
|
|
2850
2912
|
throw new Remit835BuildError(
|
|
2851
2913
|
REMIT_835_BUILD_ERROR_CODES.X12_835_BUILD_BALANCE_MISMATCH,
|
|
2852
2914
|
`build835 refuses an out-of-balance service line: ${lineWarn.message}`
|
|
@@ -2860,12 +2922,21 @@ function enforceBalance(spec) {
|
|
|
2860
2922
|
position
|
|
2861
2923
|
);
|
|
2862
2924
|
if (totalWarn !== void 0) {
|
|
2925
|
+
if (notEvaluable(totalWarn)) {
|
|
2926
|
+
throw new Remit835BuildError(
|
|
2927
|
+
REMIT_835_BUILD_ERROR_CODES.X12_835_BUILD_INVALID_SPEC,
|
|
2928
|
+
`build835 refuses a remit whose balance cannot be checked: ${totalWarn.message}`
|
|
2929
|
+
);
|
|
2930
|
+
}
|
|
2863
2931
|
throw new Remit835BuildError(
|
|
2864
2932
|
REMIT_835_BUILD_ERROR_CODES.X12_835_BUILD_BALANCE_MISMATCH,
|
|
2865
2933
|
`build835 refuses an out-of-balance remit: ${totalWarn.message}`
|
|
2866
2934
|
);
|
|
2867
2935
|
}
|
|
2868
2936
|
}
|
|
2937
|
+
function notEvaluable(warn) {
|
|
2938
|
+
return warn.code === WARNING_CODES.X12_835_BALANCE_NOT_EVALUABLE;
|
|
2939
|
+
}
|
|
2869
2940
|
function materializeAdjustment(spec) {
|
|
2870
2941
|
return {
|
|
2871
2942
|
groupCode: spec.groupCode,
|
|
@@ -3239,6 +3310,17 @@ function wireLookup(entries) {
|
|
|
3239
3310
|
return Object.freeze(table);
|
|
3240
3311
|
}
|
|
3241
3312
|
|
|
3313
|
+
// src/transactions/claim/address-segments.ts
|
|
3314
|
+
function emitsStreetLines(address) {
|
|
3315
|
+
return address.lines.length > 0;
|
|
3316
|
+
}
|
|
3317
|
+
function emitsGeographicFields(address) {
|
|
3318
|
+
return address.city !== void 0 || address.state !== void 0 || address.postalCode !== void 0 || address.countryCode !== void 0;
|
|
3319
|
+
}
|
|
3320
|
+
function statesAnAddress(address) {
|
|
3321
|
+
return emitsStreetLines(address) || emitsGeographicFields(address);
|
|
3322
|
+
}
|
|
3323
|
+
|
|
3242
3324
|
// src/transactions/claim/get-837.ts
|
|
3243
3325
|
var VARIANT_BY_ICR = wireLookup({
|
|
3244
3326
|
"005010X222A2": "P",
|
|
@@ -3299,6 +3381,8 @@ function get837Claims(delimiters, tx, opts) {
|
|
|
3299
3381
|
let receiver;
|
|
3300
3382
|
let billingProvider;
|
|
3301
3383
|
let payToAddress;
|
|
3384
|
+
let pendingPayToAddress;
|
|
3385
|
+
let payToAddressNamed = false;
|
|
3302
3386
|
let payToPlan;
|
|
3303
3387
|
let currentSubscriberMember;
|
|
3304
3388
|
let currentPayer;
|
|
@@ -3385,7 +3469,8 @@ function get837Claims(delimiters, tx, opts) {
|
|
|
3385
3469
|
currentPatientMember = { ...currentPatientMember, entity: next };
|
|
3386
3470
|
},
|
|
3387
3471
|
setPayToAddress: (next) => {
|
|
3388
|
-
|
|
3472
|
+
pendingPayToAddress = next;
|
|
3473
|
+
if (statesAnAddress(next) || payToAddress === void 0) payToAddress = next;
|
|
3389
3474
|
},
|
|
3390
3475
|
setOtherSubscriber: (next) => {
|
|
3391
3476
|
currentOtherSubscriber.otherSubscriber = next;
|
|
@@ -3400,7 +3485,10 @@ function get837Claims(delimiters, tx, opts) {
|
|
|
3400
3485
|
getCurrentSubscriber: () => currentSubscriberMember?.entity,
|
|
3401
3486
|
getCurrentPayer: () => currentPayer,
|
|
3402
3487
|
getCurrentPatient: () => currentPatientMember?.entity,
|
|
3403
|
-
|
|
3488
|
+
// Deliberately the CURRENT occurrence's accumulator, never the committed
|
|
3489
|
+
// slot: this is the getter both address arms build onto, and reading the
|
|
3490
|
+
// committed slot here is exactly what fused two `NM1*87`s.
|
|
3491
|
+
getCurrentPayToAddress: () => pendingPayToAddress,
|
|
3404
3492
|
getCurrentOtherSubscriber: () => currentOtherSubscriber?.otherSubscriber,
|
|
3405
3493
|
getCurrentOtherPayer: () => currentOtherSubscriber?.otherPayer
|
|
3406
3494
|
};
|
|
@@ -3422,6 +3510,8 @@ function get837Claims(delimiters, tx, opts) {
|
|
|
3422
3510
|
currentPatientHl = void 0;
|
|
3423
3511
|
billingProvider = void 0;
|
|
3424
3512
|
payToAddress = void 0;
|
|
3513
|
+
pendingPayToAddress = void 0;
|
|
3514
|
+
payToAddressNamed = false;
|
|
3425
3515
|
payToPlan = void 0;
|
|
3426
3516
|
context = { kind: "loop2000A" };
|
|
3427
3517
|
} else if (hl.levelCode === HL_LEVEL_CODES.SUBSCRIBER) {
|
|
@@ -3485,6 +3575,9 @@ function get837Claims(delimiters, tx, opts) {
|
|
|
3485
3575
|
billingProvider = entity;
|
|
3486
3576
|
activeEntity = { kind: "billingProvider" };
|
|
3487
3577
|
} else if (qualifier === NM1_QUALIFIERS.PAY_TO_ADDRESS && context.kind === "loop2000A") {
|
|
3578
|
+
if (payToAddressNamed) warnings.push(payToAddressRepeated(position));
|
|
3579
|
+
payToAddressNamed = true;
|
|
3580
|
+
pendingPayToAddress = void 0;
|
|
3488
3581
|
activeEntity = { kind: "payToAddress" };
|
|
3489
3582
|
} else if (qualifier === NM1_QUALIFIERS.PAY_TO_PLAN && context.kind === "loop2000A" && variant === "I") {
|
|
3490
3583
|
payToPlan = entity;
|
|
@@ -3618,8 +3711,14 @@ function get837Claims(delimiters, tx, opts) {
|
|
|
3618
3711
|
}
|
|
3619
3712
|
case "AMT": {
|
|
3620
3713
|
const amount = decodeAmt2(seg, delimiters, sink);
|
|
3621
|
-
if (amount === void 0)
|
|
3622
|
-
|
|
3714
|
+
if (amount === void 0) {
|
|
3715
|
+
warnings.push(amountRowDropped(position));
|
|
3716
|
+
break;
|
|
3717
|
+
}
|
|
3718
|
+
if (currentAdjudication !== void 0) {
|
|
3719
|
+
warnings.push(statedAmountDiscarded(position));
|
|
3720
|
+
break;
|
|
3721
|
+
}
|
|
3623
3722
|
if (currentServiceLine !== void 0) currentServiceLine.amounts.push(amount);
|
|
3624
3723
|
else if (currentClaim !== void 0) currentClaim.amounts.push(amount);
|
|
3625
3724
|
break;
|
|
@@ -3909,7 +4008,7 @@ function decodeCas(seg, delimiters, warnings, position) {
|
|
|
3909
4008
|
groupCode,
|
|
3910
4009
|
reasonCode: code,
|
|
3911
4010
|
reasonDescription: entry?.description,
|
|
3912
|
-
amount
|
|
4011
|
+
amount,
|
|
3913
4012
|
quantity
|
|
3914
4013
|
})
|
|
3915
4014
|
);
|
|
@@ -3955,7 +4054,7 @@ function openClaim2(seg, delimiters, ctx, sink) {
|
|
|
3955
4054
|
payer,
|
|
3956
4055
|
patient,
|
|
3957
4056
|
claimId: elementValue(seg, 1, delimiters),
|
|
3958
|
-
totalCharge:
|
|
4057
|
+
totalCharge: elementDecimal(seg, 2, delimiters, sink),
|
|
3959
4058
|
placeOfServiceCode: componentOptional(seg, 5, 1, delimiters),
|
|
3960
4059
|
facilityCodeQualifier: componentOptional(seg, 5, 2, delimiters),
|
|
3961
4060
|
claimFrequencyCode: componentOptional(seg, 5, 3, delimiters),
|
|
@@ -3981,8 +4080,8 @@ function openServiceLine2(seg, delimiters, variant, position) {
|
|
|
3981
4080
|
lineNumber,
|
|
3982
4081
|
position,
|
|
3983
4082
|
serviceSegmentDecoded: false,
|
|
3984
|
-
charge:
|
|
3985
|
-
units:
|
|
4083
|
+
charge: void 0,
|
|
4084
|
+
units: void 0,
|
|
3986
4085
|
unitOfMeasure: void 0,
|
|
3987
4086
|
placeOfServiceCode: void 0,
|
|
3988
4087
|
dates: [],
|
|
@@ -4043,9 +4142,9 @@ function decodeSv1(acc, seg, delimiters, sink) {
|
|
|
4043
4142
|
if (m !== void 0) mods.push(m);
|
|
4044
4143
|
}
|
|
4045
4144
|
acc.modifiers = mods;
|
|
4046
|
-
acc.charge =
|
|
4145
|
+
acc.charge = elementDecimal(seg, 2, delimiters, sink);
|
|
4047
4146
|
acc.unitOfMeasure = elementOptional(seg, 3, delimiters);
|
|
4048
|
-
acc.units =
|
|
4147
|
+
acc.units = elementDecimal(seg, 4, delimiters, sink);
|
|
4049
4148
|
acc.placeOfServiceCode = elementOptional(seg, 5, delimiters);
|
|
4050
4149
|
const pointers = [];
|
|
4051
4150
|
for (let p = 1; p <= 4; p += 1) {
|
|
@@ -4069,9 +4168,9 @@ function decodeSv2(acc, seg, delimiters, sink) {
|
|
|
4069
4168
|
if (m !== void 0) mods.push(m);
|
|
4070
4169
|
}
|
|
4071
4170
|
acc.modifiers = mods;
|
|
4072
|
-
acc.charge =
|
|
4171
|
+
acc.charge = elementDecimal(seg, 3, delimiters, sink);
|
|
4073
4172
|
acc.unitOfMeasure = elementOptional(seg, 4, delimiters);
|
|
4074
|
-
acc.units =
|
|
4173
|
+
acc.units = elementDecimal(seg, 5, delimiters, sink);
|
|
4075
4174
|
acc.serviceLineRate = elementDecimal(seg, 6, delimiters, sink);
|
|
4076
4175
|
acc.nonCoveredCharge = elementDecimal(seg, 7, delimiters, sink);
|
|
4077
4176
|
}
|
|
@@ -4086,7 +4185,7 @@ function decodeSv3(acc, seg, delimiters, sink) {
|
|
|
4086
4185
|
if (m !== void 0) mods.push(m);
|
|
4087
4186
|
}
|
|
4088
4187
|
acc.modifiers = mods;
|
|
4089
|
-
acc.charge =
|
|
4188
|
+
acc.charge = elementDecimal(seg, 2, delimiters, sink);
|
|
4090
4189
|
acc.placeOfServiceCode = elementOptional(seg, 3, delimiters);
|
|
4091
4190
|
const cavities = [];
|
|
4092
4191
|
for (let p = 1; p <= 5; p += 1) {
|
|
@@ -4095,12 +4194,12 @@ function decodeSv3(acc, seg, delimiters, sink) {
|
|
|
4095
4194
|
}
|
|
4096
4195
|
acc.oralCavityArea = cavities;
|
|
4097
4196
|
acc.prosthesisCrownInlayCode = elementOptional(seg, 5, delimiters);
|
|
4098
|
-
acc.units =
|
|
4197
|
+
acc.units = elementDecimal(seg, 6, delimiters, sink);
|
|
4099
4198
|
}
|
|
4100
4199
|
function openAdjudication(seg, delimiters, sink) {
|
|
4101
4200
|
return {
|
|
4102
4201
|
otherPayerId: elementValue(seg, 1, delimiters),
|
|
4103
|
-
amountPaid:
|
|
4202
|
+
amountPaid: elementDecimal(seg, 2, delimiters, sink),
|
|
4104
4203
|
procedureQualifier: componentOptional(seg, 3, 1, delimiters),
|
|
4105
4204
|
procedureCode: componentOptional(seg, 3, 2, delimiters),
|
|
4106
4205
|
paidUnits: elementDecimal(seg, 5, delimiters, sink),
|
|
@@ -4629,6 +4728,12 @@ function enforceClaim(variant, claim, locator) {
|
|
|
4629
4728
|
`build837${variant}: claim at ${locator} has a service line at index ${String(l)} with an empty ${line.variant === "I" ? "revenue" : "procedure"} code.`
|
|
4630
4729
|
);
|
|
4631
4730
|
}
|
|
4731
|
+
if (line.units === void 0) {
|
|
4732
|
+
throw new Claim837BuildError(
|
|
4733
|
+
CLAIM_837_BUILD_ERROR_CODES.X12_837_BUILD_INVALID_SPEC,
|
|
4734
|
+
`build837${variant}: claim at ${locator} has a service line at index ${String(l)} with no units. This builder will not emit a service unit count the caller did not supply; set units to an X12Decimal rather than leaving it undefined.`
|
|
4735
|
+
);
|
|
4736
|
+
}
|
|
4632
4737
|
}
|
|
4633
4738
|
}
|
|
4634
4739
|
function emitBillingProvider(variant, billing, body, ctx, counter) {
|
|
@@ -4743,7 +4848,7 @@ function emitOtherSubscriber(other, body, ctx) {
|
|
|
4743
4848
|
}
|
|
4744
4849
|
function emitServiceLine2(variant, line, lineNumber, body, ctx) {
|
|
4745
4850
|
body.push(ctx.seg(["LX", ctx.esc(line.lineNumber ?? String(lineNumber))]));
|
|
4746
|
-
const units =
|
|
4851
|
+
const units = decStr(line.units);
|
|
4747
4852
|
if (line.variant === "P") {
|
|
4748
4853
|
const proc = ctx.comp([line.procedureQualifier, line.procedureCode, ...line.modifiers ?? []]);
|
|
4749
4854
|
const pointers = ctx.comp(line.diagnosisPointers ?? []);
|
|
@@ -4895,10 +5000,10 @@ function emitEntity(entity, body, ctx) {
|
|
|
4895
5000
|
for (const ref of entity.references ?? []) body.push(emitRef2(ref, ctx));
|
|
4896
5001
|
}
|
|
4897
5002
|
function emitAddress(address, body, ctx) {
|
|
4898
|
-
if (address
|
|
5003
|
+
if (emitsStreetLines(address)) {
|
|
4899
5004
|
body.push(ctx.seg(["N3", ...address.lines.map(ctx.esc)]));
|
|
4900
5005
|
}
|
|
4901
|
-
if (address
|
|
5006
|
+
if (emitsGeographicFields(address)) {
|
|
4902
5007
|
body.push(
|
|
4903
5008
|
ctx.seg([
|
|
4904
5009
|
"N4",
|
|
@@ -6892,13 +6997,18 @@ function get820Payments(delimiters, tx) {
|
|
|
6892
6997
|
case "RMR": {
|
|
6893
6998
|
if (current === void 0) break;
|
|
6894
6999
|
const item = decodeRmr(seg, delimiters, sink);
|
|
6895
|
-
if (item !== void 0)
|
|
7000
|
+
if (item !== void 0) {
|
|
7001
|
+
current.openItems.push(item);
|
|
7002
|
+
break;
|
|
7003
|
+
}
|
|
7004
|
+
if (statesAnAmount(seg, delimiters)) warnings.push(statedAmountDiscarded(position));
|
|
6896
7005
|
break;
|
|
6897
7006
|
}
|
|
6898
7007
|
case "ADX": {
|
|
6899
7008
|
if (current === void 0) break;
|
|
6900
7009
|
const adjustment = decodeAdx(seg, delimiters, sink);
|
|
6901
|
-
if (adjustment
|
|
7010
|
+
if (adjustment === void 0) warnings.push(amountRowDropped(position));
|
|
7011
|
+
else current.adjustments.push(adjustment);
|
|
6902
7012
|
break;
|
|
6903
7013
|
}
|
|
6904
7014
|
case "REF": {
|
|
@@ -6952,7 +7062,7 @@ function freezeRemittance(acc) {
|
|
|
6952
7062
|
function decodeBpr2(seg, delimiters, sink) {
|
|
6953
7063
|
return Object.freeze({
|
|
6954
7064
|
transactionHandlingCode: elementValue(seg, 1, delimiters),
|
|
6955
|
-
totalPremiumAmount:
|
|
7065
|
+
totalPremiumAmount: elementDecimal(seg, 2, delimiters, sink),
|
|
6956
7066
|
creditDebitFlag: elementValue(seg, 3, delimiters),
|
|
6957
7067
|
method: elementValue(seg, 4, delimiters),
|
|
6958
7068
|
paymentFormatCode: elementOptional(seg, 5, delimiters),
|
|
@@ -7020,6 +7130,9 @@ function decodeNm13(seg, delimiters) {
|
|
|
7020
7130
|
idCode: elementOptional(seg, 9, delimiters)
|
|
7021
7131
|
});
|
|
7022
7132
|
}
|
|
7133
|
+
function statesAnAmount(seg, delimiters) {
|
|
7134
|
+
return elementValue(seg, 4, delimiters) !== "" || elementValue(seg, 5, delimiters) !== "";
|
|
7135
|
+
}
|
|
7023
7136
|
function decodeRmr(seg, delimiters, sink) {
|
|
7024
7137
|
const qualifier = elementValue(seg, 1, delimiters);
|
|
7025
7138
|
const referenceId = elementValue(seg, 2, delimiters);
|
|
@@ -7028,7 +7141,7 @@ function decodeRmr(seg, delimiters, sink) {
|
|
|
7028
7141
|
qualifier,
|
|
7029
7142
|
referenceId,
|
|
7030
7143
|
paymentActionCode: elementOptional(seg, 3, delimiters),
|
|
7031
|
-
amountPaid:
|
|
7144
|
+
amountPaid: elementDecimal(seg, 4, delimiters, sink),
|
|
7032
7145
|
amountDue: elementDecimal(seg, 5, delimiters, sink)
|
|
7033
7146
|
});
|
|
7034
7147
|
}
|
|
@@ -7051,7 +7164,7 @@ var EMPTY_ADDRESS3 = Object.freeze({
|
|
|
7051
7164
|
});
|
|
7052
7165
|
var EMPTY_HEADER2 = Object.freeze({
|
|
7053
7166
|
transactionHandlingCode: "",
|
|
7054
|
-
totalPremiumAmount:
|
|
7167
|
+
totalPremiumAmount: void 0,
|
|
7055
7168
|
creditDebitFlag: "",
|
|
7056
7169
|
method: "",
|
|
7057
7170
|
paymentFormatCode: void 0,
|
|
@@ -7610,7 +7723,8 @@ async function* get834Enrollments(delimiters, tx) {
|
|
|
7610
7723
|
if (currentCoverage === void 0) break;
|
|
7611
7724
|
const sink = { warnings: current.warnings, position };
|
|
7612
7725
|
const amount = decodeAmt3(seg, delimiters, sink);
|
|
7613
|
-
if (amount
|
|
7726
|
+
if (amount === void 0) current.warnings.push(amountRowDropped(position));
|
|
7727
|
+
else currentCoverage.amounts.push(amount);
|
|
7614
7728
|
break;
|
|
7615
7729
|
}
|
|
7616
7730
|
}
|
|
@@ -10192,7 +10306,7 @@ var profiles = Object.freeze({
|
|
|
10192
10306
|
});
|
|
10193
10307
|
|
|
10194
10308
|
// src/index.ts
|
|
10195
|
-
var VERSION = "0.0.
|
|
10309
|
+
var VERSION = "0.0.13";
|
|
10196
10310
|
|
|
10197
10311
|
exports.ACK_BUILD_ERROR_CODES = ACK_BUILD_ERROR_CODES;
|
|
10198
10312
|
exports.ALL_WARNING_MESSAGES = ALL_WARNING_MESSAGES;
|
|
@@ -10300,6 +10414,8 @@ exports.X12ParseError = X12ParseError;
|
|
|
10300
10414
|
exports.X12ProfileError = X12ProfileError;
|
|
10301
10415
|
exports.X12_ACK_DISPOSITION_CODES = X12_ACK_DISPOSITION_CODES;
|
|
10302
10416
|
exports.X12_BUILD_ERROR_CODES = X12_BUILD_ERROR_CODES;
|
|
10417
|
+
exports.amountRowDropped = amountRowDropped;
|
|
10418
|
+
exports.balanceNotEvaluable = balanceNotEvaluable;
|
|
10303
10419
|
exports.build271 = build271;
|
|
10304
10420
|
exports.build277 = build277;
|
|
10305
10421
|
exports.build277CA = build277CA;
|
|
@@ -10366,6 +10482,7 @@ exports.parse999 = parse999;
|
|
|
10366
10482
|
exports.parseTA1 = parseTA1;
|
|
10367
10483
|
exports.parseX12 = parseX12;
|
|
10368
10484
|
exports.partitionWarnings = partitionWarnings;
|
|
10485
|
+
exports.payToAddressRepeated = payToAddressRepeated;
|
|
10369
10486
|
exports.pre005010 = pre005010;
|
|
10370
10487
|
exports.profiles = profiles;
|
|
10371
10488
|
exports.readElementDecimal = readElementDecimal;
|
|
@@ -10378,6 +10495,7 @@ exports.serviceLineDropped = serviceLineDropped;
|
|
|
10378
10495
|
exports.serviceLineNotDecoded = serviceLineNotDecoded;
|
|
10379
10496
|
exports.serviceSegmentWithoutLx = serviceSegmentWithoutLx;
|
|
10380
10497
|
exports.setDefaultProfile = setDefaultProfile;
|
|
10498
|
+
exports.statedAmountDiscarded = statedAmountDiscarded;
|
|
10381
10499
|
exports.trailingGarbage = trailingGarbage;
|
|
10382
10500
|
exports.transactionCountMismatch = transactionCountMismatch;
|
|
10383
10501
|
exports.unescapeRelease = unescapeRelease;
|