@cosyte/x12 0.0.8 → 0.0.10
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 +425 -0
- package/dist/index.cjs +420 -191
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +266 -7
- package/dist/index.d.ts +266 -7
- package/dist/index.mjs +417 -192
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -140,7 +140,10 @@ var WARNING_CODES = {
|
|
|
140
140
|
X12_837_UNKNOWN_VARIANT: "X12_837_UNKNOWN_VARIANT",
|
|
141
141
|
X12_UNKNOWN_CLAIM_STATUS_CATEGORY: "X12_UNKNOWN_CLAIM_STATUS_CATEGORY",
|
|
142
142
|
X12_UNKNOWN_CLAIM_STATUS: "X12_UNKNOWN_CLAIM_STATUS",
|
|
143
|
-
X12_834_UNKNOWN_MAINTENANCE_TYPE: "X12_834_UNKNOWN_MAINTENANCE_TYPE"
|
|
143
|
+
X12_834_UNKNOWN_MAINTENANCE_TYPE: "X12_834_UNKNOWN_MAINTENANCE_TYPE",
|
|
144
|
+
X12_UNPARSEABLE_DECIMAL: "X12_UNPARSEABLE_DECIMAL",
|
|
145
|
+
X12_837_SERVICE_LINE_NOT_DECODED: "X12_837_SERVICE_LINE_NOT_DECODED",
|
|
146
|
+
X12_837_SERVICE_LINE_DROPPED: "X12_837_SERVICE_LINE_DROPPED"
|
|
144
147
|
};
|
|
145
148
|
var CONTROL_NUMBER_PAIRS = {
|
|
146
149
|
/** ISA-13 against IEA-02. */
|
|
@@ -213,7 +216,10 @@ var WARNING_MESSAGES = {
|
|
|
213
216
|
X12_837_UNKNOWN_VARIANT: `837 variant could not be resolved: ST-03's implementation convention reference is not one of "005010X222A2" / "005010X223A3" / "005010X224A2", and no SVx service-line segment was present to fall back on. The verbatim reference is preserved on the model.`,
|
|
214
217
|
X12_UNKNOWN_CLAIM_STATUS_CATEGORY: "Unknown claim status category (CSCC): the STC composite's first component is outside the bundled snapshot. The verbatim code is preserved on the status; only its description is unavailable.",
|
|
215
218
|
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.",
|
|
216
|
-
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."
|
|
219
|
+
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.",
|
|
220
|
+
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.",
|
|
221
|
+
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` hold 0 as a stand-in and are NOT values the sender supplied; 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.",
|
|
222
|
+
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."
|
|
217
223
|
};
|
|
218
224
|
var ALL_WARNING_MESSAGES = new Set(
|
|
219
225
|
Object.values(WARNING_MESSAGES)
|
|
@@ -374,6 +380,20 @@ function unknown837Variant(position) {
|
|
|
374
380
|
position
|
|
375
381
|
};
|
|
376
382
|
}
|
|
383
|
+
function serviceLineNotDecoded(position) {
|
|
384
|
+
return {
|
|
385
|
+
code: WARNING_CODES.X12_837_SERVICE_LINE_NOT_DECODED,
|
|
386
|
+
message: WARNING_MESSAGES.X12_837_SERVICE_LINE_NOT_DECODED,
|
|
387
|
+
position
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
function serviceLineDropped(position) {
|
|
391
|
+
return {
|
|
392
|
+
code: WARNING_CODES.X12_837_SERVICE_LINE_DROPPED,
|
|
393
|
+
message: WARNING_MESSAGES.X12_837_SERVICE_LINE_DROPPED,
|
|
394
|
+
position
|
|
395
|
+
};
|
|
396
|
+
}
|
|
377
397
|
function unknownClaimStatusCategory(position) {
|
|
378
398
|
return {
|
|
379
399
|
code: WARNING_CODES.X12_UNKNOWN_CLAIM_STATUS_CATEGORY,
|
|
@@ -395,6 +415,13 @@ function unknownMaintenanceType(position) {
|
|
|
395
415
|
position
|
|
396
416
|
};
|
|
397
417
|
}
|
|
418
|
+
function unparseableDecimal(position) {
|
|
419
|
+
return {
|
|
420
|
+
code: WARNING_CODES.X12_UNPARSEABLE_DECIMAL,
|
|
421
|
+
message: WARNING_MESSAGES.X12_UNPARSEABLE_DECIMAL,
|
|
422
|
+
position
|
|
423
|
+
};
|
|
424
|
+
}
|
|
398
425
|
|
|
399
426
|
// src/parser/release.ts
|
|
400
427
|
var RELEASE_CHAR = "?";
|
|
@@ -426,6 +453,9 @@ function unescapeRelease(input, delimiters, emit, position) {
|
|
|
426
453
|
return out;
|
|
427
454
|
}
|
|
428
455
|
function escapeRelease(value, delimiters) {
|
|
456
|
+
if (typeof value !== "string") {
|
|
457
|
+
throw new TypeError(`escapeRelease: value must be a string, received ${typeof value}.`);
|
|
458
|
+
}
|
|
429
459
|
if (value.length === 0) return value;
|
|
430
460
|
let out = "";
|
|
431
461
|
for (let i = 0; i < value.length; i++) {
|
|
@@ -905,13 +935,26 @@ function componentOptional(seg, n, p, delimiters) {
|
|
|
905
935
|
const v = getSegmentValue(seg, `${String(n).padStart(2, "0")}-${String(p)}`, delimiters);
|
|
906
936
|
return v === void 0 || v === "" ? void 0 : v;
|
|
907
937
|
}
|
|
908
|
-
function
|
|
938
|
+
function readElementDecimal(seg, n, delimiters) {
|
|
909
939
|
const raw = elementOptional(seg, n, delimiters);
|
|
910
|
-
if (raw === void 0) return void 0;
|
|
911
|
-
|
|
940
|
+
if (raw === void 0) return { value: void 0, status: "absent" };
|
|
941
|
+
const value = X12Decimal.fromString(raw);
|
|
942
|
+
if (value === void 0) return { value: void 0, status: "unparseable" };
|
|
943
|
+
return { value, status: "decoded" };
|
|
944
|
+
}
|
|
945
|
+
function elementDecimal(seg, n, delimiters, sink) {
|
|
946
|
+
const read = readElementDecimal(seg, n, delimiters);
|
|
947
|
+
if (read.status === "unparseable" && sink !== void 0) {
|
|
948
|
+
sink.warnings.push(unparseableDecimal({ ...sink.position, elementIndex: n }));
|
|
949
|
+
}
|
|
950
|
+
return read.value;
|
|
912
951
|
}
|
|
913
|
-
function elementDecimalOrZero(seg, n, delimiters) {
|
|
914
|
-
|
|
952
|
+
function elementDecimalOrZero(seg, n, delimiters, sink) {
|
|
953
|
+
const read = readElementDecimal(seg, n, delimiters);
|
|
954
|
+
if (read.status === "unparseable" && sink !== void 0) {
|
|
955
|
+
sink.warnings.push(unparseableDecimal({ ...sink.position, elementIndex: n }));
|
|
956
|
+
}
|
|
957
|
+
return read.value ?? X12Decimal.ZERO;
|
|
915
958
|
}
|
|
916
959
|
function collectElementValues(seg, start, end, delimiters) {
|
|
917
960
|
const out = [];
|
|
@@ -1417,6 +1460,7 @@ function defineLoopSpec(input) {
|
|
|
1417
1460
|
// src/code-lists/meta.ts
|
|
1418
1461
|
function makeLookup(snapshot) {
|
|
1419
1462
|
return (code) => {
|
|
1463
|
+
if (!Object.hasOwn(snapshot.codes, code)) return void 0;
|
|
1420
1464
|
const description = snapshot.codes[code];
|
|
1421
1465
|
if (description === void 0) return void 0;
|
|
1422
1466
|
return Object.freeze({ code, description });
|
|
@@ -1665,7 +1709,7 @@ var CLAIM_ADJUSTMENT_GROUP_CODES = {
|
|
|
1665
1709
|
PI: "PI"
|
|
1666
1710
|
};
|
|
1667
1711
|
function isClaimAdjustmentGroupCode(value) {
|
|
1668
|
-
return value
|
|
1712
|
+
return Object.hasOwn(CLAIM_ADJUSTMENT_GROUP_CODES, value);
|
|
1669
1713
|
}
|
|
1670
1714
|
|
|
1671
1715
|
// src/code-lists/rarc.ts
|
|
@@ -1805,6 +1849,7 @@ var HI_QUALIFIERS = {
|
|
|
1805
1849
|
}
|
|
1806
1850
|
};
|
|
1807
1851
|
function resolveHiQualifier(qualifier) {
|
|
1852
|
+
if (!Object.hasOwn(HI_QUALIFIERS, qualifier)) return void 0;
|
|
1808
1853
|
return HI_QUALIFIERS[qualifier];
|
|
1809
1854
|
}
|
|
1810
1855
|
function isDiagnosisQualifier(qualifier) {
|
|
@@ -1914,9 +1959,10 @@ function get835(delimiters, tx) {
|
|
|
1914
1959
|
const seg = body[i];
|
|
1915
1960
|
if (seg === void 0) continue;
|
|
1916
1961
|
const position = { segmentIndex: i + 1, transactionIndex: 0 };
|
|
1962
|
+
const sink = { warnings, position };
|
|
1917
1963
|
switch (seg.id) {
|
|
1918
1964
|
case "BPR": {
|
|
1919
|
-
payment = decodeBpr(seg, delimiters);
|
|
1965
|
+
payment = decodeBpr(seg, delimiters, sink);
|
|
1920
1966
|
bprSegmentIndex = position.segmentIndex;
|
|
1921
1967
|
break;
|
|
1922
1968
|
}
|
|
@@ -1991,7 +2037,7 @@ function get835(delimiters, tx) {
|
|
|
1991
2037
|
case "CLP": {
|
|
1992
2038
|
flushClaim();
|
|
1993
2039
|
lastParty = void 0;
|
|
1994
|
-
currentClaim = openClaim(seg, delimiters, position.segmentIndex);
|
|
2040
|
+
currentClaim = openClaim(seg, delimiters, position.segmentIndex, sink);
|
|
1995
2041
|
break;
|
|
1996
2042
|
}
|
|
1997
2043
|
case "CAS": {
|
|
@@ -2043,7 +2089,7 @@ function get835(delimiters, tx) {
|
|
|
2043
2089
|
break;
|
|
2044
2090
|
}
|
|
2045
2091
|
case "AMT": {
|
|
2046
|
-
const amount = decodeAmt(seg, delimiters);
|
|
2092
|
+
const amount = decodeAmt(seg, delimiters, sink);
|
|
2047
2093
|
if (amount === void 0) break;
|
|
2048
2094
|
if (currentServiceLine !== void 0) currentServiceLine.amounts.push(amount);
|
|
2049
2095
|
else if (currentClaim !== void 0) currentClaim.amounts.push(amount);
|
|
@@ -2062,12 +2108,12 @@ function get835(delimiters, tx) {
|
|
|
2062
2108
|
}
|
|
2063
2109
|
case "SVC": {
|
|
2064
2110
|
flushServiceLine();
|
|
2065
|
-
currentServiceLine = openServiceLine(seg, delimiters);
|
|
2111
|
+
currentServiceLine = openServiceLine(seg, delimiters, sink);
|
|
2066
2112
|
break;
|
|
2067
2113
|
}
|
|
2068
2114
|
case "PLB": {
|
|
2069
2115
|
flushClaim();
|
|
2070
|
-
for (const p of decodePlb(seg, delimiters)) providerAdjustments.push(p);
|
|
2116
|
+
for (const p of decodePlb(seg, delimiters, sink)) providerAdjustments.push(p);
|
|
2071
2117
|
break;
|
|
2072
2118
|
}
|
|
2073
2119
|
}
|
|
@@ -2098,10 +2144,10 @@ function get835(delimiters, tx) {
|
|
|
2098
2144
|
warnings: Object.freeze(warnings.slice())
|
|
2099
2145
|
});
|
|
2100
2146
|
}
|
|
2101
|
-
function decodeBpr(seg, delimiters) {
|
|
2147
|
+
function decodeBpr(seg, delimiters, sink) {
|
|
2102
2148
|
return Object.freeze({
|
|
2103
2149
|
transactionHandlingCode: elementValue(seg, 1, delimiters),
|
|
2104
|
-
totalActualPayment: elementDecimalOrZero(seg, 2, delimiters),
|
|
2150
|
+
totalActualPayment: elementDecimalOrZero(seg, 2, delimiters, sink),
|
|
2105
2151
|
creditDebitFlag: elementValue(seg, 3, delimiters),
|
|
2106
2152
|
method: elementValue(seg, 4, delimiters),
|
|
2107
2153
|
paymentFormatCode: elementOptional(seg, 5, delimiters),
|
|
@@ -2160,8 +2206,8 @@ function decodePer(seg, delimiters) {
|
|
|
2160
2206
|
communications: Object.freeze(comms)
|
|
2161
2207
|
});
|
|
2162
2208
|
}
|
|
2163
|
-
function decodeAmt(seg, delimiters) {
|
|
2164
|
-
const amount = elementDecimal(seg, 2, delimiters);
|
|
2209
|
+
function decodeAmt(seg, delimiters, sink) {
|
|
2210
|
+
const amount = elementDecimal(seg, 2, delimiters, sink);
|
|
2165
2211
|
if (amount === void 0) return void 0;
|
|
2166
2212
|
return Object.freeze({
|
|
2167
2213
|
qualifier: elementValue(seg, 1, delimiters),
|
|
@@ -2197,13 +2243,14 @@ function collectMoaRemarks(seg, delimiters) {
|
|
|
2197
2243
|
return out;
|
|
2198
2244
|
}
|
|
2199
2245
|
function decodeCasAdjustments(seg, delimiters, warnings, position) {
|
|
2246
|
+
const sink = { warnings, position };
|
|
2200
2247
|
const groupCode = elementValue(seg, 1, delimiters);
|
|
2201
2248
|
const out = [];
|
|
2202
2249
|
for (let triple = 0; triple < 6; triple += 1) {
|
|
2203
2250
|
const base = 2 + triple * 3;
|
|
2204
2251
|
const reasonCode = elementOptional(seg, base, delimiters);
|
|
2205
|
-
const amount = elementDecimal(seg, base + 1, delimiters);
|
|
2206
|
-
const quantity = elementDecimal(seg, base + 2, delimiters);
|
|
2252
|
+
const amount = elementDecimal(seg, base + 1, delimiters, sink);
|
|
2253
|
+
const quantity = elementDecimal(seg, base + 2, delimiters, sink);
|
|
2207
2254
|
if (reasonCode === void 0 && amount === void 0) continue;
|
|
2208
2255
|
const code = reasonCode ?? "";
|
|
2209
2256
|
const entry = code === "" ? void 0 : lookupCarc(code);
|
|
@@ -2247,7 +2294,7 @@ function decodeNm1(seg, delimiters) {
|
|
|
2247
2294
|
})
|
|
2248
2295
|
};
|
|
2249
2296
|
}
|
|
2250
|
-
function openClaim(seg, delimiters, clpSegmentIndex) {
|
|
2297
|
+
function openClaim(seg, delimiters, clpSegmentIndex, sink) {
|
|
2251
2298
|
const claimStatusCode = elementValue(seg, 2, delimiters);
|
|
2252
2299
|
const claimStatusDescription = lookupClpStatus(claimStatusCode)?.description;
|
|
2253
2300
|
const facilityTypeCode = componentOptional(seg, 8, 1, delimiters) ?? elementOptional(seg, 8, delimiters);
|
|
@@ -2257,9 +2304,9 @@ function openClaim(seg, delimiters, clpSegmentIndex) {
|
|
|
2257
2304
|
patientControlNumber: elementValue(seg, 1, delimiters),
|
|
2258
2305
|
claimStatusCode,
|
|
2259
2306
|
claimStatusDescription,
|
|
2260
|
-
totalChargeAmount: elementDecimalOrZero(seg, 3, delimiters),
|
|
2261
|
-
totalPaymentAmount: elementDecimalOrZero(seg, 4, delimiters),
|
|
2262
|
-
patientResponsibilityAmount: elementDecimalOrZero(seg, 5, delimiters),
|
|
2307
|
+
totalChargeAmount: elementDecimalOrZero(seg, 3, delimiters, sink),
|
|
2308
|
+
totalPaymentAmount: elementDecimalOrZero(seg, 4, delimiters, sink),
|
|
2309
|
+
patientResponsibilityAmount: elementDecimalOrZero(seg, 5, delimiters, sink),
|
|
2263
2310
|
claimFilingIndicatorCode: elementOptional(seg, 6, delimiters),
|
|
2264
2311
|
payerClaimControlNumber: elementOptional(seg, 7, delimiters),
|
|
2265
2312
|
facilityTypeCode,
|
|
@@ -2278,7 +2325,7 @@ function openClaim(seg, delimiters, clpSegmentIndex) {
|
|
|
2278
2325
|
serviceLines: []
|
|
2279
2326
|
};
|
|
2280
2327
|
}
|
|
2281
|
-
function openServiceLine(seg, delimiters) {
|
|
2328
|
+
function openServiceLine(seg, delimiters, sink) {
|
|
2282
2329
|
const productServiceIdQualifier = componentOptional(seg, 1, 1, delimiters) ?? "";
|
|
2283
2330
|
const productServiceId = componentOptional(seg, 1, 2, delimiters) ?? "";
|
|
2284
2331
|
const modifiers = [];
|
|
@@ -2286,18 +2333,20 @@ function openServiceLine(seg, delimiters) {
|
|
|
2286
2333
|
const m = componentOptional(seg, 1, comp, delimiters);
|
|
2287
2334
|
if (m !== void 0) modifiers.push(m);
|
|
2288
2335
|
}
|
|
2289
|
-
const revenueCode = elementOptional(seg,
|
|
2290
|
-
const paidUnitsOfService = elementDecimal(seg,
|
|
2336
|
+
const revenueCode = elementOptional(seg, 4, delimiters);
|
|
2337
|
+
const paidUnitsOfService = elementDecimal(seg, 5, delimiters, sink);
|
|
2338
|
+
const originalUnitsOfService = elementDecimal(seg, 7, delimiters, sink);
|
|
2291
2339
|
const originalServiceIdQualifier = componentOptional(seg, 6, 1, delimiters);
|
|
2292
2340
|
const originalServiceId = componentOptional(seg, 6, 2, delimiters);
|
|
2293
2341
|
return {
|
|
2294
2342
|
productServiceIdQualifier,
|
|
2295
2343
|
productServiceId,
|
|
2296
2344
|
modifiers,
|
|
2297
|
-
chargeAmount: elementDecimalOrZero(seg, 2, delimiters),
|
|
2298
|
-
paymentAmount: elementDecimalOrZero(seg, 3, delimiters),
|
|
2345
|
+
chargeAmount: elementDecimalOrZero(seg, 2, delimiters, sink),
|
|
2346
|
+
paymentAmount: elementDecimalOrZero(seg, 3, delimiters, sink),
|
|
2299
2347
|
revenueCode,
|
|
2300
2348
|
paidUnitsOfService,
|
|
2349
|
+
originalUnitsOfService,
|
|
2301
2350
|
originalServiceId,
|
|
2302
2351
|
originalServiceIdQualifier,
|
|
2303
2352
|
serviceDateStart: void 0,
|
|
@@ -2323,13 +2372,13 @@ function attachServiceLineDtm(line, seg, delimiters) {
|
|
|
2323
2372
|
if (qualifier === "472" || qualifier === "150") line.serviceDateStart = date;
|
|
2324
2373
|
if (qualifier === "472" || qualifier === "151") line.serviceDateEnd = date;
|
|
2325
2374
|
}
|
|
2326
|
-
function decodePlb(seg, delimiters) {
|
|
2375
|
+
function decodePlb(seg, delimiters, sink) {
|
|
2327
2376
|
const providerId = elementValue(seg, 1, delimiters);
|
|
2328
2377
|
const fiscalPeriodDate = elementValue(seg, 2, delimiters);
|
|
2329
2378
|
const out = [];
|
|
2330
2379
|
for (let pair = 0; pair < 6; pair += 1) {
|
|
2331
2380
|
const composite = 3 + pair * 2;
|
|
2332
|
-
const amount = elementDecimal(seg, composite + 1, delimiters);
|
|
2381
|
+
const amount = elementDecimal(seg, composite + 1, delimiters, sink);
|
|
2333
2382
|
const reasonCode = componentOptional(seg, composite, 1, delimiters);
|
|
2334
2383
|
const subCode = componentOptional(seg, composite, 2, delimiters);
|
|
2335
2384
|
if (amount === void 0 && reasonCode === void 0) continue;
|
|
@@ -2393,6 +2442,7 @@ function freezeServiceLine(acc) {
|
|
|
2393
2442
|
paymentAmount: acc.paymentAmount,
|
|
2394
2443
|
revenueCode: acc.revenueCode,
|
|
2395
2444
|
paidUnitsOfService: acc.paidUnitsOfService,
|
|
2445
|
+
originalUnitsOfService: acc.originalUnitsOfService,
|
|
2396
2446
|
originalServiceId: acc.originalServiceId,
|
|
2397
2447
|
originalServiceIdQualifier: acc.originalServiceIdQualifier,
|
|
2398
2448
|
serviceDateStart: acc.serviceDateStart,
|
|
@@ -2508,10 +2558,75 @@ function isRealArray(value) {
|
|
|
2508
2558
|
return Array.isArray(value);
|
|
2509
2559
|
}
|
|
2510
2560
|
|
|
2561
|
+
// src/builder/caller-decimal.ts
|
|
2562
|
+
function describeCallerDecimal(value) {
|
|
2563
|
+
if (value === null) return "null";
|
|
2564
|
+
if (value === void 0) return "undefined";
|
|
2565
|
+
const type = typeof value;
|
|
2566
|
+
if (type === "object") return Array.isArray(value) ? "an array" : "an object";
|
|
2567
|
+
if (type === "function") return "a function";
|
|
2568
|
+
return `a ${type} (${renderCallerValue(value)})`;
|
|
2569
|
+
}
|
|
2570
|
+
function requireCallerDecimal(value, at, refuse) {
|
|
2571
|
+
if (value instanceof X12Decimal) return value;
|
|
2572
|
+
refuse(
|
|
2573
|
+
`${at}: every numeric element value must be an X12Decimal, but received ${describeCallerDecimal(value)}. Values are never coerced - a JavaScript number has no X12 lexical form (0.1 + 0.2 renders as "0.30000000000000004", 1e21 as "1e+21", NaN as "NaN"), and rounding one here would guess a scale the caller never stated. Build it with X12Decimal.fromString() at the call site.`
|
|
2574
|
+
);
|
|
2575
|
+
}
|
|
2576
|
+
|
|
2577
|
+
// src/builder/caller-segment.ts
|
|
2578
|
+
function describeSegmentValue(value) {
|
|
2579
|
+
if (value === null) return "null";
|
|
2580
|
+
if (value === void 0) return "undefined";
|
|
2581
|
+
const type = typeof value;
|
|
2582
|
+
if (type === "object") return Array.isArray(value) ? "an array" : "an object";
|
|
2583
|
+
if (type === "function") return "a function";
|
|
2584
|
+
return `a ${type} (${renderCallerValue(value)})`;
|
|
2585
|
+
}
|
|
2586
|
+
function locateSlot(parts, index) {
|
|
2587
|
+
const id = parts[0];
|
|
2588
|
+
const position = String(index).padStart(2, "0");
|
|
2589
|
+
if (typeof id !== "string" || id.length === 0) return `element ${String(index)}`;
|
|
2590
|
+
return `${renderCallerValue(id)}-${position}`;
|
|
2591
|
+
}
|
|
2592
|
+
function requireCallerSegment(parts, at, refuse) {
|
|
2593
|
+
let index = 0;
|
|
2594
|
+
for (const part of parts) {
|
|
2595
|
+
if (typeof part !== "string") {
|
|
2596
|
+
refuse(
|
|
2597
|
+
`${at}: ${locateSlot(parts, index)} must be a string, but received ${describeSegmentValue(part)}. Values are never coerced - a JavaScript number cannot carry a leading-zero identifier, so converting here could emit a different value than the caller sent. Convert at the call site.`
|
|
2598
|
+
);
|
|
2599
|
+
}
|
|
2600
|
+
index += 1;
|
|
2601
|
+
}
|
|
2602
|
+
}
|
|
2603
|
+
|
|
2604
|
+
// src/builder/caller-string.ts
|
|
2605
|
+
function describeCallerValue(value) {
|
|
2606
|
+
if (value === null) return "null";
|
|
2607
|
+
if (value === void 0) return "undefined";
|
|
2608
|
+
const type = typeof value;
|
|
2609
|
+
if (type === "object") return Array.isArray(value) ? "an array" : "an object";
|
|
2610
|
+
if (type === "function") return "a function";
|
|
2611
|
+
return `a ${type} (${renderCallerValue(value)})`;
|
|
2612
|
+
}
|
|
2613
|
+
function requireCallerString(value, at, refuse) {
|
|
2614
|
+
if (typeof value === "string") return value;
|
|
2615
|
+
refuse(
|
|
2616
|
+
`${at}: every element value must be a string, but received ${describeCallerValue(value)}. Values are never coerced - a JavaScript number cannot carry a leading-zero identifier, so converting here could emit a different value than the caller sent. Convert at the call site.`
|
|
2617
|
+
);
|
|
2618
|
+
}
|
|
2619
|
+
function makeCallerEscaper(delimiters, at, refuse) {
|
|
2620
|
+
return (value) => escapeRelease(requireCallerString(value, at, refuse), delimiters);
|
|
2621
|
+
}
|
|
2622
|
+
|
|
2511
2623
|
// src/transactions/remit/build-835.ts
|
|
2512
2624
|
function refuseSpec(message) {
|
|
2513
2625
|
throw new Remit835BuildError(REMIT_835_BUILD_ERROR_CODES.X12_835_BUILD_INVALID_SPEC, message);
|
|
2514
2626
|
}
|
|
2627
|
+
function escDec(value, esc) {
|
|
2628
|
+
return esc(requireCallerDecimal(value, "build835", refuseSpec).toString());
|
|
2629
|
+
}
|
|
2515
2630
|
var X221A1_VERSION_RELEASE = "005010X221A1";
|
|
2516
2631
|
var X12_835_FUNCTIONAL_ID = "HP";
|
|
2517
2632
|
var X12_AGENCY_CODE = "X";
|
|
@@ -2533,8 +2648,9 @@ function build835(spec) {
|
|
|
2533
2648
|
component: componentSeparator,
|
|
2534
2649
|
segment: segmentTerminator
|
|
2535
2650
|
};
|
|
2536
|
-
const esc = (
|
|
2651
|
+
const esc = makeCallerEscaper(delimiters, "build835", refuseSpec);
|
|
2537
2652
|
const seg = (parts) => {
|
|
2653
|
+
requireCallerSegment(parts, "build835", refuseSpec);
|
|
2538
2654
|
let end = parts.length;
|
|
2539
2655
|
while (end > 1 && parts[end - 1] === "") end -= 1;
|
|
2540
2656
|
return parts.slice(0, end).join(elementSeparator) + segmentTerminator;
|
|
@@ -2596,9 +2712,9 @@ function build835(spec) {
|
|
|
2596
2712
|
// GS-02
|
|
2597
2713
|
esc(applicationReceiverCode),
|
|
2598
2714
|
// GS-03
|
|
2599
|
-
groupDate,
|
|
2715
|
+
esc(groupDate),
|
|
2600
2716
|
// GS-04 - CCYYMMDD
|
|
2601
|
-
groupTime,
|
|
2717
|
+
esc(groupTime),
|
|
2602
2718
|
// GS-05 - HHMM
|
|
2603
2719
|
esc(envelope.groupControlNumber),
|
|
2604
2720
|
// GS-06
|
|
@@ -2614,7 +2730,7 @@ function build835(spec) {
|
|
|
2614
2730
|
seg([
|
|
2615
2731
|
"BPR",
|
|
2616
2732
|
esc(spec.payment.transactionHandlingCode),
|
|
2617
|
-
|
|
2733
|
+
escDec(spec.payment.totalActualPayment, esc),
|
|
2618
2734
|
esc(spec.payment.creditDebitFlag),
|
|
2619
2735
|
esc(spec.payment.method),
|
|
2620
2736
|
esc(spec.payment.paymentFormatCode ?? ""),
|
|
@@ -2749,6 +2865,7 @@ function materializeServiceLine(spec) {
|
|
|
2749
2865
|
paymentAmount: spec.paymentAmount,
|
|
2750
2866
|
revenueCode: spec.revenueCode,
|
|
2751
2867
|
paidUnitsOfService: spec.paidUnitsOfService,
|
|
2868
|
+
originalUnitsOfService: spec.originalUnitsOfService,
|
|
2752
2869
|
originalServiceId: spec.originalServiceId,
|
|
2753
2870
|
originalServiceIdQualifier: spec.originalServiceIdQualifier,
|
|
2754
2871
|
serviceDateStart: spec.serviceDateStart,
|
|
@@ -2844,9 +2961,9 @@ function emitClaim(claim, body, seg, esc, comp) {
|
|
|
2844
2961
|
"CLP",
|
|
2845
2962
|
esc(claim.patientControlNumber),
|
|
2846
2963
|
esc(claim.claimStatusCode),
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2964
|
+
escDec(claim.totalChargeAmount, esc),
|
|
2965
|
+
escDec(claim.totalPaymentAmount, esc),
|
|
2966
|
+
escDec(claim.patientResponsibilityAmount, esc),
|
|
2850
2967
|
esc(claim.claimFilingIndicatorCode ?? ""),
|
|
2851
2968
|
esc(claim.payerClaimControlNumber ?? ""),
|
|
2852
2969
|
comp([claim.facilityTypeCode ?? "", "", claim.claimFrequencyCode ?? ""])
|
|
@@ -2868,7 +2985,7 @@ function emitClaim(claim, body, seg, esc, comp) {
|
|
|
2868
2985
|
}
|
|
2869
2986
|
for (const ref of claim.references ?? []) body.push(emitRef(ref, seg, esc));
|
|
2870
2987
|
for (const amt of claim.amounts ?? []) {
|
|
2871
|
-
body.push(seg(["AMT", esc(amt.qualifier),
|
|
2988
|
+
body.push(seg(["AMT", esc(amt.qualifier), escDec(amt.amount, esc)]));
|
|
2872
2989
|
}
|
|
2873
2990
|
for (const remark of claim.remarks ?? []) {
|
|
2874
2991
|
body.push(seg(["LQ", esc(remark.system), esc(remark.code)]));
|
|
@@ -2888,20 +3005,24 @@ function emitServiceLine(line, body, seg, esc, comp) {
|
|
|
2888
3005
|
seg([
|
|
2889
3006
|
"SVC",
|
|
2890
3007
|
svc01,
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
// SVC-
|
|
3008
|
+
escDec(line.chargeAmount, esc),
|
|
3009
|
+
escDec(line.paymentAmount, esc),
|
|
3010
|
+
// SVC-04 is the NUBC revenue code (element 234, Product/Service ID) and
|
|
3011
|
+
// SVC-05 is the Units of Service PAID Count (element 380, Quantity).
|
|
3012
|
+
// SVC-07 is the ORIGINAL (submitted) units, a different quantity from
|
|
3013
|
+
// SVC-05 - so the two never share a field. See the SVC note in
|
|
3014
|
+
// KNOWN-LIMITATIONS.md for the sources.
|
|
2895
3015
|
esc(line.revenueCode ?? ""),
|
|
3016
|
+
line.paidUnitsOfService === void 0 ? "" : escDec(line.paidUnitsOfService, esc),
|
|
2896
3017
|
svc06,
|
|
2897
|
-
line.
|
|
3018
|
+
line.originalUnitsOfService === void 0 ? "" : escDec(line.originalUnitsOfService, esc)
|
|
2898
3019
|
])
|
|
2899
3020
|
);
|
|
2900
3021
|
emitServiceLineDtm(line, body, seg, esc);
|
|
2901
3022
|
emitCasGroup(line.adjustments, "build835: serviceLine.adjustments", body, seg, esc);
|
|
2902
3023
|
for (const ref of line.references ?? []) body.push(emitRef(ref, seg, esc));
|
|
2903
3024
|
for (const amt of line.amounts ?? []) {
|
|
2904
|
-
body.push(seg(["AMT", esc(amt.qualifier),
|
|
3025
|
+
body.push(seg(["AMT", esc(amt.qualifier), escDec(amt.amount, esc)]));
|
|
2905
3026
|
}
|
|
2906
3027
|
for (const remark of line.remarks ?? []) {
|
|
2907
3028
|
body.push(seg(["LQ", esc(remark.system), esc(remark.code)]));
|
|
@@ -2933,8 +3054,8 @@ function emitCasGroup(raw, at, body, seg, esc) {
|
|
|
2933
3054
|
if (adj === void 0 || adj.groupCode !== groupCode) break;
|
|
2934
3055
|
parts.push(
|
|
2935
3056
|
esc(adj.reasonCode),
|
|
2936
|
-
|
|
2937
|
-
adj.quantity === void 0 ? "" :
|
|
3057
|
+
escDec(adj.amount, esc),
|
|
3058
|
+
adj.quantity === void 0 ? "" : escDec(adj.quantity, esc)
|
|
2938
3059
|
);
|
|
2939
3060
|
triples += 1;
|
|
2940
3061
|
i += 1;
|
|
@@ -2992,7 +3113,7 @@ function emitProviderAdjustments(raw, at, body, seg, esc, comp) {
|
|
|
2992
3113
|
if (adj === void 0 || adj.providerId !== providerId || adj.fiscalPeriodDate !== fiscalPeriodDate) {
|
|
2993
3114
|
break;
|
|
2994
3115
|
}
|
|
2995
|
-
parts.push(comp([adj.reasonCode, adj.subCode ?? ""]),
|
|
3116
|
+
parts.push(comp([adj.reasonCode, adj.subCode ?? ""]), escDec(adj.amount, esc));
|
|
2996
3117
|
pairs += 1;
|
|
2997
3118
|
i += 1;
|
|
2998
3119
|
}
|
|
@@ -3090,13 +3211,22 @@ var REMIT_835_LOOP_1000B = defineLoopSpec({
|
|
|
3090
3211
|
]
|
|
3091
3212
|
});
|
|
3092
3213
|
|
|
3214
|
+
// src/parser/lookup.ts
|
|
3215
|
+
function wireLookup(entries) {
|
|
3216
|
+
const table = /* @__PURE__ */ Object.create(null);
|
|
3217
|
+
for (const [key, value] of Object.entries(entries)) {
|
|
3218
|
+
table[key] = value;
|
|
3219
|
+
}
|
|
3220
|
+
return Object.freeze(table);
|
|
3221
|
+
}
|
|
3222
|
+
|
|
3093
3223
|
// src/transactions/claim/get-837.ts
|
|
3094
|
-
var VARIANT_BY_ICR =
|
|
3224
|
+
var VARIANT_BY_ICR = wireLookup({
|
|
3095
3225
|
"005010X222A2": "P",
|
|
3096
3226
|
"005010X223A3": "I",
|
|
3097
3227
|
"005010X224A2": "D"
|
|
3098
3228
|
});
|
|
3099
|
-
var VARIANT_BY_SV_SEGMENT =
|
|
3229
|
+
var VARIANT_BY_SV_SEGMENT = wireLookup({
|
|
3100
3230
|
SV1: "P",
|
|
3101
3231
|
SV2: "I",
|
|
3102
3232
|
SV3: "D"
|
|
@@ -3117,7 +3247,7 @@ var NM1_QUALIFIERS = Object.freeze({
|
|
|
3117
3247
|
PAYER: "PR",
|
|
3118
3248
|
PATIENT: "QC"
|
|
3119
3249
|
});
|
|
3120
|
-
var EXPECTED_PARENT_LEVEL =
|
|
3250
|
+
var EXPECTED_PARENT_LEVEL = wireLookup({
|
|
3121
3251
|
[HL_LEVEL_CODES.INFORMATION_SOURCE]: void 0,
|
|
3122
3252
|
[HL_LEVEL_CODES.SUBSCRIBER]: HL_LEVEL_CODES.INFORMATION_SOURCE,
|
|
3123
3253
|
[HL_LEVEL_CODES.DEPENDENT]: HL_LEVEL_CODES.SUBSCRIBER
|
|
@@ -3172,6 +3302,9 @@ function get837Claims(delimiters, tx, opts) {
|
|
|
3172
3302
|
const flushServiceLine = () => {
|
|
3173
3303
|
flushAdjudication();
|
|
3174
3304
|
if (currentServiceLine !== void 0 && currentClaim !== void 0) {
|
|
3305
|
+
if (!currentServiceLine.serviceSegmentDecoded) {
|
|
3306
|
+
warnings.push(serviceLineNotDecoded(currentServiceLine.position));
|
|
3307
|
+
}
|
|
3175
3308
|
currentClaim.serviceLines.push(freezeServiceLine2(currentServiceLine));
|
|
3176
3309
|
}
|
|
3177
3310
|
currentServiceLine = void 0;
|
|
@@ -3245,6 +3378,7 @@ function get837Claims(delimiters, tx, opts) {
|
|
|
3245
3378
|
const seg = body[i];
|
|
3246
3379
|
if (seg === void 0) continue;
|
|
3247
3380
|
const position = { segmentIndex: i + 1, transactionIndex: 0 };
|
|
3381
|
+
const sink = { warnings, position };
|
|
3248
3382
|
switch (seg.id) {
|
|
3249
3383
|
case "HL": {
|
|
3250
3384
|
flushClaim();
|
|
@@ -3392,16 +3526,21 @@ function get837Claims(delimiters, tx, opts) {
|
|
|
3392
3526
|
warnings.push(missingRequiredLoop(position, REQUIRED_LOOPS.PAYER_NAME_2010BB));
|
|
3393
3527
|
}
|
|
3394
3528
|
}
|
|
3395
|
-
currentClaim = openClaim2(
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3529
|
+
currentClaim = openClaim2(
|
|
3530
|
+
seg,
|
|
3531
|
+
delimiters,
|
|
3532
|
+
{
|
|
3533
|
+
variant,
|
|
3534
|
+
hierarchy: currentPatientHl ?? currentSubscriberHl,
|
|
3535
|
+
billingProvider,
|
|
3536
|
+
payToAddress,
|
|
3537
|
+
payToPlan,
|
|
3538
|
+
subscriber: currentSubscriberMember,
|
|
3539
|
+
payer: currentPayer,
|
|
3540
|
+
patient: currentPatientMember
|
|
3541
|
+
},
|
|
3542
|
+
sink
|
|
3543
|
+
);
|
|
3405
3544
|
activeEntity = void 0;
|
|
3406
3545
|
context = { kind: "loop2300" };
|
|
3407
3546
|
break;
|
|
@@ -3440,7 +3579,7 @@ function get837Claims(delimiters, tx, opts) {
|
|
|
3440
3579
|
break;
|
|
3441
3580
|
}
|
|
3442
3581
|
case "AMT": {
|
|
3443
|
-
const amount = decodeAmt2(seg, delimiters);
|
|
3582
|
+
const amount = decodeAmt2(seg, delimiters, sink);
|
|
3444
3583
|
if (amount === void 0) break;
|
|
3445
3584
|
if (currentAdjudication !== void 0) break;
|
|
3446
3585
|
if (currentServiceLine !== void 0) currentServiceLine.amounts.push(amount);
|
|
@@ -3449,22 +3588,26 @@ function get837Claims(delimiters, tx, opts) {
|
|
|
3449
3588
|
}
|
|
3450
3589
|
case "LX": {
|
|
3451
3590
|
flushServiceLine();
|
|
3452
|
-
if (currentClaim === void 0)
|
|
3453
|
-
|
|
3591
|
+
if (currentClaim === void 0) {
|
|
3592
|
+
warnings.push(serviceLineDropped(position));
|
|
3593
|
+
break;
|
|
3594
|
+
}
|
|
3595
|
+
currentServiceLine = openServiceLine2(seg, delimiters, currentClaim.variant, position);
|
|
3596
|
+
if (currentServiceLine === void 0) warnings.push(serviceLineDropped(position));
|
|
3454
3597
|
activeEntity = void 0;
|
|
3455
3598
|
context = { kind: "loop2400" };
|
|
3456
3599
|
break;
|
|
3457
3600
|
}
|
|
3458
3601
|
case "SV1": {
|
|
3459
|
-
if (currentServiceLine !== void 0) decodeSv1(currentServiceLine, seg, delimiters);
|
|
3602
|
+
if (currentServiceLine !== void 0) decodeSv1(currentServiceLine, seg, delimiters, sink);
|
|
3460
3603
|
break;
|
|
3461
3604
|
}
|
|
3462
3605
|
case "SV2": {
|
|
3463
|
-
if (currentServiceLine !== void 0) decodeSv2(currentServiceLine, seg, delimiters);
|
|
3606
|
+
if (currentServiceLine !== void 0) decodeSv2(currentServiceLine, seg, delimiters, sink);
|
|
3464
3607
|
break;
|
|
3465
3608
|
}
|
|
3466
3609
|
case "SV3": {
|
|
3467
|
-
if (currentServiceLine !== void 0) decodeSv3(currentServiceLine, seg, delimiters);
|
|
3610
|
+
if (currentServiceLine !== void 0) decodeSv3(currentServiceLine, seg, delimiters, sink);
|
|
3468
3611
|
break;
|
|
3469
3612
|
}
|
|
3470
3613
|
case "TOO": {
|
|
@@ -3490,7 +3633,7 @@ function get837Claims(delimiters, tx, opts) {
|
|
|
3490
3633
|
}
|
|
3491
3634
|
currentServiceLine.drug = {
|
|
3492
3635
|
...currentServiceLine.drug,
|
|
3493
|
-
quantity: elementDecimal(seg, 4, delimiters),
|
|
3636
|
+
quantity: elementDecimal(seg, 4, delimiters, sink),
|
|
3494
3637
|
unitOfMeasure: componentOptional(seg, 5, 1, delimiters)
|
|
3495
3638
|
};
|
|
3496
3639
|
break;
|
|
@@ -3498,7 +3641,7 @@ function get837Claims(delimiters, tx, opts) {
|
|
|
3498
3641
|
case "SVD": {
|
|
3499
3642
|
flushAdjudication();
|
|
3500
3643
|
if (currentServiceLine === void 0) break;
|
|
3501
|
-
currentAdjudication = openAdjudication(seg, delimiters);
|
|
3644
|
+
currentAdjudication = openAdjudication(seg, delimiters, sink);
|
|
3502
3645
|
break;
|
|
3503
3646
|
}
|
|
3504
3647
|
case "CAS": {
|
|
@@ -3676,19 +3819,20 @@ function decodeNte(seg, delimiters) {
|
|
|
3676
3819
|
description: note
|
|
3677
3820
|
});
|
|
3678
3821
|
}
|
|
3679
|
-
function decodeAmt2(seg, delimiters) {
|
|
3680
|
-
const amount = elementDecimal(seg, 2, delimiters);
|
|
3822
|
+
function decodeAmt2(seg, delimiters, sink) {
|
|
3823
|
+
const amount = elementDecimal(seg, 2, delimiters, sink);
|
|
3681
3824
|
if (amount === void 0) return void 0;
|
|
3682
3825
|
return Object.freeze({ qualifier: elementValue(seg, 1, delimiters), amount });
|
|
3683
3826
|
}
|
|
3684
3827
|
function decodeCas(seg, delimiters, warnings, position) {
|
|
3828
|
+
const sink = { warnings, position };
|
|
3685
3829
|
const groupCode = elementValue(seg, 1, delimiters);
|
|
3686
3830
|
const out = [];
|
|
3687
3831
|
for (let triple = 0; triple < 6; triple += 1) {
|
|
3688
3832
|
const base = 2 + triple * 3;
|
|
3689
3833
|
const reasonCode = elementOptional(seg, base, delimiters);
|
|
3690
|
-
const amount = elementDecimal(seg, base + 1, delimiters);
|
|
3691
|
-
const quantity = elementDecimal(seg, base + 2, delimiters);
|
|
3834
|
+
const amount = elementDecimal(seg, base + 1, delimiters, sink);
|
|
3835
|
+
const quantity = elementDecimal(seg, base + 2, delimiters, sink);
|
|
3692
3836
|
if (reasonCode === void 0 && amount === void 0) continue;
|
|
3693
3837
|
const code = reasonCode ?? "";
|
|
3694
3838
|
const entry = code === "" ? void 0 : lookupCarc(code);
|
|
@@ -3723,7 +3867,7 @@ var EMPTY_SUBSCRIBER_INFO = Object.freeze({
|
|
|
3723
3867
|
groupName: void 0,
|
|
3724
3868
|
claimFilingIndicator: void 0
|
|
3725
3869
|
});
|
|
3726
|
-
function openClaim2(seg, delimiters, ctx) {
|
|
3870
|
+
function openClaim2(seg, delimiters, ctx, sink) {
|
|
3727
3871
|
const {
|
|
3728
3872
|
variant,
|
|
3729
3873
|
hierarchy,
|
|
@@ -3744,7 +3888,7 @@ function openClaim2(seg, delimiters, ctx) {
|
|
|
3744
3888
|
payer,
|
|
3745
3889
|
patient,
|
|
3746
3890
|
claimId: elementValue(seg, 1, delimiters),
|
|
3747
|
-
totalCharge: elementDecimalOrZero(seg, 2, delimiters),
|
|
3891
|
+
totalCharge: elementDecimalOrZero(seg, 2, delimiters, sink),
|
|
3748
3892
|
placeOfServiceCode: componentOptional(seg, 5, 1, delimiters),
|
|
3749
3893
|
facilityCodeQualifier: componentOptional(seg, 5, 2, delimiters),
|
|
3750
3894
|
claimFrequencyCode: componentOptional(seg, 5, 3, delimiters),
|
|
@@ -3764,10 +3908,12 @@ function openClaim2(seg, delimiters, ctx) {
|
|
|
3764
3908
|
serviceLines: []
|
|
3765
3909
|
};
|
|
3766
3910
|
}
|
|
3767
|
-
function openServiceLine2(seg, delimiters, variant) {
|
|
3911
|
+
function openServiceLine2(seg, delimiters, variant, position) {
|
|
3768
3912
|
const lineNumber = elementValue(seg, 1, delimiters);
|
|
3769
3913
|
const base = {
|
|
3770
3914
|
lineNumber,
|
|
3915
|
+
position,
|
|
3916
|
+
serviceSegmentDecoded: false,
|
|
3771
3917
|
charge: X12Decimal.ZERO,
|
|
3772
3918
|
units: X12Decimal.ZERO,
|
|
3773
3919
|
unitOfMeasure: void 0,
|
|
@@ -3819,8 +3965,9 @@ function openServiceLine2(seg, delimiters, variant) {
|
|
|
3819
3965
|
}
|
|
3820
3966
|
return void 0;
|
|
3821
3967
|
}
|
|
3822
|
-
function decodeSv1(acc, seg, delimiters) {
|
|
3968
|
+
function decodeSv1(acc, seg, delimiters, sink) {
|
|
3823
3969
|
if (acc.variant !== "P") return;
|
|
3970
|
+
acc.serviceSegmentDecoded = true;
|
|
3824
3971
|
acc.procedureQualifier = componentOptional(seg, 1, 1, delimiters) ?? "";
|
|
3825
3972
|
acc.procedureCode = componentOptional(seg, 1, 2, delimiters) ?? "";
|
|
3826
3973
|
const mods = [];
|
|
@@ -3829,9 +3976,9 @@ function decodeSv1(acc, seg, delimiters) {
|
|
|
3829
3976
|
if (m !== void 0) mods.push(m);
|
|
3830
3977
|
}
|
|
3831
3978
|
acc.modifiers = mods;
|
|
3832
|
-
acc.charge = elementDecimalOrZero(seg, 2, delimiters);
|
|
3979
|
+
acc.charge = elementDecimalOrZero(seg, 2, delimiters, sink);
|
|
3833
3980
|
acc.unitOfMeasure = elementOptional(seg, 3, delimiters);
|
|
3834
|
-
acc.units = elementDecimalOrZero(seg, 4, delimiters);
|
|
3981
|
+
acc.units = elementDecimalOrZero(seg, 4, delimiters, sink);
|
|
3835
3982
|
acc.placeOfServiceCode = elementOptional(seg, 5, delimiters);
|
|
3836
3983
|
const pointers = [];
|
|
3837
3984
|
for (let p = 1; p <= 4; p += 1) {
|
|
@@ -3843,8 +3990,9 @@ function decodeSv1(acc, seg, delimiters) {
|
|
|
3843
3990
|
acc.epsdtIndicator = elementOptional(seg, 11, delimiters);
|
|
3844
3991
|
acc.familyPlanningIndicator = elementOptional(seg, 12, delimiters);
|
|
3845
3992
|
}
|
|
3846
|
-
function decodeSv2(acc, seg, delimiters) {
|
|
3993
|
+
function decodeSv2(acc, seg, delimiters, sink) {
|
|
3847
3994
|
if (acc.variant !== "I") return;
|
|
3995
|
+
acc.serviceSegmentDecoded = true;
|
|
3848
3996
|
acc.revenueCode = elementValue(seg, 1, delimiters);
|
|
3849
3997
|
acc.procedureQualifier = componentOptional(seg, 2, 1, delimiters);
|
|
3850
3998
|
acc.procedureCode = componentOptional(seg, 2, 2, delimiters);
|
|
@@ -3854,14 +4002,15 @@ function decodeSv2(acc, seg, delimiters) {
|
|
|
3854
4002
|
if (m !== void 0) mods.push(m);
|
|
3855
4003
|
}
|
|
3856
4004
|
acc.modifiers = mods;
|
|
3857
|
-
acc.charge = elementDecimalOrZero(seg, 3, delimiters);
|
|
4005
|
+
acc.charge = elementDecimalOrZero(seg, 3, delimiters, sink);
|
|
3858
4006
|
acc.unitOfMeasure = elementOptional(seg, 4, delimiters);
|
|
3859
|
-
acc.units = elementDecimalOrZero(seg, 5, delimiters);
|
|
3860
|
-
acc.serviceLineRate = elementDecimal(seg, 6, delimiters);
|
|
3861
|
-
acc.nonCoveredCharge = elementDecimal(seg, 7, delimiters);
|
|
4007
|
+
acc.units = elementDecimalOrZero(seg, 5, delimiters, sink);
|
|
4008
|
+
acc.serviceLineRate = elementDecimal(seg, 6, delimiters, sink);
|
|
4009
|
+
acc.nonCoveredCharge = elementDecimal(seg, 7, delimiters, sink);
|
|
3862
4010
|
}
|
|
3863
|
-
function decodeSv3(acc, seg, delimiters) {
|
|
4011
|
+
function decodeSv3(acc, seg, delimiters, sink) {
|
|
3864
4012
|
if (acc.variant !== "D") return;
|
|
4013
|
+
acc.serviceSegmentDecoded = true;
|
|
3865
4014
|
acc.procedureQualifier = componentOptional(seg, 1, 1, delimiters) ?? "";
|
|
3866
4015
|
acc.procedureCode = componentOptional(seg, 1, 2, delimiters) ?? "";
|
|
3867
4016
|
const mods = [];
|
|
@@ -3870,7 +4019,7 @@ function decodeSv3(acc, seg, delimiters) {
|
|
|
3870
4019
|
if (m !== void 0) mods.push(m);
|
|
3871
4020
|
}
|
|
3872
4021
|
acc.modifiers = mods;
|
|
3873
|
-
acc.charge = elementDecimalOrZero(seg, 2, delimiters);
|
|
4022
|
+
acc.charge = elementDecimalOrZero(seg, 2, delimiters, sink);
|
|
3874
4023
|
acc.placeOfServiceCode = elementOptional(seg, 3, delimiters);
|
|
3875
4024
|
const cavities = [];
|
|
3876
4025
|
for (let p = 1; p <= 5; p += 1) {
|
|
@@ -3879,15 +4028,15 @@ function decodeSv3(acc, seg, delimiters) {
|
|
|
3879
4028
|
}
|
|
3880
4029
|
acc.oralCavityArea = cavities;
|
|
3881
4030
|
acc.prosthesisCrownInlayCode = elementOptional(seg, 5, delimiters);
|
|
3882
|
-
acc.units = elementDecimalOrZero(seg, 6, delimiters);
|
|
4031
|
+
acc.units = elementDecimalOrZero(seg, 6, delimiters, sink);
|
|
3883
4032
|
}
|
|
3884
|
-
function openAdjudication(seg, delimiters) {
|
|
4033
|
+
function openAdjudication(seg, delimiters, sink) {
|
|
3885
4034
|
return {
|
|
3886
4035
|
otherPayerId: elementValue(seg, 1, delimiters),
|
|
3887
|
-
amountPaid: elementDecimalOrZero(seg, 2, delimiters),
|
|
4036
|
+
amountPaid: elementDecimalOrZero(seg, 2, delimiters, sink),
|
|
3888
4037
|
procedureQualifier: componentOptional(seg, 3, 1, delimiters),
|
|
3889
4038
|
procedureCode: componentOptional(seg, 3, 2, delimiters),
|
|
3890
|
-
paidUnits: elementDecimal(seg, 5, delimiters),
|
|
4039
|
+
paidUnits: elementDecimal(seg, 5, delimiters, sink),
|
|
3891
4040
|
adjustments: [],
|
|
3892
4041
|
dateAdjudicated: void 0
|
|
3893
4042
|
};
|
|
@@ -4179,6 +4328,12 @@ function refuseHierarchy(message) {
|
|
|
4179
4328
|
function refuseSpec2(message) {
|
|
4180
4329
|
throw new Claim837BuildError(CLAIM_837_BUILD_ERROR_CODES.X12_837_BUILD_INVALID_SPEC, message);
|
|
4181
4330
|
}
|
|
4331
|
+
function decStr(value) {
|
|
4332
|
+
return requireCallerDecimal(value, "build837", refuseSpec2).toString();
|
|
4333
|
+
}
|
|
4334
|
+
function escDec2(value, esc) {
|
|
4335
|
+
return esc(decStr(value));
|
|
4336
|
+
}
|
|
4182
4337
|
var VERSION_BY_VARIANT = {
|
|
4183
4338
|
P: "005010X222A2",
|
|
4184
4339
|
I: "005010X223A3",
|
|
@@ -4210,8 +4365,9 @@ function buildClaim837(variant, spec) {
|
|
|
4210
4365
|
component: componentSeparator,
|
|
4211
4366
|
segment: segmentTerminator
|
|
4212
4367
|
};
|
|
4213
|
-
const esc = (
|
|
4368
|
+
const esc = makeCallerEscaper(delimiters, "build837", refuseSpec2);
|
|
4214
4369
|
const seg = (parts) => {
|
|
4370
|
+
requireCallerSegment(parts, "build837", refuseSpec2);
|
|
4215
4371
|
let end = parts.length;
|
|
4216
4372
|
while (end > 1 && parts[end - 1] === "") end -= 1;
|
|
4217
4373
|
return parts.slice(0, end).join(elementSeparator) + segmentTerminator;
|
|
@@ -4255,8 +4411,8 @@ function buildClaim837(variant, spec) {
|
|
|
4255
4411
|
X12_837_FUNCTIONAL_ID,
|
|
4256
4412
|
esc(applicationSenderCode),
|
|
4257
4413
|
esc(applicationReceiverCode),
|
|
4258
|
-
groupDate,
|
|
4259
|
-
groupTime,
|
|
4414
|
+
esc(groupDate),
|
|
4415
|
+
esc(groupTime),
|
|
4260
4416
|
esc(envelope.groupControlNumber),
|
|
4261
4417
|
X12_AGENCY_CODE2,
|
|
4262
4418
|
versionRelease
|
|
@@ -4471,7 +4627,7 @@ function emitClaim2(variant, claim, body, ctx) {
|
|
|
4471
4627
|
ctx.seg([
|
|
4472
4628
|
"CLM",
|
|
4473
4629
|
ctx.esc(claim.claimId),
|
|
4474
|
-
|
|
4630
|
+
escDec2(claim.totalCharge, ctx.esc),
|
|
4475
4631
|
"",
|
|
4476
4632
|
"",
|
|
4477
4633
|
ctx.comp([
|
|
@@ -4519,8 +4675,8 @@ function emitOtherSubscriber(other, body, ctx) {
|
|
|
4519
4675
|
if (other.otherPayer !== void 0) emitEntity(other.otherPayer, body, ctx);
|
|
4520
4676
|
}
|
|
4521
4677
|
function emitServiceLine2(variant, line, lineNumber, body, ctx) {
|
|
4522
|
-
body.push(ctx.seg(["LX", line.lineNumber ?? String(lineNumber)]));
|
|
4523
|
-
const units = line.units === void 0 ? "0" : line.units
|
|
4678
|
+
body.push(ctx.seg(["LX", ctx.esc(line.lineNumber ?? String(lineNumber))]));
|
|
4679
|
+
const units = line.units === void 0 ? "0" : decStr(line.units);
|
|
4524
4680
|
if (line.variant === "P") {
|
|
4525
4681
|
const proc = ctx.comp([line.procedureQualifier, line.procedureCode, ...line.modifiers ?? []]);
|
|
4526
4682
|
const pointers = ctx.comp(line.diagnosisPointers ?? []);
|
|
@@ -4528,7 +4684,7 @@ function emitServiceLine2(variant, line, lineNumber, body, ctx) {
|
|
|
4528
4684
|
ctx.seg([
|
|
4529
4685
|
"SV1",
|
|
4530
4686
|
proc,
|
|
4531
|
-
|
|
4687
|
+
escDec2(line.charge, ctx.esc),
|
|
4532
4688
|
ctx.esc(line.unitOfMeasure ?? ""),
|
|
4533
4689
|
ctx.esc(units),
|
|
4534
4690
|
ctx.esc(line.placeOfServiceCode ?? ""),
|
|
@@ -4552,11 +4708,11 @@ function emitServiceLine2(variant, line, lineNumber, body, ctx) {
|
|
|
4552
4708
|
"SV2",
|
|
4553
4709
|
ctx.esc(line.revenueCode),
|
|
4554
4710
|
proc,
|
|
4555
|
-
|
|
4711
|
+
escDec2(line.charge, ctx.esc),
|
|
4556
4712
|
ctx.esc(line.unitOfMeasure ?? ""),
|
|
4557
4713
|
ctx.esc(units),
|
|
4558
|
-
line.serviceLineRate === void 0 ? "" :
|
|
4559
|
-
line.nonCoveredCharge === void 0 ? "" :
|
|
4714
|
+
line.serviceLineRate === void 0 ? "" : escDec2(line.serviceLineRate, ctx.esc),
|
|
4715
|
+
line.nonCoveredCharge === void 0 ? "" : escDec2(line.nonCoveredCharge, ctx.esc)
|
|
4560
4716
|
])
|
|
4561
4717
|
);
|
|
4562
4718
|
} else {
|
|
@@ -4566,7 +4722,7 @@ function emitServiceLine2(variant, line, lineNumber, body, ctx) {
|
|
|
4566
4722
|
ctx.seg([
|
|
4567
4723
|
"SV3",
|
|
4568
4724
|
proc,
|
|
4569
|
-
|
|
4725
|
+
escDec2(line.charge, ctx.esc),
|
|
4570
4726
|
ctx.esc(line.placeOfServiceCode ?? ""),
|
|
4571
4727
|
cavity,
|
|
4572
4728
|
ctx.esc(line.prosthesisCrownInlayCode ?? ""),
|
|
@@ -4585,7 +4741,7 @@ function emitServiceLine2(variant, line, lineNumber, body, ctx) {
|
|
|
4585
4741
|
"",
|
|
4586
4742
|
"",
|
|
4587
4743
|
"",
|
|
4588
|
-
drug.quantity === void 0 ? "" :
|
|
4744
|
+
drug.quantity === void 0 ? "" : escDec2(drug.quantity, ctx.esc),
|
|
4589
4745
|
ctx.esc(drug.unitOfMeasure ?? "")
|
|
4590
4746
|
])
|
|
4591
4747
|
);
|
|
@@ -4615,10 +4771,10 @@ function emitAdjudication(adj, body, ctx) {
|
|
|
4615
4771
|
ctx.seg([
|
|
4616
4772
|
"SVD",
|
|
4617
4773
|
ctx.esc(adj.otherPayerId),
|
|
4618
|
-
|
|
4774
|
+
escDec2(adj.amountPaid, ctx.esc),
|
|
4619
4775
|
proc,
|
|
4620
4776
|
"",
|
|
4621
|
-
adj.paidUnits === void 0 ? "" :
|
|
4777
|
+
adj.paidUnits === void 0 ? "" : escDec2(adj.paidUnits, ctx.esc)
|
|
4622
4778
|
])
|
|
4623
4779
|
);
|
|
4624
4780
|
emitCasGroup2(adj.adjustments, "build837: adjudication.adjustments", body, ctx);
|
|
@@ -4643,8 +4799,8 @@ function emitCasGroup2(raw, at, body, ctx) {
|
|
|
4643
4799
|
if (adj === void 0 || adj.groupCode !== groupCode) break;
|
|
4644
4800
|
parts.push(
|
|
4645
4801
|
ctx.esc(adj.reasonCode),
|
|
4646
|
-
|
|
4647
|
-
adj.quantity === void 0 ? "" :
|
|
4802
|
+
escDec2(adj.amount, ctx.esc),
|
|
4803
|
+
adj.quantity === void 0 ? "" : escDec2(adj.quantity, ctx.esc)
|
|
4648
4804
|
);
|
|
4649
4805
|
triples += 1;
|
|
4650
4806
|
i += 1;
|
|
@@ -4715,7 +4871,7 @@ function emitNote(note, body, ctx) {
|
|
|
4715
4871
|
body.push(ctx.seg(["NTE", ctx.esc(note.noteReferenceCode), ctx.esc(note.description)]));
|
|
4716
4872
|
}
|
|
4717
4873
|
function emitAmount(amt, body, ctx) {
|
|
4718
|
-
body.push(ctx.seg(["AMT", ctx.esc(amt.qualifier),
|
|
4874
|
+
body.push(ctx.seg(["AMT", ctx.esc(amt.qualifier), escDec2(amt.amount, ctx.esc)]));
|
|
4719
4875
|
}
|
|
4720
4876
|
function emitHi(hi, body, ctx) {
|
|
4721
4877
|
const composite = ctx.comp([
|
|
@@ -4723,8 +4879,10 @@ function emitHi(hi, body, ctx) {
|
|
|
4723
4879
|
hi.code,
|
|
4724
4880
|
hi.dateQualifier ?? "",
|
|
4725
4881
|
hi.date ?? "",
|
|
4726
|
-
|
|
4727
|
-
|
|
4882
|
+
// `decStr`, not `escDec`: `ctx.comp` maps `esc` over every component, so
|
|
4883
|
+
// escaping here would double-release an active delimiter.
|
|
4884
|
+
hi.monetaryAmount === void 0 ? "" : decStr(hi.monetaryAmount),
|
|
4885
|
+
hi.quantity === void 0 ? "" : decStr(hi.quantity),
|
|
4728
4886
|
hi.versionId ?? "",
|
|
4729
4887
|
"",
|
|
4730
4888
|
hi.poaIndicator ?? ""
|
|
@@ -5036,6 +5194,7 @@ function get271Eligibility(delimiters, tx) {
|
|
|
5036
5194
|
const seg = body[i];
|
|
5037
5195
|
if (seg === void 0) continue;
|
|
5038
5196
|
const position = { segmentIndex: i + 1, transactionIndex: 0 };
|
|
5197
|
+
const sink = { warnings, position };
|
|
5039
5198
|
switch (seg.id) {
|
|
5040
5199
|
case "HL": {
|
|
5041
5200
|
const hl = decodeHl2(seg, delimiters);
|
|
@@ -5139,7 +5298,7 @@ function get271Eligibility(delimiters, tx) {
|
|
|
5139
5298
|
case "EB": {
|
|
5140
5299
|
flushBenefit();
|
|
5141
5300
|
if (currentSubscriber === void 0 && currentDependent === void 0) break;
|
|
5142
|
-
currentBenefit = openBenefit(seg, delimiters);
|
|
5301
|
+
currentBenefit = openBenefit(seg, delimiters, sink);
|
|
5143
5302
|
break;
|
|
5144
5303
|
}
|
|
5145
5304
|
case "MSG": {
|
|
@@ -5236,7 +5395,7 @@ function decodeDtp2(seg, delimiters) {
|
|
|
5236
5395
|
value
|
|
5237
5396
|
});
|
|
5238
5397
|
}
|
|
5239
|
-
function openBenefit(seg, delimiters) {
|
|
5398
|
+
function openBenefit(seg, delimiters, sink) {
|
|
5240
5399
|
const serviceTypeCodes = [];
|
|
5241
5400
|
for (const code of getAllSegmentValues(seg, "03", delimiters)) {
|
|
5242
5401
|
if (code === "") continue;
|
|
@@ -5251,10 +5410,10 @@ function openBenefit(seg, delimiters) {
|
|
|
5251
5410
|
insuranceTypeCode: elementOptional(seg, 4, delimiters),
|
|
5252
5411
|
planCoverageDescription: elementOptional(seg, 5, delimiters),
|
|
5253
5412
|
timePeriodQualifier: elementOptional(seg, 6, delimiters),
|
|
5254
|
-
monetaryAmount: elementDecimal(seg, 7, delimiters),
|
|
5255
|
-
percent: elementDecimal(seg, 8, delimiters),
|
|
5413
|
+
monetaryAmount: elementDecimal(seg, 7, delimiters, sink),
|
|
5414
|
+
percent: elementDecimal(seg, 8, delimiters, sink),
|
|
5256
5415
|
quantityQualifier: elementOptional(seg, 9, delimiters),
|
|
5257
|
-
quantity: elementDecimal(seg, 10, delimiters),
|
|
5416
|
+
quantity: elementDecimal(seg, 10, delimiters, sink),
|
|
5258
5417
|
authorizationRequired: elementOptional(seg, 11, delimiters),
|
|
5259
5418
|
inPlanNetwork: elementOptional(seg, 12, delimiters),
|
|
5260
5419
|
references: [],
|
|
@@ -5351,6 +5510,15 @@ function refuseHierarchy2(message) {
|
|
|
5351
5510
|
message
|
|
5352
5511
|
);
|
|
5353
5512
|
}
|
|
5513
|
+
function refuseSpec3(message) {
|
|
5514
|
+
throw new Eligibility271BuildError(
|
|
5515
|
+
ELIGIBILITY_271_BUILD_ERROR_CODES.X12_271_BUILD_INVALID_SPEC,
|
|
5516
|
+
message
|
|
5517
|
+
);
|
|
5518
|
+
}
|
|
5519
|
+
function escDec3(value, esc) {
|
|
5520
|
+
return esc(requireCallerDecimal(value, "build271", refuseSpec3).toString());
|
|
5521
|
+
}
|
|
5354
5522
|
var X279A1_VERSION_RELEASE = "005010X279A1";
|
|
5355
5523
|
var X12_271_FUNCTIONAL_ID = "HB";
|
|
5356
5524
|
var X12_AGENCY_CODE3 = "X";
|
|
@@ -5368,8 +5536,9 @@ function build271(spec) {
|
|
|
5368
5536
|
component: componentSeparator,
|
|
5369
5537
|
segment: segmentTerminator
|
|
5370
5538
|
};
|
|
5371
|
-
const esc = (
|
|
5539
|
+
const esc = makeCallerEscaper(delimiters, "build271", refuseSpec3);
|
|
5372
5540
|
const seg = (parts) => {
|
|
5541
|
+
requireCallerSegment(parts, "build271", refuseSpec3);
|
|
5373
5542
|
let end = parts.length;
|
|
5374
5543
|
while (end > 1 && parts[end - 1] === "") end -= 1;
|
|
5375
5544
|
return parts.slice(0, end).join(elementSeparator) + segmentTerminator;
|
|
@@ -5407,8 +5576,8 @@ function build271(spec) {
|
|
|
5407
5576
|
X12_271_FUNCTIONAL_ID,
|
|
5408
5577
|
esc(applicationSenderCode),
|
|
5409
5578
|
esc(applicationReceiverCode),
|
|
5410
|
-
groupDate,
|
|
5411
|
-
groupTime,
|
|
5579
|
+
esc(groupDate),
|
|
5580
|
+
esc(groupTime),
|
|
5412
5581
|
esc(envelope.groupControlNumber),
|
|
5413
5582
|
X12_AGENCY_CODE3,
|
|
5414
5583
|
X279A1_VERSION_RELEASE
|
|
@@ -5578,10 +5747,10 @@ function emitBenefit(benefit, body, ctx) {
|
|
|
5578
5747
|
ctx.esc(benefit.insuranceTypeCode ?? ""),
|
|
5579
5748
|
ctx.esc(benefit.planCoverageDescription ?? ""),
|
|
5580
5749
|
ctx.esc(benefit.timePeriodQualifier ?? ""),
|
|
5581
|
-
benefit.monetaryAmount === void 0 ? "" :
|
|
5582
|
-
benefit.percent === void 0 ? "" :
|
|
5750
|
+
benefit.monetaryAmount === void 0 ? "" : escDec3(benefit.monetaryAmount, ctx.esc),
|
|
5751
|
+
benefit.percent === void 0 ? "" : escDec3(benefit.percent, ctx.esc),
|
|
5583
5752
|
ctx.esc(benefit.quantityQualifier ?? ""),
|
|
5584
|
-
benefit.quantity === void 0 ? "" :
|
|
5753
|
+
benefit.quantity === void 0 ? "" : escDec3(benefit.quantity, ctx.esc),
|
|
5585
5754
|
ctx.esc(benefit.authorizationRequired ?? ""),
|
|
5586
5755
|
ctx.esc(benefit.inPlanNetwork ?? "")
|
|
5587
5756
|
])
|
|
@@ -5788,6 +5957,7 @@ function walk277(delimiters, tx) {
|
|
|
5788
5957
|
const seg = body[i];
|
|
5789
5958
|
if (seg === void 0) continue;
|
|
5790
5959
|
const position = { segmentIndex: i + 1, transactionIndex: 0 };
|
|
5960
|
+
const sink = { warnings, position };
|
|
5791
5961
|
switch (seg.id) {
|
|
5792
5962
|
case "HL": {
|
|
5793
5963
|
flushClaim();
|
|
@@ -5865,7 +6035,7 @@ function walk277(delimiters, tx) {
|
|
|
5865
6035
|
case "SVC": {
|
|
5866
6036
|
flushServiceLine();
|
|
5867
6037
|
if (currentClaim === void 0) currentClaim = openClaim3();
|
|
5868
|
-
currentServiceLine = openServiceLine3(seg, delimiters);
|
|
6038
|
+
currentServiceLine = openServiceLine3(seg, delimiters, sink);
|
|
5869
6039
|
break;
|
|
5870
6040
|
}
|
|
5871
6041
|
case "REF": {
|
|
@@ -5939,6 +6109,7 @@ function decodeDtp3(seg, delimiters) {
|
|
|
5939
6109
|
});
|
|
5940
6110
|
}
|
|
5941
6111
|
function decodeStc(seg, delimiters, warnings, position) {
|
|
6112
|
+
const sink = { warnings, position };
|
|
5942
6113
|
const statuses = [];
|
|
5943
6114
|
for (const elementIndex of [1, 10, 11]) {
|
|
5944
6115
|
const code = decodeStatusComposite(seg, elementIndex, delimiters, warnings, position);
|
|
@@ -5947,8 +6118,8 @@ function decodeStc(seg, delimiters, warnings, position) {
|
|
|
5947
6118
|
return Object.freeze({
|
|
5948
6119
|
statusEffectiveDate: elementOptional(seg, 2, delimiters),
|
|
5949
6120
|
actionCode: elementOptional(seg, 3, delimiters),
|
|
5950
|
-
totalChargeAmount: elementDecimal(seg, 4, delimiters),
|
|
5951
|
-
paymentAmount: elementDecimal(seg, 5, delimiters),
|
|
6121
|
+
totalChargeAmount: elementDecimal(seg, 4, delimiters, sink),
|
|
6122
|
+
paymentAmount: elementDecimal(seg, 5, delimiters, sink),
|
|
5952
6123
|
adjudicationDate: elementOptional(seg, 6, delimiters),
|
|
5953
6124
|
message: elementOptional(seg, 12, delimiters),
|
|
5954
6125
|
statuses: Object.freeze(statuses)
|
|
@@ -5975,7 +6146,7 @@ function decodeStatusComposite(seg, n, delimiters, warnings, position) {
|
|
|
5975
6146
|
entityCode
|
|
5976
6147
|
});
|
|
5977
6148
|
}
|
|
5978
|
-
function openServiceLine3(seg, delimiters) {
|
|
6149
|
+
function openServiceLine3(seg, delimiters, sink) {
|
|
5979
6150
|
const modifiers = [];
|
|
5980
6151
|
for (let comp = 3; comp <= 6; comp += 1) {
|
|
5981
6152
|
const m = componentOptional(seg, 1, comp, delimiters);
|
|
@@ -5985,9 +6156,13 @@ function openServiceLine3(seg, delimiters) {
|
|
|
5985
6156
|
serviceIdQualifier: componentOptional(seg, 1, 1, delimiters),
|
|
5986
6157
|
procedureCode: componentOptional(seg, 1, 2, delimiters),
|
|
5987
6158
|
modifiers,
|
|
5988
|
-
lineChargeAmount: elementDecimal(seg, 2, delimiters),
|
|
5989
|
-
linePaymentAmount: elementDecimal(seg, 3, delimiters),
|
|
6159
|
+
lineChargeAmount: elementDecimal(seg, 2, delimiters, sink),
|
|
6160
|
+
linePaymentAmount: elementDecimal(seg, 3, delimiters, sink),
|
|
5990
6161
|
revenueCode: elementOptional(seg, 4, delimiters),
|
|
6162
|
+
// SVC-07. SVC-05 (Quantity) and SVC-06 (a second composite) are NOT USED
|
|
6163
|
+
// in both X212 and X214, so they are deliberately left unread rather than
|
|
6164
|
+
// decoded "for symmetry" with the 835, whose SVC-05 IS the paid count.
|
|
6165
|
+
unitsOfService: elementDecimal(seg, 7, delimiters, sink),
|
|
5991
6166
|
statuses: [],
|
|
5992
6167
|
references: [],
|
|
5993
6168
|
dates: []
|
|
@@ -6001,6 +6176,7 @@ function freezeServiceLine3(acc) {
|
|
|
6001
6176
|
lineChargeAmount: acc.lineChargeAmount,
|
|
6002
6177
|
linePaymentAmount: acc.linePaymentAmount,
|
|
6003
6178
|
revenueCode: acc.revenueCode,
|
|
6179
|
+
unitsOfService: acc.unitsOfService,
|
|
6004
6180
|
statuses: Object.freeze(acc.statuses.slice()),
|
|
6005
6181
|
references: Object.freeze(acc.references.slice()),
|
|
6006
6182
|
dates: Object.freeze(acc.dates.slice())
|
|
@@ -6043,12 +6219,15 @@ function refuseHierarchy3(message) {
|
|
|
6043
6219
|
message
|
|
6044
6220
|
);
|
|
6045
6221
|
}
|
|
6046
|
-
function
|
|
6222
|
+
function refuseSpec4(message) {
|
|
6047
6223
|
throw new ClaimStatus277BuildError(
|
|
6048
6224
|
CLAIM_STATUS_277_BUILD_ERROR_CODES.X12_277_BUILD_INVALID_SPEC,
|
|
6049
6225
|
message
|
|
6050
6226
|
);
|
|
6051
6227
|
}
|
|
6228
|
+
function escDec4(value, esc) {
|
|
6229
|
+
return esc(requireCallerDecimal(value, "build277", refuseSpec4).toString());
|
|
6230
|
+
}
|
|
6052
6231
|
var X12_277_FUNCTIONAL_ID = "HN";
|
|
6053
6232
|
var X12_AGENCY_CODE4 = "X";
|
|
6054
6233
|
var HL_LEVEL3 = {
|
|
@@ -6066,7 +6245,7 @@ function build277CA(spec) {
|
|
|
6066
6245
|
}
|
|
6067
6246
|
function buildClaimStatus(version, spec) {
|
|
6068
6247
|
const { envelope } = spec;
|
|
6069
|
-
enforceStructuralSpec4(spec);
|
|
6248
|
+
enforceStructuralSpec4(version, spec);
|
|
6070
6249
|
const elementSeparator = envelope.elementSeparator ?? "*";
|
|
6071
6250
|
const repetitionSeparator = envelope.repetitionSeparator ?? "^";
|
|
6072
6251
|
const componentSeparator = envelope.componentSeparator ?? ":";
|
|
@@ -6077,8 +6256,9 @@ function buildClaimStatus(version, spec) {
|
|
|
6077
6256
|
component: componentSeparator,
|
|
6078
6257
|
segment: segmentTerminator
|
|
6079
6258
|
};
|
|
6080
|
-
const esc = (
|
|
6259
|
+
const esc = makeCallerEscaper(delimiters, "build277", refuseSpec4);
|
|
6081
6260
|
const seg = (parts) => {
|
|
6261
|
+
requireCallerSegment(parts, "build277", refuseSpec4);
|
|
6082
6262
|
let end = parts.length;
|
|
6083
6263
|
while (end > 1 && parts[end - 1] === "") end -= 1;
|
|
6084
6264
|
return parts.slice(0, end).join(elementSeparator) + segmentTerminator;
|
|
@@ -6122,8 +6302,8 @@ function buildClaimStatus(version, spec) {
|
|
|
6122
6302
|
X12_277_FUNCTIONAL_ID,
|
|
6123
6303
|
esc(applicationSenderCode),
|
|
6124
6304
|
esc(applicationReceiverCode),
|
|
6125
|
-
groupDate,
|
|
6126
|
-
groupTime,
|
|
6305
|
+
esc(groupDate),
|
|
6306
|
+
esc(groupTime),
|
|
6127
6307
|
esc(envelope.groupControlNumber),
|
|
6128
6308
|
X12_AGENCY_CODE4,
|
|
6129
6309
|
version
|
|
@@ -6142,7 +6322,7 @@ function buildClaimStatus(version, spec) {
|
|
|
6142
6322
|
const raw = isa + gs + st + body.join("") + se + ge + iea;
|
|
6143
6323
|
return parseX12(raw);
|
|
6144
6324
|
}
|
|
6145
|
-
function enforceStructuralSpec4(spec) {
|
|
6325
|
+
function enforceStructuralSpec4(version, spec) {
|
|
6146
6326
|
const sources = requireCallerArray(
|
|
6147
6327
|
spec.informationSources,
|
|
6148
6328
|
"build277: spec.informationSources",
|
|
@@ -6200,13 +6380,13 @@ function enforceStructuralSpec4(spec) {
|
|
|
6200
6380
|
for (let u = 0; u < subscribers.length; u += 1) {
|
|
6201
6381
|
const subscriber = subscribers[u];
|
|
6202
6382
|
if (subscriber === void 0) continue;
|
|
6203
|
-
enforceSubscriber(subscriber, `${locator}.subscriber[${String(u)}]`);
|
|
6383
|
+
enforceSubscriber(version, subscriber, `${locator}.subscriber[${String(u)}]`);
|
|
6204
6384
|
}
|
|
6205
6385
|
}
|
|
6206
6386
|
}
|
|
6207
6387
|
}
|
|
6208
6388
|
}
|
|
6209
|
-
function enforceSubscriber(subscriber, locator) {
|
|
6389
|
+
function enforceSubscriber(version, subscriber, locator) {
|
|
6210
6390
|
const claims = requireCallerArray(
|
|
6211
6391
|
subscriber.claims,
|
|
6212
6392
|
`build277: subscriber at ${locator}: claims`,
|
|
@@ -6225,7 +6405,8 @@ function enforceSubscriber(subscriber, locator) {
|
|
|
6225
6405
|
}
|
|
6226
6406
|
for (let c = 0; c < claims.length; c += 1) {
|
|
6227
6407
|
const claim = claims[c];
|
|
6228
|
-
if (claim !== void 0)
|
|
6408
|
+
if (claim !== void 0)
|
|
6409
|
+
enforceClaim2(version, claim, `${locator}.claim[${String(c)}]`, c === 0);
|
|
6229
6410
|
}
|
|
6230
6411
|
for (let d = 0; d < dependents.length; d += 1) {
|
|
6231
6412
|
const dependent = dependents[d];
|
|
@@ -6244,20 +6425,21 @@ function enforceSubscriber(subscriber, locator) {
|
|
|
6244
6425
|
}
|
|
6245
6426
|
for (let c = 0; c < depClaims.length; c += 1) {
|
|
6246
6427
|
const claim = depClaims[c];
|
|
6247
|
-
if (claim !== void 0)
|
|
6428
|
+
if (claim !== void 0)
|
|
6429
|
+
enforceClaim2(version, claim, `${depLocator}.claim[${String(c)}]`, c === 0);
|
|
6248
6430
|
}
|
|
6249
6431
|
}
|
|
6250
6432
|
}
|
|
6251
|
-
function enforceClaim2(claim, locator, isFirst) {
|
|
6433
|
+
function enforceClaim2(version, claim, locator, isFirst) {
|
|
6252
6434
|
const statuses = requireCallerArray(
|
|
6253
6435
|
claim.statuses,
|
|
6254
6436
|
`build277: claim at ${locator}: statuses`,
|
|
6255
|
-
|
|
6437
|
+
refuseSpec4
|
|
6256
6438
|
);
|
|
6257
6439
|
const serviceLines = requireCallerArray(
|
|
6258
6440
|
claim.serviceLines,
|
|
6259
6441
|
`build277: claim at ${locator}: serviceLines`,
|
|
6260
|
-
|
|
6442
|
+
refuseSpec4
|
|
6261
6443
|
);
|
|
6262
6444
|
if (claim.trace === void 0 && statuses.length === 0 && serviceLines.length === 0) {
|
|
6263
6445
|
throw new ClaimStatus277BuildError(
|
|
@@ -6277,10 +6459,16 @@ function enforceClaim2(claim, locator, isFirst) {
|
|
|
6277
6459
|
for (let l = 0; l < serviceLines.length; l += 1) {
|
|
6278
6460
|
const line = serviceLines[l];
|
|
6279
6461
|
if (line === void 0) continue;
|
|
6462
|
+
if (version === "005010X212" && line.unitsOfService === void 0) {
|
|
6463
|
+
throw new ClaimStatus277BuildError(
|
|
6464
|
+
CLAIM_STATUS_277_BUILD_ERROR_CODES.X12_277_BUILD_INVALID_SPEC,
|
|
6465
|
+
`build277: service line at ${locator}.line[${String(l)}] has no unitsOfService, and SVC-07 is a required element in 005010X212. Supply the submitted count; it is never defaulted. In 005010X214 it is situational, so build277CA accepts the same line.`
|
|
6466
|
+
);
|
|
6467
|
+
}
|
|
6280
6468
|
const lineStatuses = requireCallerArray(
|
|
6281
6469
|
line.statuses,
|
|
6282
6470
|
`build277: claim at ${locator}.line[${String(l)}]: statuses`,
|
|
6283
|
-
|
|
6471
|
+
refuseSpec4
|
|
6284
6472
|
);
|
|
6285
6473
|
for (let i = 0; i < lineStatuses.length; i += 1) {
|
|
6286
6474
|
enforceStatus(lineStatuses[i], `${locator}.line[${String(l)}].status[${String(i)}]`);
|
|
@@ -6370,9 +6558,12 @@ function emitServiceLine3(line, body, ctx) {
|
|
|
6370
6558
|
ctx.seg([
|
|
6371
6559
|
"SVC",
|
|
6372
6560
|
svc01,
|
|
6373
|
-
line.lineChargeAmount === void 0 ? "" :
|
|
6374
|
-
line.linePaymentAmount === void 0 ? "" :
|
|
6375
|
-
ctx.esc(line.revenueCode ?? "")
|
|
6561
|
+
line.lineChargeAmount === void 0 ? "" : escDec4(line.lineChargeAmount, ctx.esc),
|
|
6562
|
+
line.linePaymentAmount === void 0 ? "" : escDec4(line.linePaymentAmount, ctx.esc),
|
|
6563
|
+
ctx.esc(line.revenueCode ?? ""),
|
|
6564
|
+
"",
|
|
6565
|
+
"",
|
|
6566
|
+
line.unitsOfService === void 0 ? "" : escDec4(line.unitsOfService, ctx.esc)
|
|
6376
6567
|
])
|
|
6377
6568
|
);
|
|
6378
6569
|
for (const status of line.statuses ?? []) emitStatus(status, body, ctx);
|
|
@@ -6391,8 +6582,8 @@ function emitStatus(status, body, ctx) {
|
|
|
6391
6582
|
composite(0),
|
|
6392
6583
|
ctx.esc(status.statusEffectiveDate ?? ""),
|
|
6393
6584
|
ctx.esc(status.actionCode ?? ""),
|
|
6394
|
-
status.totalChargeAmount === void 0 ? "" :
|
|
6395
|
-
status.paymentAmount === void 0 ? "" :
|
|
6585
|
+
status.totalChargeAmount === void 0 ? "" : escDec4(status.totalChargeAmount, ctx.esc),
|
|
6586
|
+
status.paymentAmount === void 0 ? "" : escDec4(status.paymentAmount, ctx.esc),
|
|
6396
6587
|
ctx.esc(status.adjudicationDate ?? ""),
|
|
6397
6588
|
"",
|
|
6398
6589
|
"",
|
|
@@ -6562,9 +6753,11 @@ function get820Payments(delimiters, tx) {
|
|
|
6562
6753
|
for (let i = 0; i < body.length; i += 1) {
|
|
6563
6754
|
const seg = body[i];
|
|
6564
6755
|
if (seg === void 0) continue;
|
|
6756
|
+
const position = { segmentIndex: i + 1, transactionIndex: 0 };
|
|
6757
|
+
const sink = { warnings, position };
|
|
6565
6758
|
switch (seg.id) {
|
|
6566
6759
|
case "BPR": {
|
|
6567
|
-
payment = decodeBpr2(seg, delimiters);
|
|
6760
|
+
payment = decodeBpr2(seg, delimiters, sink);
|
|
6568
6761
|
break;
|
|
6569
6762
|
}
|
|
6570
6763
|
case "TRN": {
|
|
@@ -6631,13 +6824,13 @@ function get820Payments(delimiters, tx) {
|
|
|
6631
6824
|
}
|
|
6632
6825
|
case "RMR": {
|
|
6633
6826
|
if (current === void 0) break;
|
|
6634
|
-
const item = decodeRmr(seg, delimiters);
|
|
6827
|
+
const item = decodeRmr(seg, delimiters, sink);
|
|
6635
6828
|
if (item !== void 0) current.openItems.push(item);
|
|
6636
6829
|
break;
|
|
6637
6830
|
}
|
|
6638
6831
|
case "ADX": {
|
|
6639
6832
|
if (current === void 0) break;
|
|
6640
|
-
const adjustment = decodeAdx(seg, delimiters);
|
|
6833
|
+
const adjustment = decodeAdx(seg, delimiters, sink);
|
|
6641
6834
|
if (adjustment !== void 0) current.adjustments.push(adjustment);
|
|
6642
6835
|
break;
|
|
6643
6836
|
}
|
|
@@ -6689,10 +6882,10 @@ function freezeRemittance(acc) {
|
|
|
6689
6882
|
adjustments: Object.freeze(acc.adjustments.slice())
|
|
6690
6883
|
});
|
|
6691
6884
|
}
|
|
6692
|
-
function decodeBpr2(seg, delimiters) {
|
|
6885
|
+
function decodeBpr2(seg, delimiters, sink) {
|
|
6693
6886
|
return Object.freeze({
|
|
6694
6887
|
transactionHandlingCode: elementValue(seg, 1, delimiters),
|
|
6695
|
-
totalPremiumAmount: elementDecimalOrZero(seg, 2, delimiters),
|
|
6888
|
+
totalPremiumAmount: elementDecimalOrZero(seg, 2, delimiters, sink),
|
|
6696
6889
|
creditDebitFlag: elementValue(seg, 3, delimiters),
|
|
6697
6890
|
method: elementValue(seg, 4, delimiters),
|
|
6698
6891
|
paymentFormatCode: elementOptional(seg, 5, delimiters),
|
|
@@ -6760,7 +6953,7 @@ function decodeNm13(seg, delimiters) {
|
|
|
6760
6953
|
idCode: elementOptional(seg, 9, delimiters)
|
|
6761
6954
|
});
|
|
6762
6955
|
}
|
|
6763
|
-
function decodeRmr(seg, delimiters) {
|
|
6956
|
+
function decodeRmr(seg, delimiters, sink) {
|
|
6764
6957
|
const qualifier = elementValue(seg, 1, delimiters);
|
|
6765
6958
|
const referenceId = elementValue(seg, 2, delimiters);
|
|
6766
6959
|
if (qualifier === "" && referenceId === "") return void 0;
|
|
@@ -6768,12 +6961,12 @@ function decodeRmr(seg, delimiters) {
|
|
|
6768
6961
|
qualifier,
|
|
6769
6962
|
referenceId,
|
|
6770
6963
|
paymentActionCode: elementOptional(seg, 3, delimiters),
|
|
6771
|
-
amountPaid: elementDecimalOrZero(seg, 4, delimiters),
|
|
6772
|
-
amountDue: elementDecimal(seg, 5, delimiters)
|
|
6964
|
+
amountPaid: elementDecimalOrZero(seg, 4, delimiters, sink),
|
|
6965
|
+
amountDue: elementDecimal(seg, 5, delimiters, sink)
|
|
6773
6966
|
});
|
|
6774
6967
|
}
|
|
6775
|
-
function decodeAdx(seg, delimiters) {
|
|
6776
|
-
const amount = elementDecimal(seg, 1, delimiters);
|
|
6968
|
+
function decodeAdx(seg, delimiters, sink) {
|
|
6969
|
+
const amount = elementDecimal(seg, 1, delimiters, sink);
|
|
6777
6970
|
if (amount === void 0) return void 0;
|
|
6778
6971
|
return Object.freeze({
|
|
6779
6972
|
amount,
|
|
@@ -6831,9 +7024,12 @@ var Premium820BuildError = class extends Error {
|
|
|
6831
7024
|
};
|
|
6832
7025
|
|
|
6833
7026
|
// src/transactions/premium/build-820.ts
|
|
6834
|
-
function
|
|
7027
|
+
function refuseSpec5(message) {
|
|
6835
7028
|
throw new Premium820BuildError(PREMIUM_820_BUILD_ERROR_CODES.X12_820_BUILD_INVALID_SPEC, message);
|
|
6836
7029
|
}
|
|
7030
|
+
function escDec5(value, esc) {
|
|
7031
|
+
return esc(requireCallerDecimal(value, "build820", refuseSpec5).toString());
|
|
7032
|
+
}
|
|
6837
7033
|
var X218_VERSION_RELEASE = "005010X218";
|
|
6838
7034
|
var X12_820_FUNCTIONAL_ID = "RA";
|
|
6839
7035
|
var X12_AGENCY_CODE5 = "X";
|
|
@@ -6850,8 +7046,9 @@ function build820(spec) {
|
|
|
6850
7046
|
component: componentSeparator,
|
|
6851
7047
|
segment: segmentTerminator
|
|
6852
7048
|
};
|
|
6853
|
-
const esc = (
|
|
7049
|
+
const esc = makeCallerEscaper(delimiters, "build820", refuseSpec5);
|
|
6854
7050
|
const seg = (parts) => {
|
|
7051
|
+
requireCallerSegment(parts, "build820", refuseSpec5);
|
|
6855
7052
|
let end = parts.length;
|
|
6856
7053
|
while (end > 1 && parts[end - 1] === "") end -= 1;
|
|
6857
7054
|
return parts.slice(0, end).join(elementSeparator) + segmentTerminator;
|
|
@@ -6907,9 +7104,9 @@ function build820(spec) {
|
|
|
6907
7104
|
// GS-02
|
|
6908
7105
|
esc(applicationReceiverCode),
|
|
6909
7106
|
// GS-03
|
|
6910
|
-
groupDate,
|
|
7107
|
+
esc(groupDate),
|
|
6911
7108
|
// GS-04 - CCYYMMDD
|
|
6912
|
-
groupTime,
|
|
7109
|
+
esc(groupTime),
|
|
6913
7110
|
// GS-05 - HHMM
|
|
6914
7111
|
esc(envelope.groupControlNumber),
|
|
6915
7112
|
// GS-06
|
|
@@ -6925,7 +7122,7 @@ function build820(spec) {
|
|
|
6925
7122
|
seg([
|
|
6926
7123
|
"BPR",
|
|
6927
7124
|
esc(spec.payment.transactionHandlingCode),
|
|
6928
|
-
|
|
7125
|
+
escDec5(spec.payment.totalPremiumAmount, esc),
|
|
6929
7126
|
esc(spec.payment.creditDebitFlag),
|
|
6930
7127
|
esc(spec.payment.method),
|
|
6931
7128
|
esc(spec.payment.paymentFormatCode ?? ""),
|
|
@@ -6977,7 +7174,7 @@ function build820(spec) {
|
|
|
6977
7174
|
return parseX12(raw);
|
|
6978
7175
|
}
|
|
6979
7176
|
function enforceStructuralSpec5(spec) {
|
|
6980
|
-
const traces = requireCallerArray(spec.traces, "build820: spec.traces",
|
|
7177
|
+
const traces = requireCallerArray(spec.traces, "build820: spec.traces", refuseSpec5);
|
|
6981
7178
|
if (traces.length === 0) {
|
|
6982
7179
|
throw new Premium820BuildError(
|
|
6983
7180
|
PREMIUM_820_BUILD_ERROR_CODES.X12_820_BUILD_INVALID_SPEC,
|
|
@@ -6987,7 +7184,7 @@ function enforceStructuralSpec5(spec) {
|
|
|
6987
7184
|
const remittances = requireCallerArray(
|
|
6988
7185
|
spec.remittances,
|
|
6989
7186
|
"build820: spec.remittances",
|
|
6990
|
-
|
|
7187
|
+
refuseSpec5
|
|
6991
7188
|
);
|
|
6992
7189
|
if (remittances.length === 0) {
|
|
6993
7190
|
throw new Premium820BuildError(
|
|
@@ -7007,7 +7204,7 @@ function enforceStructuralSpec5(spec) {
|
|
|
7007
7204
|
const openItems = requireCallerArray(
|
|
7008
7205
|
remittance.openItems,
|
|
7009
7206
|
`build820: spec.remittances[${String(r)}].openItems`,
|
|
7010
|
-
|
|
7207
|
+
refuseSpec5
|
|
7011
7208
|
);
|
|
7012
7209
|
if (openItems.length === 0) {
|
|
7013
7210
|
throw new Premium820BuildError(
|
|
@@ -7082,7 +7279,7 @@ function emitRemittance(remittance, body, seg, esc) {
|
|
|
7082
7279
|
body.push(
|
|
7083
7280
|
seg([
|
|
7084
7281
|
"ADX",
|
|
7085
|
-
|
|
7282
|
+
escDec5(adjustment.amount, esc),
|
|
7086
7283
|
esc(adjustment.reasonCode),
|
|
7087
7284
|
esc(adjustment.referenceQualifier ?? ""),
|
|
7088
7285
|
esc(adjustment.referenceId ?? "")
|
|
@@ -7112,8 +7309,8 @@ function emitOpenItem(item, seg, esc) {
|
|
|
7112
7309
|
esc(item.qualifier),
|
|
7113
7310
|
esc(item.referenceId),
|
|
7114
7311
|
esc(item.paymentActionCode ?? ""),
|
|
7115
|
-
|
|
7116
|
-
item.amountDue === void 0 ? "" :
|
|
7312
|
+
escDec5(item.amountPaid, esc),
|
|
7313
|
+
item.amountDue === void 0 ? "" : escDec5(item.amountDue, esc)
|
|
7117
7314
|
]);
|
|
7118
7315
|
}
|
|
7119
7316
|
function emitRef5(ref, seg, esc) {
|
|
@@ -7344,7 +7541,8 @@ async function* get834Enrollments(delimiters, tx) {
|
|
|
7344
7541
|
}
|
|
7345
7542
|
case "AMT": {
|
|
7346
7543
|
if (currentCoverage === void 0) break;
|
|
7347
|
-
const
|
|
7544
|
+
const sink = { warnings: current.warnings, position };
|
|
7545
|
+
const amount = decodeAmt3(seg, delimiters, sink);
|
|
7348
7546
|
if (amount !== void 0) currentCoverage.amounts.push(amount);
|
|
7349
7547
|
break;
|
|
7350
7548
|
}
|
|
@@ -7470,8 +7668,8 @@ function decodeDtp4(seg, delimiters) {
|
|
|
7470
7668
|
value
|
|
7471
7669
|
});
|
|
7472
7670
|
}
|
|
7473
|
-
function decodeAmt3(seg, delimiters) {
|
|
7474
|
-
const amount = elementDecimal(seg, 2, delimiters);
|
|
7671
|
+
function decodeAmt3(seg, delimiters, sink) {
|
|
7672
|
+
const amount = elementDecimal(seg, 2, delimiters, sink);
|
|
7475
7673
|
if (amount === void 0) return void 0;
|
|
7476
7674
|
return Object.freeze({
|
|
7477
7675
|
qualifier: elementValue(seg, 1, delimiters),
|
|
@@ -7527,12 +7725,15 @@ var Enrollment834BuildError = class extends Error {
|
|
|
7527
7725
|
};
|
|
7528
7726
|
|
|
7529
7727
|
// src/transactions/enrollment/build-834.ts
|
|
7530
|
-
function
|
|
7728
|
+
function refuseSpec6(message) {
|
|
7531
7729
|
throw new Enrollment834BuildError(
|
|
7532
7730
|
ENROLLMENT_834_BUILD_ERROR_CODES.X12_834_BUILD_INVALID_SPEC,
|
|
7533
7731
|
message
|
|
7534
7732
|
);
|
|
7535
7733
|
}
|
|
7734
|
+
function escDec6(value, esc) {
|
|
7735
|
+
return esc(requireCallerDecimal(value, "build834", refuseSpec6).toString());
|
|
7736
|
+
}
|
|
7536
7737
|
var X220A1_VERSION_RELEASE = "005010X220A1";
|
|
7537
7738
|
var X12_834_FUNCTIONAL_ID = "BE";
|
|
7538
7739
|
var X12_AGENCY_CODE6 = "X";
|
|
@@ -7551,8 +7752,9 @@ function build834(spec) {
|
|
|
7551
7752
|
component: componentSeparator,
|
|
7552
7753
|
segment: segmentTerminator
|
|
7553
7754
|
};
|
|
7554
|
-
const esc = (
|
|
7755
|
+
const esc = makeCallerEscaper(delimiters, "build834", refuseSpec6);
|
|
7555
7756
|
const seg = (parts) => {
|
|
7757
|
+
requireCallerSegment(parts, "build834", refuseSpec6);
|
|
7556
7758
|
let end = parts.length;
|
|
7557
7759
|
while (end > 1 && parts[end - 1] === "") end -= 1;
|
|
7558
7760
|
return parts.slice(0, end).join(elementSeparator) + segmentTerminator;
|
|
@@ -7608,9 +7810,9 @@ function build834(spec) {
|
|
|
7608
7810
|
// GS-02
|
|
7609
7811
|
esc(applicationReceiverCode),
|
|
7610
7812
|
// GS-03
|
|
7611
|
-
groupDate,
|
|
7813
|
+
esc(groupDate),
|
|
7612
7814
|
// GS-04 - CCYYMMDD
|
|
7613
|
-
groupTime,
|
|
7815
|
+
esc(groupTime),
|
|
7614
7816
|
// GS-05 - HHMM
|
|
7615
7817
|
esc(envelope.groupControlNumber),
|
|
7616
7818
|
// GS-06
|
|
@@ -7632,7 +7834,7 @@ function build834(spec) {
|
|
|
7632
7834
|
return parseX12(raw);
|
|
7633
7835
|
}
|
|
7634
7836
|
function enforceStructuralSpec6(spec) {
|
|
7635
|
-
const members = requireCallerArray(spec.members, "build834: spec.members",
|
|
7837
|
+
const members = requireCallerArray(spec.members, "build834: spec.members", refuseSpec6);
|
|
7636
7838
|
if (members.length === 0) {
|
|
7637
7839
|
throw new Enrollment834BuildError(
|
|
7638
7840
|
ENROLLMENT_834_BUILD_ERROR_CODES.X12_834_BUILD_INVALID_SPEC,
|
|
@@ -7657,7 +7859,7 @@ function enforceStructuralSpec6(spec) {
|
|
|
7657
7859
|
const coverages = requireCallerArray(
|
|
7658
7860
|
member.healthCoverages,
|
|
7659
7861
|
`build834: spec.members[${String(m)}].healthCoverages`,
|
|
7660
|
-
|
|
7862
|
+
refuseSpec6
|
|
7661
7863
|
);
|
|
7662
7864
|
for (let c = 0; c < coverages.length; c += 1) {
|
|
7663
7865
|
const coverage = coverages[c];
|
|
@@ -7791,7 +7993,7 @@ function emitCoverage(coverage, body, seg, esc) {
|
|
|
7791
7993
|
);
|
|
7792
7994
|
for (const date of coverage.dates ?? []) body.push(emitDate4(date, seg, esc));
|
|
7793
7995
|
for (const amount of coverage.amounts ?? []) {
|
|
7794
|
-
body.push(seg(["AMT", esc(amount.qualifier),
|
|
7996
|
+
body.push(seg(["AMT", esc(amount.qualifier), escDec6(amount.amount, esc)]));
|
|
7795
7997
|
}
|
|
7796
7998
|
}
|
|
7797
7999
|
function emitRef6(ref, seg, esc) {
|
|
@@ -8184,6 +8386,12 @@ function refuseHierarchy4(message) {
|
|
|
8184
8386
|
message
|
|
8185
8387
|
);
|
|
8186
8388
|
}
|
|
8389
|
+
function refuseSpec7(message) {
|
|
8390
|
+
throw new ServicesReview278BuildError(
|
|
8391
|
+
AUTH_278_BUILD_ERROR_CODES.X12_278_BUILD_INVALID_SPEC,
|
|
8392
|
+
message
|
|
8393
|
+
);
|
|
8394
|
+
}
|
|
8187
8395
|
var X12_278_FUNCTIONAL_ID = "HI";
|
|
8188
8396
|
var X12_AGENCY_CODE7 = "X";
|
|
8189
8397
|
var HL_LEVEL4 = {
|
|
@@ -8212,8 +8420,9 @@ function buildServicesReview(version, direction, spec) {
|
|
|
8212
8420
|
component: componentSeparator,
|
|
8213
8421
|
segment: segmentTerminator
|
|
8214
8422
|
};
|
|
8215
|
-
const esc = (
|
|
8423
|
+
const esc = makeCallerEscaper(delimiters, "build278", refuseSpec7);
|
|
8216
8424
|
const seg = (parts) => {
|
|
8425
|
+
requireCallerSegment(parts, "build278", refuseSpec7);
|
|
8217
8426
|
let end = parts.length;
|
|
8218
8427
|
while (end > 1 && parts[end - 1] === "") end -= 1;
|
|
8219
8428
|
return parts.slice(0, end).join(elementSeparator) + segmentTerminator;
|
|
@@ -8257,8 +8466,8 @@ function buildServicesReview(version, direction, spec) {
|
|
|
8257
8466
|
X12_278_FUNCTIONAL_ID,
|
|
8258
8467
|
esc(applicationSenderCode),
|
|
8259
8468
|
esc(applicationReceiverCode),
|
|
8260
|
-
groupDate,
|
|
8261
|
-
groupTime,
|
|
8469
|
+
esc(groupDate),
|
|
8470
|
+
esc(groupTime),
|
|
8262
8471
|
esc(envelope.groupControlNumber),
|
|
8263
8472
|
X12_AGENCY_CODE7,
|
|
8264
8473
|
version
|
|
@@ -8387,7 +8596,7 @@ function emitReview(review, parentHlId, direction, body, ctx, counter) {
|
|
|
8387
8596
|
const nested = review.reviews ?? [];
|
|
8388
8597
|
const hasChild = nested.length > 0 ? "1" : "0";
|
|
8389
8598
|
const levelCode = review.levelCode ?? DEFAULT_REVIEW_LEVEL;
|
|
8390
|
-
body.push(ctx.seg(["HL", hlId, parentHlId, levelCode, hasChild]));
|
|
8599
|
+
body.push(ctx.seg(["HL", hlId, parentHlId, ctx.esc(levelCode), hasChild]));
|
|
8391
8600
|
for (const trace of review.traces ?? []) {
|
|
8392
8601
|
body.push(
|
|
8393
8602
|
ctx.seg([
|
|
@@ -8963,6 +9172,9 @@ function narrowNoteCode(value) {
|
|
|
8963
9172
|
}
|
|
8964
9173
|
|
|
8965
9174
|
// src/transactions/ack/build-999.ts
|
|
9175
|
+
function refuseSpec8(message) {
|
|
9176
|
+
throw new AckBuildError(ACK_BUILD_ERROR_CODES.X12_ACK_INVALID_SPEC, message);
|
|
9177
|
+
}
|
|
8966
9178
|
var X231A1_VERSION_RELEASE = "005010X231A1";
|
|
8967
9179
|
var X12_AGENCY_CODE8 = "X";
|
|
8968
9180
|
function build999(spec) {
|
|
@@ -8979,7 +9191,7 @@ function build999(spec) {
|
|
|
8979
9191
|
component: componentSeparator,
|
|
8980
9192
|
segment: segmentTerminator
|
|
8981
9193
|
};
|
|
8982
|
-
const esc = (
|
|
9194
|
+
const esc = makeCallerEscaper(delimiters, "build999", refuseSpec8);
|
|
8983
9195
|
const senderQualifier = envelope.senderQualifier ?? "ZZ";
|
|
8984
9196
|
const receiverQualifier = envelope.receiverQualifier ?? "ZZ";
|
|
8985
9197
|
const usageIndicator = envelope.usageIndicator ?? "P";
|
|
@@ -9031,13 +9243,13 @@ function build999(spec) {
|
|
|
9031
9243
|
// GS-02
|
|
9032
9244
|
esc(envelope.receiverId),
|
|
9033
9245
|
// GS-03
|
|
9034
|
-
groupDate,
|
|
9246
|
+
esc(groupDate),
|
|
9035
9247
|
// GS-04 - CCYYMMDD
|
|
9036
|
-
groupTime,
|
|
9248
|
+
esc(groupTime),
|
|
9037
9249
|
// GS-05 - HHMM
|
|
9038
|
-
envelope.groupControlNumber,
|
|
9250
|
+
esc(envelope.groupControlNumber),
|
|
9039
9251
|
// GS-06
|
|
9040
|
-
groupResponsibleAgency,
|
|
9252
|
+
esc(groupResponsibleAgency),
|
|
9041
9253
|
// GS-07
|
|
9042
9254
|
X231A1_VERSION_RELEASE
|
|
9043
9255
|
// GS-08 - the 999 TR3
|
|
@@ -9047,7 +9259,7 @@ function build999(spec) {
|
|
|
9047
9259
|
);
|
|
9048
9260
|
const stControlNumber = envelope.transactionSetControlNumber;
|
|
9049
9261
|
const st = joinSeg(
|
|
9050
|
-
["ST", "999", stControlNumber, X231A1_VERSION_RELEASE],
|
|
9262
|
+
["ST", "999", esc(stControlNumber), X231A1_VERSION_RELEASE],
|
|
9051
9263
|
elementSeparator,
|
|
9052
9264
|
segmentTerminator
|
|
9053
9265
|
);
|
|
@@ -9080,8 +9292,16 @@ function build999(spec) {
|
|
|
9080
9292
|
const ak9 = buildAk9(functionalGroup, esc, elementSeparator, segmentTerminator);
|
|
9081
9293
|
const bodySegments = [st, ak1, ...responseSegments, ak9];
|
|
9082
9294
|
const seCount = bodySegments.length + 1;
|
|
9083
|
-
const se = joinSeg(
|
|
9084
|
-
|
|
9295
|
+
const se = joinSeg(
|
|
9296
|
+
["SE", String(seCount), esc(stControlNumber)],
|
|
9297
|
+
elementSeparator,
|
|
9298
|
+
segmentTerminator
|
|
9299
|
+
);
|
|
9300
|
+
const ge = joinSeg(
|
|
9301
|
+
["GE", "1", esc(envelope.groupControlNumber)],
|
|
9302
|
+
elementSeparator,
|
|
9303
|
+
segmentTerminator
|
|
9304
|
+
);
|
|
9085
9305
|
const iea = joinSeg(["IEA", "1", interchangeControlNumber], elementSeparator, segmentTerminator);
|
|
9086
9306
|
const raw = isa + gs + bodySegments.join("") + se + ge + iea;
|
|
9087
9307
|
return parseX12(raw);
|
|
@@ -9203,7 +9423,7 @@ function buildIk4(elemError, esc, componentSeparator, elementSeparator, segmentT
|
|
|
9203
9423
|
return joinSeg(parts, elementSeparator, segmentTerminator);
|
|
9204
9424
|
}
|
|
9205
9425
|
function buildIk5(response, esc, elementSeparator, segmentTerminator) {
|
|
9206
|
-
const parts = ["IK5", response.disposition];
|
|
9426
|
+
const parts = ["IK5", esc(response.disposition)];
|
|
9207
9427
|
const codes = response.syntaxErrorCodes ?? [];
|
|
9208
9428
|
if (codes.length > 5) {
|
|
9209
9429
|
throw new AckBuildError(
|
|
@@ -9217,7 +9437,7 @@ function buildIk5(response, esc, elementSeparator, segmentTerminator) {
|
|
|
9217
9437
|
function buildAk9(group, esc, elementSeparator, segmentTerminator) {
|
|
9218
9438
|
const parts = [
|
|
9219
9439
|
"AK9",
|
|
9220
|
-
group.disposition,
|
|
9440
|
+
esc(group.disposition),
|
|
9221
9441
|
String(group.numberOfTransactionSets),
|
|
9222
9442
|
String(group.numberOfReceivedTransactionSets),
|
|
9223
9443
|
String(group.numberOfAcceptedTransactionSets)
|
|
@@ -9233,6 +9453,7 @@ function buildAk9(group, esc, elementSeparator, segmentTerminator) {
|
|
|
9233
9453
|
return joinSeg(parts, elementSeparator, segmentTerminator);
|
|
9234
9454
|
}
|
|
9235
9455
|
function joinSeg(parts, elementSeparator, segmentTerminator) {
|
|
9456
|
+
requireCallerSegment(parts, "build999", refuseSpec8);
|
|
9236
9457
|
return parts.join(elementSeparator) + segmentTerminator;
|
|
9237
9458
|
}
|
|
9238
9459
|
function pad8(value, width) {
|
|
@@ -9459,6 +9680,9 @@ var X12BuildError = class extends Error {
|
|
|
9459
9680
|
};
|
|
9460
9681
|
|
|
9461
9682
|
// src/builder/build-interchange.ts
|
|
9683
|
+
function refuseSpec9(message) {
|
|
9684
|
+
throw new X12BuildError(X12_BUILD_ERROR_CODES.X12_BUILD_INVALID_SPEC, message);
|
|
9685
|
+
}
|
|
9462
9686
|
function buildInterchange(spec) {
|
|
9463
9687
|
const elementSeparator = spec.elementSeparator ?? "*";
|
|
9464
9688
|
const repetitionSeparator = spec.repetitionSeparator ?? "^";
|
|
@@ -9470,7 +9694,7 @@ function buildInterchange(spec) {
|
|
|
9470
9694
|
component: componentSeparator,
|
|
9471
9695
|
segment: segmentTerminator
|
|
9472
9696
|
};
|
|
9473
|
-
const esc = (
|
|
9697
|
+
const esc = makeCallerEscaper(delimiters, "buildInterchange", refuseSpec9);
|
|
9474
9698
|
const senderQualifier = spec.senderQualifier ?? "ZZ";
|
|
9475
9699
|
const receiverQualifier = spec.receiverQualifier ?? "ZZ";
|
|
9476
9700
|
const usageIndicator = spec.usageIndicator ?? "P";
|
|
@@ -9584,6 +9808,7 @@ function buildTransaction(tx, esc, elementSeparator, segmentTerminator) {
|
|
|
9584
9808
|
return st + bodySegments + se;
|
|
9585
9809
|
}
|
|
9586
9810
|
function joinSeg2(parts, elementSeparator, segmentTerminator) {
|
|
9811
|
+
requireCallerSegment(parts, "buildInterchange", refuseSpec9);
|
|
9587
9812
|
return parts.join(elementSeparator) + segmentTerminator;
|
|
9588
9813
|
}
|
|
9589
9814
|
function pad9(value, width) {
|
|
@@ -9892,7 +10117,7 @@ var profiles = Object.freeze({
|
|
|
9892
10117
|
});
|
|
9893
10118
|
|
|
9894
10119
|
// src/index.ts
|
|
9895
|
-
var VERSION = "0.0.
|
|
10120
|
+
var VERSION = "0.0.10";
|
|
9896
10121
|
|
|
9897
10122
|
exports.ACK_BUILD_ERROR_CODES = ACK_BUILD_ERROR_CODES;
|
|
9898
10123
|
exports.ALL_WARNING_MESSAGES = ALL_WARNING_MESSAGES;
|
|
@@ -10067,11 +10292,14 @@ exports.parseX12 = parseX12;
|
|
|
10067
10292
|
exports.partitionWarnings = partitionWarnings;
|
|
10068
10293
|
exports.pre005010 = pre005010;
|
|
10069
10294
|
exports.profiles = profiles;
|
|
10295
|
+
exports.readElementDecimal = readElementDecimal;
|
|
10070
10296
|
exports.remitBalanceMismatch = remitBalanceMismatch;
|
|
10071
10297
|
exports.renderCallerValue = renderCallerValue;
|
|
10072
10298
|
exports.resolveHiQualifier = resolveHiQualifier;
|
|
10073
10299
|
exports.segmentCountMismatch = segmentCountMismatch;
|
|
10074
10300
|
exports.serializeX12 = serializeX12;
|
|
10301
|
+
exports.serviceLineDropped = serviceLineDropped;
|
|
10302
|
+
exports.serviceLineNotDecoded = serviceLineNotDecoded;
|
|
10075
10303
|
exports.setDefaultProfile = setDefaultProfile;
|
|
10076
10304
|
exports.trailingGarbage = trailingGarbage;
|
|
10077
10305
|
exports.transactionCountMismatch = transactionCountMismatch;
|
|
@@ -10084,5 +10312,6 @@ exports.unknownClaimStatusCategory = unknownClaimStatusCategory;
|
|
|
10084
10312
|
exports.unknownHiQualifier = unknownHiQualifier;
|
|
10085
10313
|
exports.unknownMaintenanceType = unknownMaintenanceType;
|
|
10086
10314
|
exports.unknownRarc = unknownRarc;
|
|
10315
|
+
exports.unparseableDecimal = unparseableDecimal;
|
|
10087
10316
|
//# sourceMappingURL=index.cjs.map
|
|
10088
10317
|
//# sourceMappingURL=index.cjs.map
|