@cosyte/x12 0.0.9 → 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 +336 -4
- package/dist/index.cjs +360 -171
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +241 -7
- package/dist/index.d.ts +241 -7
- package/dist/index.mjs +357 -172
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -138,7 +138,10 @@ var WARNING_CODES = {
|
|
|
138
138
|
X12_837_UNKNOWN_VARIANT: "X12_837_UNKNOWN_VARIANT",
|
|
139
139
|
X12_UNKNOWN_CLAIM_STATUS_CATEGORY: "X12_UNKNOWN_CLAIM_STATUS_CATEGORY",
|
|
140
140
|
X12_UNKNOWN_CLAIM_STATUS: "X12_UNKNOWN_CLAIM_STATUS",
|
|
141
|
-
X12_834_UNKNOWN_MAINTENANCE_TYPE: "X12_834_UNKNOWN_MAINTENANCE_TYPE"
|
|
141
|
+
X12_834_UNKNOWN_MAINTENANCE_TYPE: "X12_834_UNKNOWN_MAINTENANCE_TYPE",
|
|
142
|
+
X12_UNPARSEABLE_DECIMAL: "X12_UNPARSEABLE_DECIMAL",
|
|
143
|
+
X12_837_SERVICE_LINE_NOT_DECODED: "X12_837_SERVICE_LINE_NOT_DECODED",
|
|
144
|
+
X12_837_SERVICE_LINE_DROPPED: "X12_837_SERVICE_LINE_DROPPED"
|
|
142
145
|
};
|
|
143
146
|
var CONTROL_NUMBER_PAIRS = {
|
|
144
147
|
/** ISA-13 against IEA-02. */
|
|
@@ -211,7 +214,10 @@ var WARNING_MESSAGES = {
|
|
|
211
214
|
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.`,
|
|
212
215
|
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.",
|
|
213
216
|
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.",
|
|
214
|
-
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."
|
|
217
|
+
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.",
|
|
218
|
+
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.",
|
|
219
|
+
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.",
|
|
220
|
+
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."
|
|
215
221
|
};
|
|
216
222
|
var ALL_WARNING_MESSAGES = new Set(
|
|
217
223
|
Object.values(WARNING_MESSAGES)
|
|
@@ -372,6 +378,20 @@ function unknown837Variant(position) {
|
|
|
372
378
|
position
|
|
373
379
|
};
|
|
374
380
|
}
|
|
381
|
+
function serviceLineNotDecoded(position) {
|
|
382
|
+
return {
|
|
383
|
+
code: WARNING_CODES.X12_837_SERVICE_LINE_NOT_DECODED,
|
|
384
|
+
message: WARNING_MESSAGES.X12_837_SERVICE_LINE_NOT_DECODED,
|
|
385
|
+
position
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
function serviceLineDropped(position) {
|
|
389
|
+
return {
|
|
390
|
+
code: WARNING_CODES.X12_837_SERVICE_LINE_DROPPED,
|
|
391
|
+
message: WARNING_MESSAGES.X12_837_SERVICE_LINE_DROPPED,
|
|
392
|
+
position
|
|
393
|
+
};
|
|
394
|
+
}
|
|
375
395
|
function unknownClaimStatusCategory(position) {
|
|
376
396
|
return {
|
|
377
397
|
code: WARNING_CODES.X12_UNKNOWN_CLAIM_STATUS_CATEGORY,
|
|
@@ -393,6 +413,13 @@ function unknownMaintenanceType(position) {
|
|
|
393
413
|
position
|
|
394
414
|
};
|
|
395
415
|
}
|
|
416
|
+
function unparseableDecimal(position) {
|
|
417
|
+
return {
|
|
418
|
+
code: WARNING_CODES.X12_UNPARSEABLE_DECIMAL,
|
|
419
|
+
message: WARNING_MESSAGES.X12_UNPARSEABLE_DECIMAL,
|
|
420
|
+
position
|
|
421
|
+
};
|
|
422
|
+
}
|
|
396
423
|
|
|
397
424
|
// src/parser/release.ts
|
|
398
425
|
var RELEASE_CHAR = "?";
|
|
@@ -906,13 +933,26 @@ function componentOptional(seg, n, p, delimiters) {
|
|
|
906
933
|
const v = getSegmentValue(seg, `${String(n).padStart(2, "0")}-${String(p)}`, delimiters);
|
|
907
934
|
return v === void 0 || v === "" ? void 0 : v;
|
|
908
935
|
}
|
|
909
|
-
function
|
|
936
|
+
function readElementDecimal(seg, n, delimiters) {
|
|
910
937
|
const raw = elementOptional(seg, n, delimiters);
|
|
911
|
-
if (raw === void 0) return void 0;
|
|
912
|
-
|
|
938
|
+
if (raw === void 0) return { value: void 0, status: "absent" };
|
|
939
|
+
const value = X12Decimal.fromString(raw);
|
|
940
|
+
if (value === void 0) return { value: void 0, status: "unparseable" };
|
|
941
|
+
return { value, status: "decoded" };
|
|
913
942
|
}
|
|
914
|
-
function
|
|
915
|
-
|
|
943
|
+
function elementDecimal(seg, n, delimiters, sink) {
|
|
944
|
+
const read = readElementDecimal(seg, n, delimiters);
|
|
945
|
+
if (read.status === "unparseable" && sink !== void 0) {
|
|
946
|
+
sink.warnings.push(unparseableDecimal({ ...sink.position, elementIndex: n }));
|
|
947
|
+
}
|
|
948
|
+
return read.value;
|
|
949
|
+
}
|
|
950
|
+
function elementDecimalOrZero(seg, n, delimiters, sink) {
|
|
951
|
+
const read = readElementDecimal(seg, n, delimiters);
|
|
952
|
+
if (read.status === "unparseable" && sink !== void 0) {
|
|
953
|
+
sink.warnings.push(unparseableDecimal({ ...sink.position, elementIndex: n }));
|
|
954
|
+
}
|
|
955
|
+
return read.value ?? X12Decimal.ZERO;
|
|
916
956
|
}
|
|
917
957
|
function collectElementValues(seg, start, end, delimiters) {
|
|
918
958
|
const out = [];
|
|
@@ -1418,6 +1458,7 @@ function defineLoopSpec(input) {
|
|
|
1418
1458
|
// src/code-lists/meta.ts
|
|
1419
1459
|
function makeLookup(snapshot) {
|
|
1420
1460
|
return (code) => {
|
|
1461
|
+
if (!Object.hasOwn(snapshot.codes, code)) return void 0;
|
|
1421
1462
|
const description = snapshot.codes[code];
|
|
1422
1463
|
if (description === void 0) return void 0;
|
|
1423
1464
|
return Object.freeze({ code, description });
|
|
@@ -1666,7 +1707,7 @@ var CLAIM_ADJUSTMENT_GROUP_CODES = {
|
|
|
1666
1707
|
PI: "PI"
|
|
1667
1708
|
};
|
|
1668
1709
|
function isClaimAdjustmentGroupCode(value) {
|
|
1669
|
-
return value
|
|
1710
|
+
return Object.hasOwn(CLAIM_ADJUSTMENT_GROUP_CODES, value);
|
|
1670
1711
|
}
|
|
1671
1712
|
|
|
1672
1713
|
// src/code-lists/rarc.ts
|
|
@@ -1806,6 +1847,7 @@ var HI_QUALIFIERS = {
|
|
|
1806
1847
|
}
|
|
1807
1848
|
};
|
|
1808
1849
|
function resolveHiQualifier(qualifier) {
|
|
1850
|
+
if (!Object.hasOwn(HI_QUALIFIERS, qualifier)) return void 0;
|
|
1809
1851
|
return HI_QUALIFIERS[qualifier];
|
|
1810
1852
|
}
|
|
1811
1853
|
function isDiagnosisQualifier(qualifier) {
|
|
@@ -1915,9 +1957,10 @@ function get835(delimiters, tx) {
|
|
|
1915
1957
|
const seg = body[i];
|
|
1916
1958
|
if (seg === void 0) continue;
|
|
1917
1959
|
const position = { segmentIndex: i + 1, transactionIndex: 0 };
|
|
1960
|
+
const sink = { warnings, position };
|
|
1918
1961
|
switch (seg.id) {
|
|
1919
1962
|
case "BPR": {
|
|
1920
|
-
payment = decodeBpr(seg, delimiters);
|
|
1963
|
+
payment = decodeBpr(seg, delimiters, sink);
|
|
1921
1964
|
bprSegmentIndex = position.segmentIndex;
|
|
1922
1965
|
break;
|
|
1923
1966
|
}
|
|
@@ -1992,7 +2035,7 @@ function get835(delimiters, tx) {
|
|
|
1992
2035
|
case "CLP": {
|
|
1993
2036
|
flushClaim();
|
|
1994
2037
|
lastParty = void 0;
|
|
1995
|
-
currentClaim = openClaim(seg, delimiters, position.segmentIndex);
|
|
2038
|
+
currentClaim = openClaim(seg, delimiters, position.segmentIndex, sink);
|
|
1996
2039
|
break;
|
|
1997
2040
|
}
|
|
1998
2041
|
case "CAS": {
|
|
@@ -2044,7 +2087,7 @@ function get835(delimiters, tx) {
|
|
|
2044
2087
|
break;
|
|
2045
2088
|
}
|
|
2046
2089
|
case "AMT": {
|
|
2047
|
-
const amount = decodeAmt(seg, delimiters);
|
|
2090
|
+
const amount = decodeAmt(seg, delimiters, sink);
|
|
2048
2091
|
if (amount === void 0) break;
|
|
2049
2092
|
if (currentServiceLine !== void 0) currentServiceLine.amounts.push(amount);
|
|
2050
2093
|
else if (currentClaim !== void 0) currentClaim.amounts.push(amount);
|
|
@@ -2063,12 +2106,12 @@ function get835(delimiters, tx) {
|
|
|
2063
2106
|
}
|
|
2064
2107
|
case "SVC": {
|
|
2065
2108
|
flushServiceLine();
|
|
2066
|
-
currentServiceLine = openServiceLine(seg, delimiters);
|
|
2109
|
+
currentServiceLine = openServiceLine(seg, delimiters, sink);
|
|
2067
2110
|
break;
|
|
2068
2111
|
}
|
|
2069
2112
|
case "PLB": {
|
|
2070
2113
|
flushClaim();
|
|
2071
|
-
for (const p of decodePlb(seg, delimiters)) providerAdjustments.push(p);
|
|
2114
|
+
for (const p of decodePlb(seg, delimiters, sink)) providerAdjustments.push(p);
|
|
2072
2115
|
break;
|
|
2073
2116
|
}
|
|
2074
2117
|
}
|
|
@@ -2099,10 +2142,10 @@ function get835(delimiters, tx) {
|
|
|
2099
2142
|
warnings: Object.freeze(warnings.slice())
|
|
2100
2143
|
});
|
|
2101
2144
|
}
|
|
2102
|
-
function decodeBpr(seg, delimiters) {
|
|
2145
|
+
function decodeBpr(seg, delimiters, sink) {
|
|
2103
2146
|
return Object.freeze({
|
|
2104
2147
|
transactionHandlingCode: elementValue(seg, 1, delimiters),
|
|
2105
|
-
totalActualPayment: elementDecimalOrZero(seg, 2, delimiters),
|
|
2148
|
+
totalActualPayment: elementDecimalOrZero(seg, 2, delimiters, sink),
|
|
2106
2149
|
creditDebitFlag: elementValue(seg, 3, delimiters),
|
|
2107
2150
|
method: elementValue(seg, 4, delimiters),
|
|
2108
2151
|
paymentFormatCode: elementOptional(seg, 5, delimiters),
|
|
@@ -2161,8 +2204,8 @@ function decodePer(seg, delimiters) {
|
|
|
2161
2204
|
communications: Object.freeze(comms)
|
|
2162
2205
|
});
|
|
2163
2206
|
}
|
|
2164
|
-
function decodeAmt(seg, delimiters) {
|
|
2165
|
-
const amount = elementDecimal(seg, 2, delimiters);
|
|
2207
|
+
function decodeAmt(seg, delimiters, sink) {
|
|
2208
|
+
const amount = elementDecimal(seg, 2, delimiters, sink);
|
|
2166
2209
|
if (amount === void 0) return void 0;
|
|
2167
2210
|
return Object.freeze({
|
|
2168
2211
|
qualifier: elementValue(seg, 1, delimiters),
|
|
@@ -2198,13 +2241,14 @@ function collectMoaRemarks(seg, delimiters) {
|
|
|
2198
2241
|
return out;
|
|
2199
2242
|
}
|
|
2200
2243
|
function decodeCasAdjustments(seg, delimiters, warnings, position) {
|
|
2244
|
+
const sink = { warnings, position };
|
|
2201
2245
|
const groupCode = elementValue(seg, 1, delimiters);
|
|
2202
2246
|
const out = [];
|
|
2203
2247
|
for (let triple = 0; triple < 6; triple += 1) {
|
|
2204
2248
|
const base = 2 + triple * 3;
|
|
2205
2249
|
const reasonCode = elementOptional(seg, base, delimiters);
|
|
2206
|
-
const amount = elementDecimal(seg, base + 1, delimiters);
|
|
2207
|
-
const quantity = elementDecimal(seg, base + 2, delimiters);
|
|
2250
|
+
const amount = elementDecimal(seg, base + 1, delimiters, sink);
|
|
2251
|
+
const quantity = elementDecimal(seg, base + 2, delimiters, sink);
|
|
2208
2252
|
if (reasonCode === void 0 && amount === void 0) continue;
|
|
2209
2253
|
const code = reasonCode ?? "";
|
|
2210
2254
|
const entry = code === "" ? void 0 : lookupCarc(code);
|
|
@@ -2248,7 +2292,7 @@ function decodeNm1(seg, delimiters) {
|
|
|
2248
2292
|
})
|
|
2249
2293
|
};
|
|
2250
2294
|
}
|
|
2251
|
-
function openClaim(seg, delimiters, clpSegmentIndex) {
|
|
2295
|
+
function openClaim(seg, delimiters, clpSegmentIndex, sink) {
|
|
2252
2296
|
const claimStatusCode = elementValue(seg, 2, delimiters);
|
|
2253
2297
|
const claimStatusDescription = lookupClpStatus(claimStatusCode)?.description;
|
|
2254
2298
|
const facilityTypeCode = componentOptional(seg, 8, 1, delimiters) ?? elementOptional(seg, 8, delimiters);
|
|
@@ -2258,9 +2302,9 @@ function openClaim(seg, delimiters, clpSegmentIndex) {
|
|
|
2258
2302
|
patientControlNumber: elementValue(seg, 1, delimiters),
|
|
2259
2303
|
claimStatusCode,
|
|
2260
2304
|
claimStatusDescription,
|
|
2261
|
-
totalChargeAmount: elementDecimalOrZero(seg, 3, delimiters),
|
|
2262
|
-
totalPaymentAmount: elementDecimalOrZero(seg, 4, delimiters),
|
|
2263
|
-
patientResponsibilityAmount: elementDecimalOrZero(seg, 5, delimiters),
|
|
2305
|
+
totalChargeAmount: elementDecimalOrZero(seg, 3, delimiters, sink),
|
|
2306
|
+
totalPaymentAmount: elementDecimalOrZero(seg, 4, delimiters, sink),
|
|
2307
|
+
patientResponsibilityAmount: elementDecimalOrZero(seg, 5, delimiters, sink),
|
|
2264
2308
|
claimFilingIndicatorCode: elementOptional(seg, 6, delimiters),
|
|
2265
2309
|
payerClaimControlNumber: elementOptional(seg, 7, delimiters),
|
|
2266
2310
|
facilityTypeCode,
|
|
@@ -2279,7 +2323,7 @@ function openClaim(seg, delimiters, clpSegmentIndex) {
|
|
|
2279
2323
|
serviceLines: []
|
|
2280
2324
|
};
|
|
2281
2325
|
}
|
|
2282
|
-
function openServiceLine(seg, delimiters) {
|
|
2326
|
+
function openServiceLine(seg, delimiters, sink) {
|
|
2283
2327
|
const productServiceIdQualifier = componentOptional(seg, 1, 1, delimiters) ?? "";
|
|
2284
2328
|
const productServiceId = componentOptional(seg, 1, 2, delimiters) ?? "";
|
|
2285
2329
|
const modifiers = [];
|
|
@@ -2287,18 +2331,20 @@ function openServiceLine(seg, delimiters) {
|
|
|
2287
2331
|
const m = componentOptional(seg, 1, comp, delimiters);
|
|
2288
2332
|
if (m !== void 0) modifiers.push(m);
|
|
2289
2333
|
}
|
|
2290
|
-
const revenueCode = elementOptional(seg,
|
|
2291
|
-
const paidUnitsOfService = elementDecimal(seg,
|
|
2334
|
+
const revenueCode = elementOptional(seg, 4, delimiters);
|
|
2335
|
+
const paidUnitsOfService = elementDecimal(seg, 5, delimiters, sink);
|
|
2336
|
+
const originalUnitsOfService = elementDecimal(seg, 7, delimiters, sink);
|
|
2292
2337
|
const originalServiceIdQualifier = componentOptional(seg, 6, 1, delimiters);
|
|
2293
2338
|
const originalServiceId = componentOptional(seg, 6, 2, delimiters);
|
|
2294
2339
|
return {
|
|
2295
2340
|
productServiceIdQualifier,
|
|
2296
2341
|
productServiceId,
|
|
2297
2342
|
modifiers,
|
|
2298
|
-
chargeAmount: elementDecimalOrZero(seg, 2, delimiters),
|
|
2299
|
-
paymentAmount: elementDecimalOrZero(seg, 3, delimiters),
|
|
2343
|
+
chargeAmount: elementDecimalOrZero(seg, 2, delimiters, sink),
|
|
2344
|
+
paymentAmount: elementDecimalOrZero(seg, 3, delimiters, sink),
|
|
2300
2345
|
revenueCode,
|
|
2301
2346
|
paidUnitsOfService,
|
|
2347
|
+
originalUnitsOfService,
|
|
2302
2348
|
originalServiceId,
|
|
2303
2349
|
originalServiceIdQualifier,
|
|
2304
2350
|
serviceDateStart: void 0,
|
|
@@ -2324,13 +2370,13 @@ function attachServiceLineDtm(line, seg, delimiters) {
|
|
|
2324
2370
|
if (qualifier === "472" || qualifier === "150") line.serviceDateStart = date;
|
|
2325
2371
|
if (qualifier === "472" || qualifier === "151") line.serviceDateEnd = date;
|
|
2326
2372
|
}
|
|
2327
|
-
function decodePlb(seg, delimiters) {
|
|
2373
|
+
function decodePlb(seg, delimiters, sink) {
|
|
2328
2374
|
const providerId = elementValue(seg, 1, delimiters);
|
|
2329
2375
|
const fiscalPeriodDate = elementValue(seg, 2, delimiters);
|
|
2330
2376
|
const out = [];
|
|
2331
2377
|
for (let pair = 0; pair < 6; pair += 1) {
|
|
2332
2378
|
const composite = 3 + pair * 2;
|
|
2333
|
-
const amount = elementDecimal(seg, composite + 1, delimiters);
|
|
2379
|
+
const amount = elementDecimal(seg, composite + 1, delimiters, sink);
|
|
2334
2380
|
const reasonCode = componentOptional(seg, composite, 1, delimiters);
|
|
2335
2381
|
const subCode = componentOptional(seg, composite, 2, delimiters);
|
|
2336
2382
|
if (amount === void 0 && reasonCode === void 0) continue;
|
|
@@ -2394,6 +2440,7 @@ function freezeServiceLine(acc) {
|
|
|
2394
2440
|
paymentAmount: acc.paymentAmount,
|
|
2395
2441
|
revenueCode: acc.revenueCode,
|
|
2396
2442
|
paidUnitsOfService: acc.paidUnitsOfService,
|
|
2443
|
+
originalUnitsOfService: acc.originalUnitsOfService,
|
|
2397
2444
|
originalServiceId: acc.originalServiceId,
|
|
2398
2445
|
originalServiceIdQualifier: acc.originalServiceIdQualifier,
|
|
2399
2446
|
serviceDateStart: acc.serviceDateStart,
|
|
@@ -2509,6 +2556,49 @@ function isRealArray(value) {
|
|
|
2509
2556
|
return Array.isArray(value);
|
|
2510
2557
|
}
|
|
2511
2558
|
|
|
2559
|
+
// src/builder/caller-decimal.ts
|
|
2560
|
+
function describeCallerDecimal(value) {
|
|
2561
|
+
if (value === null) return "null";
|
|
2562
|
+
if (value === void 0) return "undefined";
|
|
2563
|
+
const type = typeof value;
|
|
2564
|
+
if (type === "object") return Array.isArray(value) ? "an array" : "an object";
|
|
2565
|
+
if (type === "function") return "a function";
|
|
2566
|
+
return `a ${type} (${renderCallerValue(value)})`;
|
|
2567
|
+
}
|
|
2568
|
+
function requireCallerDecimal(value, at, refuse) {
|
|
2569
|
+
if (value instanceof X12Decimal) return value;
|
|
2570
|
+
refuse(
|
|
2571
|
+
`${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.`
|
|
2572
|
+
);
|
|
2573
|
+
}
|
|
2574
|
+
|
|
2575
|
+
// src/builder/caller-segment.ts
|
|
2576
|
+
function describeSegmentValue(value) {
|
|
2577
|
+
if (value === null) return "null";
|
|
2578
|
+
if (value === void 0) return "undefined";
|
|
2579
|
+
const type = typeof value;
|
|
2580
|
+
if (type === "object") return Array.isArray(value) ? "an array" : "an object";
|
|
2581
|
+
if (type === "function") return "a function";
|
|
2582
|
+
return `a ${type} (${renderCallerValue(value)})`;
|
|
2583
|
+
}
|
|
2584
|
+
function locateSlot(parts, index) {
|
|
2585
|
+
const id = parts[0];
|
|
2586
|
+
const position = String(index).padStart(2, "0");
|
|
2587
|
+
if (typeof id !== "string" || id.length === 0) return `element ${String(index)}`;
|
|
2588
|
+
return `${renderCallerValue(id)}-${position}`;
|
|
2589
|
+
}
|
|
2590
|
+
function requireCallerSegment(parts, at, refuse) {
|
|
2591
|
+
let index = 0;
|
|
2592
|
+
for (const part of parts) {
|
|
2593
|
+
if (typeof part !== "string") {
|
|
2594
|
+
refuse(
|
|
2595
|
+
`${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.`
|
|
2596
|
+
);
|
|
2597
|
+
}
|
|
2598
|
+
index += 1;
|
|
2599
|
+
}
|
|
2600
|
+
}
|
|
2601
|
+
|
|
2512
2602
|
// src/builder/caller-string.ts
|
|
2513
2603
|
function describeCallerValue(value) {
|
|
2514
2604
|
if (value === null) return "null";
|
|
@@ -2532,6 +2622,9 @@ function makeCallerEscaper(delimiters, at, refuse) {
|
|
|
2532
2622
|
function refuseSpec(message) {
|
|
2533
2623
|
throw new Remit835BuildError(REMIT_835_BUILD_ERROR_CODES.X12_835_BUILD_INVALID_SPEC, message);
|
|
2534
2624
|
}
|
|
2625
|
+
function escDec(value, esc) {
|
|
2626
|
+
return esc(requireCallerDecimal(value, "build835", refuseSpec).toString());
|
|
2627
|
+
}
|
|
2535
2628
|
var X221A1_VERSION_RELEASE = "005010X221A1";
|
|
2536
2629
|
var X12_835_FUNCTIONAL_ID = "HP";
|
|
2537
2630
|
var X12_AGENCY_CODE = "X";
|
|
@@ -2555,6 +2648,7 @@ function build835(spec) {
|
|
|
2555
2648
|
};
|
|
2556
2649
|
const esc = makeCallerEscaper(delimiters, "build835", refuseSpec);
|
|
2557
2650
|
const seg = (parts) => {
|
|
2651
|
+
requireCallerSegment(parts, "build835", refuseSpec);
|
|
2558
2652
|
let end = parts.length;
|
|
2559
2653
|
while (end > 1 && parts[end - 1] === "") end -= 1;
|
|
2560
2654
|
return parts.slice(0, end).join(elementSeparator) + segmentTerminator;
|
|
@@ -2616,9 +2710,9 @@ function build835(spec) {
|
|
|
2616
2710
|
// GS-02
|
|
2617
2711
|
esc(applicationReceiverCode),
|
|
2618
2712
|
// GS-03
|
|
2619
|
-
groupDate,
|
|
2713
|
+
esc(groupDate),
|
|
2620
2714
|
// GS-04 - CCYYMMDD
|
|
2621
|
-
groupTime,
|
|
2715
|
+
esc(groupTime),
|
|
2622
2716
|
// GS-05 - HHMM
|
|
2623
2717
|
esc(envelope.groupControlNumber),
|
|
2624
2718
|
// GS-06
|
|
@@ -2634,7 +2728,7 @@ function build835(spec) {
|
|
|
2634
2728
|
seg([
|
|
2635
2729
|
"BPR",
|
|
2636
2730
|
esc(spec.payment.transactionHandlingCode),
|
|
2637
|
-
|
|
2731
|
+
escDec(spec.payment.totalActualPayment, esc),
|
|
2638
2732
|
esc(spec.payment.creditDebitFlag),
|
|
2639
2733
|
esc(spec.payment.method),
|
|
2640
2734
|
esc(spec.payment.paymentFormatCode ?? ""),
|
|
@@ -2769,6 +2863,7 @@ function materializeServiceLine(spec) {
|
|
|
2769
2863
|
paymentAmount: spec.paymentAmount,
|
|
2770
2864
|
revenueCode: spec.revenueCode,
|
|
2771
2865
|
paidUnitsOfService: spec.paidUnitsOfService,
|
|
2866
|
+
originalUnitsOfService: spec.originalUnitsOfService,
|
|
2772
2867
|
originalServiceId: spec.originalServiceId,
|
|
2773
2868
|
originalServiceIdQualifier: spec.originalServiceIdQualifier,
|
|
2774
2869
|
serviceDateStart: spec.serviceDateStart,
|
|
@@ -2864,9 +2959,9 @@ function emitClaim(claim, body, seg, esc, comp) {
|
|
|
2864
2959
|
"CLP",
|
|
2865
2960
|
esc(claim.patientControlNumber),
|
|
2866
2961
|
esc(claim.claimStatusCode),
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2962
|
+
escDec(claim.totalChargeAmount, esc),
|
|
2963
|
+
escDec(claim.totalPaymentAmount, esc),
|
|
2964
|
+
escDec(claim.patientResponsibilityAmount, esc),
|
|
2870
2965
|
esc(claim.claimFilingIndicatorCode ?? ""),
|
|
2871
2966
|
esc(claim.payerClaimControlNumber ?? ""),
|
|
2872
2967
|
comp([claim.facilityTypeCode ?? "", "", claim.claimFrequencyCode ?? ""])
|
|
@@ -2888,7 +2983,7 @@ function emitClaim(claim, body, seg, esc, comp) {
|
|
|
2888
2983
|
}
|
|
2889
2984
|
for (const ref of claim.references ?? []) body.push(emitRef(ref, seg, esc));
|
|
2890
2985
|
for (const amt of claim.amounts ?? []) {
|
|
2891
|
-
body.push(seg(["AMT", esc(amt.qualifier),
|
|
2986
|
+
body.push(seg(["AMT", esc(amt.qualifier), escDec(amt.amount, esc)]));
|
|
2892
2987
|
}
|
|
2893
2988
|
for (const remark of claim.remarks ?? []) {
|
|
2894
2989
|
body.push(seg(["LQ", esc(remark.system), esc(remark.code)]));
|
|
@@ -2908,20 +3003,24 @@ function emitServiceLine(line, body, seg, esc, comp) {
|
|
|
2908
3003
|
seg([
|
|
2909
3004
|
"SVC",
|
|
2910
3005
|
svc01,
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
// SVC-
|
|
3006
|
+
escDec(line.chargeAmount, esc),
|
|
3007
|
+
escDec(line.paymentAmount, esc),
|
|
3008
|
+
// SVC-04 is the NUBC revenue code (element 234, Product/Service ID) and
|
|
3009
|
+
// SVC-05 is the Units of Service PAID Count (element 380, Quantity).
|
|
3010
|
+
// SVC-07 is the ORIGINAL (submitted) units, a different quantity from
|
|
3011
|
+
// SVC-05 - so the two never share a field. See the SVC note in
|
|
3012
|
+
// KNOWN-LIMITATIONS.md for the sources.
|
|
2915
3013
|
esc(line.revenueCode ?? ""),
|
|
3014
|
+
line.paidUnitsOfService === void 0 ? "" : escDec(line.paidUnitsOfService, esc),
|
|
2916
3015
|
svc06,
|
|
2917
|
-
line.
|
|
3016
|
+
line.originalUnitsOfService === void 0 ? "" : escDec(line.originalUnitsOfService, esc)
|
|
2918
3017
|
])
|
|
2919
3018
|
);
|
|
2920
3019
|
emitServiceLineDtm(line, body, seg, esc);
|
|
2921
3020
|
emitCasGroup(line.adjustments, "build835: serviceLine.adjustments", body, seg, esc);
|
|
2922
3021
|
for (const ref of line.references ?? []) body.push(emitRef(ref, seg, esc));
|
|
2923
3022
|
for (const amt of line.amounts ?? []) {
|
|
2924
|
-
body.push(seg(["AMT", esc(amt.qualifier),
|
|
3023
|
+
body.push(seg(["AMT", esc(amt.qualifier), escDec(amt.amount, esc)]));
|
|
2925
3024
|
}
|
|
2926
3025
|
for (const remark of line.remarks ?? []) {
|
|
2927
3026
|
body.push(seg(["LQ", esc(remark.system), esc(remark.code)]));
|
|
@@ -2953,8 +3052,8 @@ function emitCasGroup(raw, at, body, seg, esc) {
|
|
|
2953
3052
|
if (adj === void 0 || adj.groupCode !== groupCode) break;
|
|
2954
3053
|
parts.push(
|
|
2955
3054
|
esc(adj.reasonCode),
|
|
2956
|
-
|
|
2957
|
-
adj.quantity === void 0 ? "" :
|
|
3055
|
+
escDec(adj.amount, esc),
|
|
3056
|
+
adj.quantity === void 0 ? "" : escDec(adj.quantity, esc)
|
|
2958
3057
|
);
|
|
2959
3058
|
triples += 1;
|
|
2960
3059
|
i += 1;
|
|
@@ -3012,7 +3111,7 @@ function emitProviderAdjustments(raw, at, body, seg, esc, comp) {
|
|
|
3012
3111
|
if (adj === void 0 || adj.providerId !== providerId || adj.fiscalPeriodDate !== fiscalPeriodDate) {
|
|
3013
3112
|
break;
|
|
3014
3113
|
}
|
|
3015
|
-
parts.push(comp([adj.reasonCode, adj.subCode ?? ""]),
|
|
3114
|
+
parts.push(comp([adj.reasonCode, adj.subCode ?? ""]), escDec(adj.amount, esc));
|
|
3016
3115
|
pairs += 1;
|
|
3017
3116
|
i += 1;
|
|
3018
3117
|
}
|
|
@@ -3110,13 +3209,22 @@ var REMIT_835_LOOP_1000B = defineLoopSpec({
|
|
|
3110
3209
|
]
|
|
3111
3210
|
});
|
|
3112
3211
|
|
|
3212
|
+
// src/parser/lookup.ts
|
|
3213
|
+
function wireLookup(entries) {
|
|
3214
|
+
const table = /* @__PURE__ */ Object.create(null);
|
|
3215
|
+
for (const [key, value] of Object.entries(entries)) {
|
|
3216
|
+
table[key] = value;
|
|
3217
|
+
}
|
|
3218
|
+
return Object.freeze(table);
|
|
3219
|
+
}
|
|
3220
|
+
|
|
3113
3221
|
// src/transactions/claim/get-837.ts
|
|
3114
|
-
var VARIANT_BY_ICR =
|
|
3222
|
+
var VARIANT_BY_ICR = wireLookup({
|
|
3115
3223
|
"005010X222A2": "P",
|
|
3116
3224
|
"005010X223A3": "I",
|
|
3117
3225
|
"005010X224A2": "D"
|
|
3118
3226
|
});
|
|
3119
|
-
var VARIANT_BY_SV_SEGMENT =
|
|
3227
|
+
var VARIANT_BY_SV_SEGMENT = wireLookup({
|
|
3120
3228
|
SV1: "P",
|
|
3121
3229
|
SV2: "I",
|
|
3122
3230
|
SV3: "D"
|
|
@@ -3137,7 +3245,7 @@ var NM1_QUALIFIERS = Object.freeze({
|
|
|
3137
3245
|
PAYER: "PR",
|
|
3138
3246
|
PATIENT: "QC"
|
|
3139
3247
|
});
|
|
3140
|
-
var EXPECTED_PARENT_LEVEL =
|
|
3248
|
+
var EXPECTED_PARENT_LEVEL = wireLookup({
|
|
3141
3249
|
[HL_LEVEL_CODES.INFORMATION_SOURCE]: void 0,
|
|
3142
3250
|
[HL_LEVEL_CODES.SUBSCRIBER]: HL_LEVEL_CODES.INFORMATION_SOURCE,
|
|
3143
3251
|
[HL_LEVEL_CODES.DEPENDENT]: HL_LEVEL_CODES.SUBSCRIBER
|
|
@@ -3192,6 +3300,9 @@ function get837Claims(delimiters, tx, opts) {
|
|
|
3192
3300
|
const flushServiceLine = () => {
|
|
3193
3301
|
flushAdjudication();
|
|
3194
3302
|
if (currentServiceLine !== void 0 && currentClaim !== void 0) {
|
|
3303
|
+
if (!currentServiceLine.serviceSegmentDecoded) {
|
|
3304
|
+
warnings.push(serviceLineNotDecoded(currentServiceLine.position));
|
|
3305
|
+
}
|
|
3195
3306
|
currentClaim.serviceLines.push(freezeServiceLine2(currentServiceLine));
|
|
3196
3307
|
}
|
|
3197
3308
|
currentServiceLine = void 0;
|
|
@@ -3265,6 +3376,7 @@ function get837Claims(delimiters, tx, opts) {
|
|
|
3265
3376
|
const seg = body[i];
|
|
3266
3377
|
if (seg === void 0) continue;
|
|
3267
3378
|
const position = { segmentIndex: i + 1, transactionIndex: 0 };
|
|
3379
|
+
const sink = { warnings, position };
|
|
3268
3380
|
switch (seg.id) {
|
|
3269
3381
|
case "HL": {
|
|
3270
3382
|
flushClaim();
|
|
@@ -3412,16 +3524,21 @@ function get837Claims(delimiters, tx, opts) {
|
|
|
3412
3524
|
warnings.push(missingRequiredLoop(position, REQUIRED_LOOPS.PAYER_NAME_2010BB));
|
|
3413
3525
|
}
|
|
3414
3526
|
}
|
|
3415
|
-
currentClaim = openClaim2(
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3527
|
+
currentClaim = openClaim2(
|
|
3528
|
+
seg,
|
|
3529
|
+
delimiters,
|
|
3530
|
+
{
|
|
3531
|
+
variant,
|
|
3532
|
+
hierarchy: currentPatientHl ?? currentSubscriberHl,
|
|
3533
|
+
billingProvider,
|
|
3534
|
+
payToAddress,
|
|
3535
|
+
payToPlan,
|
|
3536
|
+
subscriber: currentSubscriberMember,
|
|
3537
|
+
payer: currentPayer,
|
|
3538
|
+
patient: currentPatientMember
|
|
3539
|
+
},
|
|
3540
|
+
sink
|
|
3541
|
+
);
|
|
3425
3542
|
activeEntity = void 0;
|
|
3426
3543
|
context = { kind: "loop2300" };
|
|
3427
3544
|
break;
|
|
@@ -3460,7 +3577,7 @@ function get837Claims(delimiters, tx, opts) {
|
|
|
3460
3577
|
break;
|
|
3461
3578
|
}
|
|
3462
3579
|
case "AMT": {
|
|
3463
|
-
const amount = decodeAmt2(seg, delimiters);
|
|
3580
|
+
const amount = decodeAmt2(seg, delimiters, sink);
|
|
3464
3581
|
if (amount === void 0) break;
|
|
3465
3582
|
if (currentAdjudication !== void 0) break;
|
|
3466
3583
|
if (currentServiceLine !== void 0) currentServiceLine.amounts.push(amount);
|
|
@@ -3469,22 +3586,26 @@ function get837Claims(delimiters, tx, opts) {
|
|
|
3469
3586
|
}
|
|
3470
3587
|
case "LX": {
|
|
3471
3588
|
flushServiceLine();
|
|
3472
|
-
if (currentClaim === void 0)
|
|
3473
|
-
|
|
3589
|
+
if (currentClaim === void 0) {
|
|
3590
|
+
warnings.push(serviceLineDropped(position));
|
|
3591
|
+
break;
|
|
3592
|
+
}
|
|
3593
|
+
currentServiceLine = openServiceLine2(seg, delimiters, currentClaim.variant, position);
|
|
3594
|
+
if (currentServiceLine === void 0) warnings.push(serviceLineDropped(position));
|
|
3474
3595
|
activeEntity = void 0;
|
|
3475
3596
|
context = { kind: "loop2400" };
|
|
3476
3597
|
break;
|
|
3477
3598
|
}
|
|
3478
3599
|
case "SV1": {
|
|
3479
|
-
if (currentServiceLine !== void 0) decodeSv1(currentServiceLine, seg, delimiters);
|
|
3600
|
+
if (currentServiceLine !== void 0) decodeSv1(currentServiceLine, seg, delimiters, sink);
|
|
3480
3601
|
break;
|
|
3481
3602
|
}
|
|
3482
3603
|
case "SV2": {
|
|
3483
|
-
if (currentServiceLine !== void 0) decodeSv2(currentServiceLine, seg, delimiters);
|
|
3604
|
+
if (currentServiceLine !== void 0) decodeSv2(currentServiceLine, seg, delimiters, sink);
|
|
3484
3605
|
break;
|
|
3485
3606
|
}
|
|
3486
3607
|
case "SV3": {
|
|
3487
|
-
if (currentServiceLine !== void 0) decodeSv3(currentServiceLine, seg, delimiters);
|
|
3608
|
+
if (currentServiceLine !== void 0) decodeSv3(currentServiceLine, seg, delimiters, sink);
|
|
3488
3609
|
break;
|
|
3489
3610
|
}
|
|
3490
3611
|
case "TOO": {
|
|
@@ -3510,7 +3631,7 @@ function get837Claims(delimiters, tx, opts) {
|
|
|
3510
3631
|
}
|
|
3511
3632
|
currentServiceLine.drug = {
|
|
3512
3633
|
...currentServiceLine.drug,
|
|
3513
|
-
quantity: elementDecimal(seg, 4, delimiters),
|
|
3634
|
+
quantity: elementDecimal(seg, 4, delimiters, sink),
|
|
3514
3635
|
unitOfMeasure: componentOptional(seg, 5, 1, delimiters)
|
|
3515
3636
|
};
|
|
3516
3637
|
break;
|
|
@@ -3518,7 +3639,7 @@ function get837Claims(delimiters, tx, opts) {
|
|
|
3518
3639
|
case "SVD": {
|
|
3519
3640
|
flushAdjudication();
|
|
3520
3641
|
if (currentServiceLine === void 0) break;
|
|
3521
|
-
currentAdjudication = openAdjudication(seg, delimiters);
|
|
3642
|
+
currentAdjudication = openAdjudication(seg, delimiters, sink);
|
|
3522
3643
|
break;
|
|
3523
3644
|
}
|
|
3524
3645
|
case "CAS": {
|
|
@@ -3696,19 +3817,20 @@ function decodeNte(seg, delimiters) {
|
|
|
3696
3817
|
description: note
|
|
3697
3818
|
});
|
|
3698
3819
|
}
|
|
3699
|
-
function decodeAmt2(seg, delimiters) {
|
|
3700
|
-
const amount = elementDecimal(seg, 2, delimiters);
|
|
3820
|
+
function decodeAmt2(seg, delimiters, sink) {
|
|
3821
|
+
const amount = elementDecimal(seg, 2, delimiters, sink);
|
|
3701
3822
|
if (amount === void 0) return void 0;
|
|
3702
3823
|
return Object.freeze({ qualifier: elementValue(seg, 1, delimiters), amount });
|
|
3703
3824
|
}
|
|
3704
3825
|
function decodeCas(seg, delimiters, warnings, position) {
|
|
3826
|
+
const sink = { warnings, position };
|
|
3705
3827
|
const groupCode = elementValue(seg, 1, delimiters);
|
|
3706
3828
|
const out = [];
|
|
3707
3829
|
for (let triple = 0; triple < 6; triple += 1) {
|
|
3708
3830
|
const base = 2 + triple * 3;
|
|
3709
3831
|
const reasonCode = elementOptional(seg, base, delimiters);
|
|
3710
|
-
const amount = elementDecimal(seg, base + 1, delimiters);
|
|
3711
|
-
const quantity = elementDecimal(seg, base + 2, delimiters);
|
|
3832
|
+
const amount = elementDecimal(seg, base + 1, delimiters, sink);
|
|
3833
|
+
const quantity = elementDecimal(seg, base + 2, delimiters, sink);
|
|
3712
3834
|
if (reasonCode === void 0 && amount === void 0) continue;
|
|
3713
3835
|
const code = reasonCode ?? "";
|
|
3714
3836
|
const entry = code === "" ? void 0 : lookupCarc(code);
|
|
@@ -3743,7 +3865,7 @@ var EMPTY_SUBSCRIBER_INFO = Object.freeze({
|
|
|
3743
3865
|
groupName: void 0,
|
|
3744
3866
|
claimFilingIndicator: void 0
|
|
3745
3867
|
});
|
|
3746
|
-
function openClaim2(seg, delimiters, ctx) {
|
|
3868
|
+
function openClaim2(seg, delimiters, ctx, sink) {
|
|
3747
3869
|
const {
|
|
3748
3870
|
variant,
|
|
3749
3871
|
hierarchy,
|
|
@@ -3764,7 +3886,7 @@ function openClaim2(seg, delimiters, ctx) {
|
|
|
3764
3886
|
payer,
|
|
3765
3887
|
patient,
|
|
3766
3888
|
claimId: elementValue(seg, 1, delimiters),
|
|
3767
|
-
totalCharge: elementDecimalOrZero(seg, 2, delimiters),
|
|
3889
|
+
totalCharge: elementDecimalOrZero(seg, 2, delimiters, sink),
|
|
3768
3890
|
placeOfServiceCode: componentOptional(seg, 5, 1, delimiters),
|
|
3769
3891
|
facilityCodeQualifier: componentOptional(seg, 5, 2, delimiters),
|
|
3770
3892
|
claimFrequencyCode: componentOptional(seg, 5, 3, delimiters),
|
|
@@ -3784,10 +3906,12 @@ function openClaim2(seg, delimiters, ctx) {
|
|
|
3784
3906
|
serviceLines: []
|
|
3785
3907
|
};
|
|
3786
3908
|
}
|
|
3787
|
-
function openServiceLine2(seg, delimiters, variant) {
|
|
3909
|
+
function openServiceLine2(seg, delimiters, variant, position) {
|
|
3788
3910
|
const lineNumber = elementValue(seg, 1, delimiters);
|
|
3789
3911
|
const base = {
|
|
3790
3912
|
lineNumber,
|
|
3913
|
+
position,
|
|
3914
|
+
serviceSegmentDecoded: false,
|
|
3791
3915
|
charge: X12Decimal.ZERO,
|
|
3792
3916
|
units: X12Decimal.ZERO,
|
|
3793
3917
|
unitOfMeasure: void 0,
|
|
@@ -3839,8 +3963,9 @@ function openServiceLine2(seg, delimiters, variant) {
|
|
|
3839
3963
|
}
|
|
3840
3964
|
return void 0;
|
|
3841
3965
|
}
|
|
3842
|
-
function decodeSv1(acc, seg, delimiters) {
|
|
3966
|
+
function decodeSv1(acc, seg, delimiters, sink) {
|
|
3843
3967
|
if (acc.variant !== "P") return;
|
|
3968
|
+
acc.serviceSegmentDecoded = true;
|
|
3844
3969
|
acc.procedureQualifier = componentOptional(seg, 1, 1, delimiters) ?? "";
|
|
3845
3970
|
acc.procedureCode = componentOptional(seg, 1, 2, delimiters) ?? "";
|
|
3846
3971
|
const mods = [];
|
|
@@ -3849,9 +3974,9 @@ function decodeSv1(acc, seg, delimiters) {
|
|
|
3849
3974
|
if (m !== void 0) mods.push(m);
|
|
3850
3975
|
}
|
|
3851
3976
|
acc.modifiers = mods;
|
|
3852
|
-
acc.charge = elementDecimalOrZero(seg, 2, delimiters);
|
|
3977
|
+
acc.charge = elementDecimalOrZero(seg, 2, delimiters, sink);
|
|
3853
3978
|
acc.unitOfMeasure = elementOptional(seg, 3, delimiters);
|
|
3854
|
-
acc.units = elementDecimalOrZero(seg, 4, delimiters);
|
|
3979
|
+
acc.units = elementDecimalOrZero(seg, 4, delimiters, sink);
|
|
3855
3980
|
acc.placeOfServiceCode = elementOptional(seg, 5, delimiters);
|
|
3856
3981
|
const pointers = [];
|
|
3857
3982
|
for (let p = 1; p <= 4; p += 1) {
|
|
@@ -3863,8 +3988,9 @@ function decodeSv1(acc, seg, delimiters) {
|
|
|
3863
3988
|
acc.epsdtIndicator = elementOptional(seg, 11, delimiters);
|
|
3864
3989
|
acc.familyPlanningIndicator = elementOptional(seg, 12, delimiters);
|
|
3865
3990
|
}
|
|
3866
|
-
function decodeSv2(acc, seg, delimiters) {
|
|
3991
|
+
function decodeSv2(acc, seg, delimiters, sink) {
|
|
3867
3992
|
if (acc.variant !== "I") return;
|
|
3993
|
+
acc.serviceSegmentDecoded = true;
|
|
3868
3994
|
acc.revenueCode = elementValue(seg, 1, delimiters);
|
|
3869
3995
|
acc.procedureQualifier = componentOptional(seg, 2, 1, delimiters);
|
|
3870
3996
|
acc.procedureCode = componentOptional(seg, 2, 2, delimiters);
|
|
@@ -3874,14 +4000,15 @@ function decodeSv2(acc, seg, delimiters) {
|
|
|
3874
4000
|
if (m !== void 0) mods.push(m);
|
|
3875
4001
|
}
|
|
3876
4002
|
acc.modifiers = mods;
|
|
3877
|
-
acc.charge = elementDecimalOrZero(seg, 3, delimiters);
|
|
4003
|
+
acc.charge = elementDecimalOrZero(seg, 3, delimiters, sink);
|
|
3878
4004
|
acc.unitOfMeasure = elementOptional(seg, 4, delimiters);
|
|
3879
|
-
acc.units = elementDecimalOrZero(seg, 5, delimiters);
|
|
3880
|
-
acc.serviceLineRate = elementDecimal(seg, 6, delimiters);
|
|
3881
|
-
acc.nonCoveredCharge = elementDecimal(seg, 7, delimiters);
|
|
4005
|
+
acc.units = elementDecimalOrZero(seg, 5, delimiters, sink);
|
|
4006
|
+
acc.serviceLineRate = elementDecimal(seg, 6, delimiters, sink);
|
|
4007
|
+
acc.nonCoveredCharge = elementDecimal(seg, 7, delimiters, sink);
|
|
3882
4008
|
}
|
|
3883
|
-
function decodeSv3(acc, seg, delimiters) {
|
|
4009
|
+
function decodeSv3(acc, seg, delimiters, sink) {
|
|
3884
4010
|
if (acc.variant !== "D") return;
|
|
4011
|
+
acc.serviceSegmentDecoded = true;
|
|
3885
4012
|
acc.procedureQualifier = componentOptional(seg, 1, 1, delimiters) ?? "";
|
|
3886
4013
|
acc.procedureCode = componentOptional(seg, 1, 2, delimiters) ?? "";
|
|
3887
4014
|
const mods = [];
|
|
@@ -3890,7 +4017,7 @@ function decodeSv3(acc, seg, delimiters) {
|
|
|
3890
4017
|
if (m !== void 0) mods.push(m);
|
|
3891
4018
|
}
|
|
3892
4019
|
acc.modifiers = mods;
|
|
3893
|
-
acc.charge = elementDecimalOrZero(seg, 2, delimiters);
|
|
4020
|
+
acc.charge = elementDecimalOrZero(seg, 2, delimiters, sink);
|
|
3894
4021
|
acc.placeOfServiceCode = elementOptional(seg, 3, delimiters);
|
|
3895
4022
|
const cavities = [];
|
|
3896
4023
|
for (let p = 1; p <= 5; p += 1) {
|
|
@@ -3899,15 +4026,15 @@ function decodeSv3(acc, seg, delimiters) {
|
|
|
3899
4026
|
}
|
|
3900
4027
|
acc.oralCavityArea = cavities;
|
|
3901
4028
|
acc.prosthesisCrownInlayCode = elementOptional(seg, 5, delimiters);
|
|
3902
|
-
acc.units = elementDecimalOrZero(seg, 6, delimiters);
|
|
4029
|
+
acc.units = elementDecimalOrZero(seg, 6, delimiters, sink);
|
|
3903
4030
|
}
|
|
3904
|
-
function openAdjudication(seg, delimiters) {
|
|
4031
|
+
function openAdjudication(seg, delimiters, sink) {
|
|
3905
4032
|
return {
|
|
3906
4033
|
otherPayerId: elementValue(seg, 1, delimiters),
|
|
3907
|
-
amountPaid: elementDecimalOrZero(seg, 2, delimiters),
|
|
4034
|
+
amountPaid: elementDecimalOrZero(seg, 2, delimiters, sink),
|
|
3908
4035
|
procedureQualifier: componentOptional(seg, 3, 1, delimiters),
|
|
3909
4036
|
procedureCode: componentOptional(seg, 3, 2, delimiters),
|
|
3910
|
-
paidUnits: elementDecimal(seg, 5, delimiters),
|
|
4037
|
+
paidUnits: elementDecimal(seg, 5, delimiters, sink),
|
|
3911
4038
|
adjustments: [],
|
|
3912
4039
|
dateAdjudicated: void 0
|
|
3913
4040
|
};
|
|
@@ -4199,6 +4326,12 @@ function refuseHierarchy(message) {
|
|
|
4199
4326
|
function refuseSpec2(message) {
|
|
4200
4327
|
throw new Claim837BuildError(CLAIM_837_BUILD_ERROR_CODES.X12_837_BUILD_INVALID_SPEC, message);
|
|
4201
4328
|
}
|
|
4329
|
+
function decStr(value) {
|
|
4330
|
+
return requireCallerDecimal(value, "build837", refuseSpec2).toString();
|
|
4331
|
+
}
|
|
4332
|
+
function escDec2(value, esc) {
|
|
4333
|
+
return esc(decStr(value));
|
|
4334
|
+
}
|
|
4202
4335
|
var VERSION_BY_VARIANT = {
|
|
4203
4336
|
P: "005010X222A2",
|
|
4204
4337
|
I: "005010X223A3",
|
|
@@ -4232,6 +4365,7 @@ function buildClaim837(variant, spec) {
|
|
|
4232
4365
|
};
|
|
4233
4366
|
const esc = makeCallerEscaper(delimiters, "build837", refuseSpec2);
|
|
4234
4367
|
const seg = (parts) => {
|
|
4368
|
+
requireCallerSegment(parts, "build837", refuseSpec2);
|
|
4235
4369
|
let end = parts.length;
|
|
4236
4370
|
while (end > 1 && parts[end - 1] === "") end -= 1;
|
|
4237
4371
|
return parts.slice(0, end).join(elementSeparator) + segmentTerminator;
|
|
@@ -4275,8 +4409,8 @@ function buildClaim837(variant, spec) {
|
|
|
4275
4409
|
X12_837_FUNCTIONAL_ID,
|
|
4276
4410
|
esc(applicationSenderCode),
|
|
4277
4411
|
esc(applicationReceiverCode),
|
|
4278
|
-
groupDate,
|
|
4279
|
-
groupTime,
|
|
4412
|
+
esc(groupDate),
|
|
4413
|
+
esc(groupTime),
|
|
4280
4414
|
esc(envelope.groupControlNumber),
|
|
4281
4415
|
X12_AGENCY_CODE2,
|
|
4282
4416
|
versionRelease
|
|
@@ -4491,7 +4625,7 @@ function emitClaim2(variant, claim, body, ctx) {
|
|
|
4491
4625
|
ctx.seg([
|
|
4492
4626
|
"CLM",
|
|
4493
4627
|
ctx.esc(claim.claimId),
|
|
4494
|
-
|
|
4628
|
+
escDec2(claim.totalCharge, ctx.esc),
|
|
4495
4629
|
"",
|
|
4496
4630
|
"",
|
|
4497
4631
|
ctx.comp([
|
|
@@ -4539,8 +4673,8 @@ function emitOtherSubscriber(other, body, ctx) {
|
|
|
4539
4673
|
if (other.otherPayer !== void 0) emitEntity(other.otherPayer, body, ctx);
|
|
4540
4674
|
}
|
|
4541
4675
|
function emitServiceLine2(variant, line, lineNumber, body, ctx) {
|
|
4542
|
-
body.push(ctx.seg(["LX", line.lineNumber ?? String(lineNumber)]));
|
|
4543
|
-
const units = line.units === void 0 ? "0" : line.units
|
|
4676
|
+
body.push(ctx.seg(["LX", ctx.esc(line.lineNumber ?? String(lineNumber))]));
|
|
4677
|
+
const units = line.units === void 0 ? "0" : decStr(line.units);
|
|
4544
4678
|
if (line.variant === "P") {
|
|
4545
4679
|
const proc = ctx.comp([line.procedureQualifier, line.procedureCode, ...line.modifiers ?? []]);
|
|
4546
4680
|
const pointers = ctx.comp(line.diagnosisPointers ?? []);
|
|
@@ -4548,7 +4682,7 @@ function emitServiceLine2(variant, line, lineNumber, body, ctx) {
|
|
|
4548
4682
|
ctx.seg([
|
|
4549
4683
|
"SV1",
|
|
4550
4684
|
proc,
|
|
4551
|
-
|
|
4685
|
+
escDec2(line.charge, ctx.esc),
|
|
4552
4686
|
ctx.esc(line.unitOfMeasure ?? ""),
|
|
4553
4687
|
ctx.esc(units),
|
|
4554
4688
|
ctx.esc(line.placeOfServiceCode ?? ""),
|
|
@@ -4572,11 +4706,11 @@ function emitServiceLine2(variant, line, lineNumber, body, ctx) {
|
|
|
4572
4706
|
"SV2",
|
|
4573
4707
|
ctx.esc(line.revenueCode),
|
|
4574
4708
|
proc,
|
|
4575
|
-
|
|
4709
|
+
escDec2(line.charge, ctx.esc),
|
|
4576
4710
|
ctx.esc(line.unitOfMeasure ?? ""),
|
|
4577
4711
|
ctx.esc(units),
|
|
4578
|
-
line.serviceLineRate === void 0 ? "" :
|
|
4579
|
-
line.nonCoveredCharge === void 0 ? "" :
|
|
4712
|
+
line.serviceLineRate === void 0 ? "" : escDec2(line.serviceLineRate, ctx.esc),
|
|
4713
|
+
line.nonCoveredCharge === void 0 ? "" : escDec2(line.nonCoveredCharge, ctx.esc)
|
|
4580
4714
|
])
|
|
4581
4715
|
);
|
|
4582
4716
|
} else {
|
|
@@ -4586,7 +4720,7 @@ function emitServiceLine2(variant, line, lineNumber, body, ctx) {
|
|
|
4586
4720
|
ctx.seg([
|
|
4587
4721
|
"SV3",
|
|
4588
4722
|
proc,
|
|
4589
|
-
|
|
4723
|
+
escDec2(line.charge, ctx.esc),
|
|
4590
4724
|
ctx.esc(line.placeOfServiceCode ?? ""),
|
|
4591
4725
|
cavity,
|
|
4592
4726
|
ctx.esc(line.prosthesisCrownInlayCode ?? ""),
|
|
@@ -4605,7 +4739,7 @@ function emitServiceLine2(variant, line, lineNumber, body, ctx) {
|
|
|
4605
4739
|
"",
|
|
4606
4740
|
"",
|
|
4607
4741
|
"",
|
|
4608
|
-
drug.quantity === void 0 ? "" :
|
|
4742
|
+
drug.quantity === void 0 ? "" : escDec2(drug.quantity, ctx.esc),
|
|
4609
4743
|
ctx.esc(drug.unitOfMeasure ?? "")
|
|
4610
4744
|
])
|
|
4611
4745
|
);
|
|
@@ -4635,10 +4769,10 @@ function emitAdjudication(adj, body, ctx) {
|
|
|
4635
4769
|
ctx.seg([
|
|
4636
4770
|
"SVD",
|
|
4637
4771
|
ctx.esc(adj.otherPayerId),
|
|
4638
|
-
|
|
4772
|
+
escDec2(adj.amountPaid, ctx.esc),
|
|
4639
4773
|
proc,
|
|
4640
4774
|
"",
|
|
4641
|
-
adj.paidUnits === void 0 ? "" :
|
|
4775
|
+
adj.paidUnits === void 0 ? "" : escDec2(adj.paidUnits, ctx.esc)
|
|
4642
4776
|
])
|
|
4643
4777
|
);
|
|
4644
4778
|
emitCasGroup2(adj.adjustments, "build837: adjudication.adjustments", body, ctx);
|
|
@@ -4663,8 +4797,8 @@ function emitCasGroup2(raw, at, body, ctx) {
|
|
|
4663
4797
|
if (adj === void 0 || adj.groupCode !== groupCode) break;
|
|
4664
4798
|
parts.push(
|
|
4665
4799
|
ctx.esc(adj.reasonCode),
|
|
4666
|
-
|
|
4667
|
-
adj.quantity === void 0 ? "" :
|
|
4800
|
+
escDec2(adj.amount, ctx.esc),
|
|
4801
|
+
adj.quantity === void 0 ? "" : escDec2(adj.quantity, ctx.esc)
|
|
4668
4802
|
);
|
|
4669
4803
|
triples += 1;
|
|
4670
4804
|
i += 1;
|
|
@@ -4735,7 +4869,7 @@ function emitNote(note, body, ctx) {
|
|
|
4735
4869
|
body.push(ctx.seg(["NTE", ctx.esc(note.noteReferenceCode), ctx.esc(note.description)]));
|
|
4736
4870
|
}
|
|
4737
4871
|
function emitAmount(amt, body, ctx) {
|
|
4738
|
-
body.push(ctx.seg(["AMT", ctx.esc(amt.qualifier),
|
|
4872
|
+
body.push(ctx.seg(["AMT", ctx.esc(amt.qualifier), escDec2(amt.amount, ctx.esc)]));
|
|
4739
4873
|
}
|
|
4740
4874
|
function emitHi(hi, body, ctx) {
|
|
4741
4875
|
const composite = ctx.comp([
|
|
@@ -4743,8 +4877,10 @@ function emitHi(hi, body, ctx) {
|
|
|
4743
4877
|
hi.code,
|
|
4744
4878
|
hi.dateQualifier ?? "",
|
|
4745
4879
|
hi.date ?? "",
|
|
4746
|
-
|
|
4747
|
-
|
|
4880
|
+
// `decStr`, not `escDec`: `ctx.comp` maps `esc` over every component, so
|
|
4881
|
+
// escaping here would double-release an active delimiter.
|
|
4882
|
+
hi.monetaryAmount === void 0 ? "" : decStr(hi.monetaryAmount),
|
|
4883
|
+
hi.quantity === void 0 ? "" : decStr(hi.quantity),
|
|
4748
4884
|
hi.versionId ?? "",
|
|
4749
4885
|
"",
|
|
4750
4886
|
hi.poaIndicator ?? ""
|
|
@@ -5056,6 +5192,7 @@ function get271Eligibility(delimiters, tx) {
|
|
|
5056
5192
|
const seg = body[i];
|
|
5057
5193
|
if (seg === void 0) continue;
|
|
5058
5194
|
const position = { segmentIndex: i + 1, transactionIndex: 0 };
|
|
5195
|
+
const sink = { warnings, position };
|
|
5059
5196
|
switch (seg.id) {
|
|
5060
5197
|
case "HL": {
|
|
5061
5198
|
const hl = decodeHl2(seg, delimiters);
|
|
@@ -5159,7 +5296,7 @@ function get271Eligibility(delimiters, tx) {
|
|
|
5159
5296
|
case "EB": {
|
|
5160
5297
|
flushBenefit();
|
|
5161
5298
|
if (currentSubscriber === void 0 && currentDependent === void 0) break;
|
|
5162
|
-
currentBenefit = openBenefit(seg, delimiters);
|
|
5299
|
+
currentBenefit = openBenefit(seg, delimiters, sink);
|
|
5163
5300
|
break;
|
|
5164
5301
|
}
|
|
5165
5302
|
case "MSG": {
|
|
@@ -5256,7 +5393,7 @@ function decodeDtp2(seg, delimiters) {
|
|
|
5256
5393
|
value
|
|
5257
5394
|
});
|
|
5258
5395
|
}
|
|
5259
|
-
function openBenefit(seg, delimiters) {
|
|
5396
|
+
function openBenefit(seg, delimiters, sink) {
|
|
5260
5397
|
const serviceTypeCodes = [];
|
|
5261
5398
|
for (const code of getAllSegmentValues(seg, "03", delimiters)) {
|
|
5262
5399
|
if (code === "") continue;
|
|
@@ -5271,10 +5408,10 @@ function openBenefit(seg, delimiters) {
|
|
|
5271
5408
|
insuranceTypeCode: elementOptional(seg, 4, delimiters),
|
|
5272
5409
|
planCoverageDescription: elementOptional(seg, 5, delimiters),
|
|
5273
5410
|
timePeriodQualifier: elementOptional(seg, 6, delimiters),
|
|
5274
|
-
monetaryAmount: elementDecimal(seg, 7, delimiters),
|
|
5275
|
-
percent: elementDecimal(seg, 8, delimiters),
|
|
5411
|
+
monetaryAmount: elementDecimal(seg, 7, delimiters, sink),
|
|
5412
|
+
percent: elementDecimal(seg, 8, delimiters, sink),
|
|
5276
5413
|
quantityQualifier: elementOptional(seg, 9, delimiters),
|
|
5277
|
-
quantity: elementDecimal(seg, 10, delimiters),
|
|
5414
|
+
quantity: elementDecimal(seg, 10, delimiters, sink),
|
|
5278
5415
|
authorizationRequired: elementOptional(seg, 11, delimiters),
|
|
5279
5416
|
inPlanNetwork: elementOptional(seg, 12, delimiters),
|
|
5280
5417
|
references: [],
|
|
@@ -5377,6 +5514,9 @@ function refuseSpec3(message) {
|
|
|
5377
5514
|
message
|
|
5378
5515
|
);
|
|
5379
5516
|
}
|
|
5517
|
+
function escDec3(value, esc) {
|
|
5518
|
+
return esc(requireCallerDecimal(value, "build271", refuseSpec3).toString());
|
|
5519
|
+
}
|
|
5380
5520
|
var X279A1_VERSION_RELEASE = "005010X279A1";
|
|
5381
5521
|
var X12_271_FUNCTIONAL_ID = "HB";
|
|
5382
5522
|
var X12_AGENCY_CODE3 = "X";
|
|
@@ -5396,6 +5536,7 @@ function build271(spec) {
|
|
|
5396
5536
|
};
|
|
5397
5537
|
const esc = makeCallerEscaper(delimiters, "build271", refuseSpec3);
|
|
5398
5538
|
const seg = (parts) => {
|
|
5539
|
+
requireCallerSegment(parts, "build271", refuseSpec3);
|
|
5399
5540
|
let end = parts.length;
|
|
5400
5541
|
while (end > 1 && parts[end - 1] === "") end -= 1;
|
|
5401
5542
|
return parts.slice(0, end).join(elementSeparator) + segmentTerminator;
|
|
@@ -5433,8 +5574,8 @@ function build271(spec) {
|
|
|
5433
5574
|
X12_271_FUNCTIONAL_ID,
|
|
5434
5575
|
esc(applicationSenderCode),
|
|
5435
5576
|
esc(applicationReceiverCode),
|
|
5436
|
-
groupDate,
|
|
5437
|
-
groupTime,
|
|
5577
|
+
esc(groupDate),
|
|
5578
|
+
esc(groupTime),
|
|
5438
5579
|
esc(envelope.groupControlNumber),
|
|
5439
5580
|
X12_AGENCY_CODE3,
|
|
5440
5581
|
X279A1_VERSION_RELEASE
|
|
@@ -5604,10 +5745,10 @@ function emitBenefit(benefit, body, ctx) {
|
|
|
5604
5745
|
ctx.esc(benefit.insuranceTypeCode ?? ""),
|
|
5605
5746
|
ctx.esc(benefit.planCoverageDescription ?? ""),
|
|
5606
5747
|
ctx.esc(benefit.timePeriodQualifier ?? ""),
|
|
5607
|
-
benefit.monetaryAmount === void 0 ? "" :
|
|
5608
|
-
benefit.percent === void 0 ? "" :
|
|
5748
|
+
benefit.monetaryAmount === void 0 ? "" : escDec3(benefit.monetaryAmount, ctx.esc),
|
|
5749
|
+
benefit.percent === void 0 ? "" : escDec3(benefit.percent, ctx.esc),
|
|
5609
5750
|
ctx.esc(benefit.quantityQualifier ?? ""),
|
|
5610
|
-
benefit.quantity === void 0 ? "" :
|
|
5751
|
+
benefit.quantity === void 0 ? "" : escDec3(benefit.quantity, ctx.esc),
|
|
5611
5752
|
ctx.esc(benefit.authorizationRequired ?? ""),
|
|
5612
5753
|
ctx.esc(benefit.inPlanNetwork ?? "")
|
|
5613
5754
|
])
|
|
@@ -5814,6 +5955,7 @@ function walk277(delimiters, tx) {
|
|
|
5814
5955
|
const seg = body[i];
|
|
5815
5956
|
if (seg === void 0) continue;
|
|
5816
5957
|
const position = { segmentIndex: i + 1, transactionIndex: 0 };
|
|
5958
|
+
const sink = { warnings, position };
|
|
5817
5959
|
switch (seg.id) {
|
|
5818
5960
|
case "HL": {
|
|
5819
5961
|
flushClaim();
|
|
@@ -5891,7 +6033,7 @@ function walk277(delimiters, tx) {
|
|
|
5891
6033
|
case "SVC": {
|
|
5892
6034
|
flushServiceLine();
|
|
5893
6035
|
if (currentClaim === void 0) currentClaim = openClaim3();
|
|
5894
|
-
currentServiceLine = openServiceLine3(seg, delimiters);
|
|
6036
|
+
currentServiceLine = openServiceLine3(seg, delimiters, sink);
|
|
5895
6037
|
break;
|
|
5896
6038
|
}
|
|
5897
6039
|
case "REF": {
|
|
@@ -5965,6 +6107,7 @@ function decodeDtp3(seg, delimiters) {
|
|
|
5965
6107
|
});
|
|
5966
6108
|
}
|
|
5967
6109
|
function decodeStc(seg, delimiters, warnings, position) {
|
|
6110
|
+
const sink = { warnings, position };
|
|
5968
6111
|
const statuses = [];
|
|
5969
6112
|
for (const elementIndex of [1, 10, 11]) {
|
|
5970
6113
|
const code = decodeStatusComposite(seg, elementIndex, delimiters, warnings, position);
|
|
@@ -5973,8 +6116,8 @@ function decodeStc(seg, delimiters, warnings, position) {
|
|
|
5973
6116
|
return Object.freeze({
|
|
5974
6117
|
statusEffectiveDate: elementOptional(seg, 2, delimiters),
|
|
5975
6118
|
actionCode: elementOptional(seg, 3, delimiters),
|
|
5976
|
-
totalChargeAmount: elementDecimal(seg, 4, delimiters),
|
|
5977
|
-
paymentAmount: elementDecimal(seg, 5, delimiters),
|
|
6119
|
+
totalChargeAmount: elementDecimal(seg, 4, delimiters, sink),
|
|
6120
|
+
paymentAmount: elementDecimal(seg, 5, delimiters, sink),
|
|
5978
6121
|
adjudicationDate: elementOptional(seg, 6, delimiters),
|
|
5979
6122
|
message: elementOptional(seg, 12, delimiters),
|
|
5980
6123
|
statuses: Object.freeze(statuses)
|
|
@@ -6001,7 +6144,7 @@ function decodeStatusComposite(seg, n, delimiters, warnings, position) {
|
|
|
6001
6144
|
entityCode
|
|
6002
6145
|
});
|
|
6003
6146
|
}
|
|
6004
|
-
function openServiceLine3(seg, delimiters) {
|
|
6147
|
+
function openServiceLine3(seg, delimiters, sink) {
|
|
6005
6148
|
const modifiers = [];
|
|
6006
6149
|
for (let comp = 3; comp <= 6; comp += 1) {
|
|
6007
6150
|
const m = componentOptional(seg, 1, comp, delimiters);
|
|
@@ -6011,9 +6154,13 @@ function openServiceLine3(seg, delimiters) {
|
|
|
6011
6154
|
serviceIdQualifier: componentOptional(seg, 1, 1, delimiters),
|
|
6012
6155
|
procedureCode: componentOptional(seg, 1, 2, delimiters),
|
|
6013
6156
|
modifiers,
|
|
6014
|
-
lineChargeAmount: elementDecimal(seg, 2, delimiters),
|
|
6015
|
-
linePaymentAmount: elementDecimal(seg, 3, delimiters),
|
|
6157
|
+
lineChargeAmount: elementDecimal(seg, 2, delimiters, sink),
|
|
6158
|
+
linePaymentAmount: elementDecimal(seg, 3, delimiters, sink),
|
|
6016
6159
|
revenueCode: elementOptional(seg, 4, delimiters),
|
|
6160
|
+
// SVC-07. SVC-05 (Quantity) and SVC-06 (a second composite) are NOT USED
|
|
6161
|
+
// in both X212 and X214, so they are deliberately left unread rather than
|
|
6162
|
+
// decoded "for symmetry" with the 835, whose SVC-05 IS the paid count.
|
|
6163
|
+
unitsOfService: elementDecimal(seg, 7, delimiters, sink),
|
|
6017
6164
|
statuses: [],
|
|
6018
6165
|
references: [],
|
|
6019
6166
|
dates: []
|
|
@@ -6027,6 +6174,7 @@ function freezeServiceLine3(acc) {
|
|
|
6027
6174
|
lineChargeAmount: acc.lineChargeAmount,
|
|
6028
6175
|
linePaymentAmount: acc.linePaymentAmount,
|
|
6029
6176
|
revenueCode: acc.revenueCode,
|
|
6177
|
+
unitsOfService: acc.unitsOfService,
|
|
6030
6178
|
statuses: Object.freeze(acc.statuses.slice()),
|
|
6031
6179
|
references: Object.freeze(acc.references.slice()),
|
|
6032
6180
|
dates: Object.freeze(acc.dates.slice())
|
|
@@ -6075,6 +6223,9 @@ function refuseSpec4(message) {
|
|
|
6075
6223
|
message
|
|
6076
6224
|
);
|
|
6077
6225
|
}
|
|
6226
|
+
function escDec4(value, esc) {
|
|
6227
|
+
return esc(requireCallerDecimal(value, "build277", refuseSpec4).toString());
|
|
6228
|
+
}
|
|
6078
6229
|
var X12_277_FUNCTIONAL_ID = "HN";
|
|
6079
6230
|
var X12_AGENCY_CODE4 = "X";
|
|
6080
6231
|
var HL_LEVEL3 = {
|
|
@@ -6092,7 +6243,7 @@ function build277CA(spec) {
|
|
|
6092
6243
|
}
|
|
6093
6244
|
function buildClaimStatus(version, spec) {
|
|
6094
6245
|
const { envelope } = spec;
|
|
6095
|
-
enforceStructuralSpec4(spec);
|
|
6246
|
+
enforceStructuralSpec4(version, spec);
|
|
6096
6247
|
const elementSeparator = envelope.elementSeparator ?? "*";
|
|
6097
6248
|
const repetitionSeparator = envelope.repetitionSeparator ?? "^";
|
|
6098
6249
|
const componentSeparator = envelope.componentSeparator ?? ":";
|
|
@@ -6105,6 +6256,7 @@ function buildClaimStatus(version, spec) {
|
|
|
6105
6256
|
};
|
|
6106
6257
|
const esc = makeCallerEscaper(delimiters, "build277", refuseSpec4);
|
|
6107
6258
|
const seg = (parts) => {
|
|
6259
|
+
requireCallerSegment(parts, "build277", refuseSpec4);
|
|
6108
6260
|
let end = parts.length;
|
|
6109
6261
|
while (end > 1 && parts[end - 1] === "") end -= 1;
|
|
6110
6262
|
return parts.slice(0, end).join(elementSeparator) + segmentTerminator;
|
|
@@ -6148,8 +6300,8 @@ function buildClaimStatus(version, spec) {
|
|
|
6148
6300
|
X12_277_FUNCTIONAL_ID,
|
|
6149
6301
|
esc(applicationSenderCode),
|
|
6150
6302
|
esc(applicationReceiverCode),
|
|
6151
|
-
groupDate,
|
|
6152
|
-
groupTime,
|
|
6303
|
+
esc(groupDate),
|
|
6304
|
+
esc(groupTime),
|
|
6153
6305
|
esc(envelope.groupControlNumber),
|
|
6154
6306
|
X12_AGENCY_CODE4,
|
|
6155
6307
|
version
|
|
@@ -6168,7 +6320,7 @@ function buildClaimStatus(version, spec) {
|
|
|
6168
6320
|
const raw = isa + gs + st + body.join("") + se + ge + iea;
|
|
6169
6321
|
return parseX12(raw);
|
|
6170
6322
|
}
|
|
6171
|
-
function enforceStructuralSpec4(spec) {
|
|
6323
|
+
function enforceStructuralSpec4(version, spec) {
|
|
6172
6324
|
const sources = requireCallerArray(
|
|
6173
6325
|
spec.informationSources,
|
|
6174
6326
|
"build277: spec.informationSources",
|
|
@@ -6226,13 +6378,13 @@ function enforceStructuralSpec4(spec) {
|
|
|
6226
6378
|
for (let u = 0; u < subscribers.length; u += 1) {
|
|
6227
6379
|
const subscriber = subscribers[u];
|
|
6228
6380
|
if (subscriber === void 0) continue;
|
|
6229
|
-
enforceSubscriber(subscriber, `${locator}.subscriber[${String(u)}]`);
|
|
6381
|
+
enforceSubscriber(version, subscriber, `${locator}.subscriber[${String(u)}]`);
|
|
6230
6382
|
}
|
|
6231
6383
|
}
|
|
6232
6384
|
}
|
|
6233
6385
|
}
|
|
6234
6386
|
}
|
|
6235
|
-
function enforceSubscriber(subscriber, locator) {
|
|
6387
|
+
function enforceSubscriber(version, subscriber, locator) {
|
|
6236
6388
|
const claims = requireCallerArray(
|
|
6237
6389
|
subscriber.claims,
|
|
6238
6390
|
`build277: subscriber at ${locator}: claims`,
|
|
@@ -6251,7 +6403,8 @@ function enforceSubscriber(subscriber, locator) {
|
|
|
6251
6403
|
}
|
|
6252
6404
|
for (let c = 0; c < claims.length; c += 1) {
|
|
6253
6405
|
const claim = claims[c];
|
|
6254
|
-
if (claim !== void 0)
|
|
6406
|
+
if (claim !== void 0)
|
|
6407
|
+
enforceClaim2(version, claim, `${locator}.claim[${String(c)}]`, c === 0);
|
|
6255
6408
|
}
|
|
6256
6409
|
for (let d = 0; d < dependents.length; d += 1) {
|
|
6257
6410
|
const dependent = dependents[d];
|
|
@@ -6270,11 +6423,12 @@ function enforceSubscriber(subscriber, locator) {
|
|
|
6270
6423
|
}
|
|
6271
6424
|
for (let c = 0; c < depClaims.length; c += 1) {
|
|
6272
6425
|
const claim = depClaims[c];
|
|
6273
|
-
if (claim !== void 0)
|
|
6426
|
+
if (claim !== void 0)
|
|
6427
|
+
enforceClaim2(version, claim, `${depLocator}.claim[${String(c)}]`, c === 0);
|
|
6274
6428
|
}
|
|
6275
6429
|
}
|
|
6276
6430
|
}
|
|
6277
|
-
function enforceClaim2(claim, locator, isFirst) {
|
|
6431
|
+
function enforceClaim2(version, claim, locator, isFirst) {
|
|
6278
6432
|
const statuses = requireCallerArray(
|
|
6279
6433
|
claim.statuses,
|
|
6280
6434
|
`build277: claim at ${locator}: statuses`,
|
|
@@ -6303,6 +6457,12 @@ function enforceClaim2(claim, locator, isFirst) {
|
|
|
6303
6457
|
for (let l = 0; l < serviceLines.length; l += 1) {
|
|
6304
6458
|
const line = serviceLines[l];
|
|
6305
6459
|
if (line === void 0) continue;
|
|
6460
|
+
if (version === "005010X212" && line.unitsOfService === void 0) {
|
|
6461
|
+
throw new ClaimStatus277BuildError(
|
|
6462
|
+
CLAIM_STATUS_277_BUILD_ERROR_CODES.X12_277_BUILD_INVALID_SPEC,
|
|
6463
|
+
`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.`
|
|
6464
|
+
);
|
|
6465
|
+
}
|
|
6306
6466
|
const lineStatuses = requireCallerArray(
|
|
6307
6467
|
line.statuses,
|
|
6308
6468
|
`build277: claim at ${locator}.line[${String(l)}]: statuses`,
|
|
@@ -6396,9 +6556,12 @@ function emitServiceLine3(line, body, ctx) {
|
|
|
6396
6556
|
ctx.seg([
|
|
6397
6557
|
"SVC",
|
|
6398
6558
|
svc01,
|
|
6399
|
-
line.lineChargeAmount === void 0 ? "" :
|
|
6400
|
-
line.linePaymentAmount === void 0 ? "" :
|
|
6401
|
-
ctx.esc(line.revenueCode ?? "")
|
|
6559
|
+
line.lineChargeAmount === void 0 ? "" : escDec4(line.lineChargeAmount, ctx.esc),
|
|
6560
|
+
line.linePaymentAmount === void 0 ? "" : escDec4(line.linePaymentAmount, ctx.esc),
|
|
6561
|
+
ctx.esc(line.revenueCode ?? ""),
|
|
6562
|
+
"",
|
|
6563
|
+
"",
|
|
6564
|
+
line.unitsOfService === void 0 ? "" : escDec4(line.unitsOfService, ctx.esc)
|
|
6402
6565
|
])
|
|
6403
6566
|
);
|
|
6404
6567
|
for (const status of line.statuses ?? []) emitStatus(status, body, ctx);
|
|
@@ -6417,8 +6580,8 @@ function emitStatus(status, body, ctx) {
|
|
|
6417
6580
|
composite(0),
|
|
6418
6581
|
ctx.esc(status.statusEffectiveDate ?? ""),
|
|
6419
6582
|
ctx.esc(status.actionCode ?? ""),
|
|
6420
|
-
status.totalChargeAmount === void 0 ? "" :
|
|
6421
|
-
status.paymentAmount === void 0 ? "" :
|
|
6583
|
+
status.totalChargeAmount === void 0 ? "" : escDec4(status.totalChargeAmount, ctx.esc),
|
|
6584
|
+
status.paymentAmount === void 0 ? "" : escDec4(status.paymentAmount, ctx.esc),
|
|
6422
6585
|
ctx.esc(status.adjudicationDate ?? ""),
|
|
6423
6586
|
"",
|
|
6424
6587
|
"",
|
|
@@ -6588,9 +6751,11 @@ function get820Payments(delimiters, tx) {
|
|
|
6588
6751
|
for (let i = 0; i < body.length; i += 1) {
|
|
6589
6752
|
const seg = body[i];
|
|
6590
6753
|
if (seg === void 0) continue;
|
|
6754
|
+
const position = { segmentIndex: i + 1, transactionIndex: 0 };
|
|
6755
|
+
const sink = { warnings, position };
|
|
6591
6756
|
switch (seg.id) {
|
|
6592
6757
|
case "BPR": {
|
|
6593
|
-
payment = decodeBpr2(seg, delimiters);
|
|
6758
|
+
payment = decodeBpr2(seg, delimiters, sink);
|
|
6594
6759
|
break;
|
|
6595
6760
|
}
|
|
6596
6761
|
case "TRN": {
|
|
@@ -6657,13 +6822,13 @@ function get820Payments(delimiters, tx) {
|
|
|
6657
6822
|
}
|
|
6658
6823
|
case "RMR": {
|
|
6659
6824
|
if (current === void 0) break;
|
|
6660
|
-
const item = decodeRmr(seg, delimiters);
|
|
6825
|
+
const item = decodeRmr(seg, delimiters, sink);
|
|
6661
6826
|
if (item !== void 0) current.openItems.push(item);
|
|
6662
6827
|
break;
|
|
6663
6828
|
}
|
|
6664
6829
|
case "ADX": {
|
|
6665
6830
|
if (current === void 0) break;
|
|
6666
|
-
const adjustment = decodeAdx(seg, delimiters);
|
|
6831
|
+
const adjustment = decodeAdx(seg, delimiters, sink);
|
|
6667
6832
|
if (adjustment !== void 0) current.adjustments.push(adjustment);
|
|
6668
6833
|
break;
|
|
6669
6834
|
}
|
|
@@ -6715,10 +6880,10 @@ function freezeRemittance(acc) {
|
|
|
6715
6880
|
adjustments: Object.freeze(acc.adjustments.slice())
|
|
6716
6881
|
});
|
|
6717
6882
|
}
|
|
6718
|
-
function decodeBpr2(seg, delimiters) {
|
|
6883
|
+
function decodeBpr2(seg, delimiters, sink) {
|
|
6719
6884
|
return Object.freeze({
|
|
6720
6885
|
transactionHandlingCode: elementValue(seg, 1, delimiters),
|
|
6721
|
-
totalPremiumAmount: elementDecimalOrZero(seg, 2, delimiters),
|
|
6886
|
+
totalPremiumAmount: elementDecimalOrZero(seg, 2, delimiters, sink),
|
|
6722
6887
|
creditDebitFlag: elementValue(seg, 3, delimiters),
|
|
6723
6888
|
method: elementValue(seg, 4, delimiters),
|
|
6724
6889
|
paymentFormatCode: elementOptional(seg, 5, delimiters),
|
|
@@ -6786,7 +6951,7 @@ function decodeNm13(seg, delimiters) {
|
|
|
6786
6951
|
idCode: elementOptional(seg, 9, delimiters)
|
|
6787
6952
|
});
|
|
6788
6953
|
}
|
|
6789
|
-
function decodeRmr(seg, delimiters) {
|
|
6954
|
+
function decodeRmr(seg, delimiters, sink) {
|
|
6790
6955
|
const qualifier = elementValue(seg, 1, delimiters);
|
|
6791
6956
|
const referenceId = elementValue(seg, 2, delimiters);
|
|
6792
6957
|
if (qualifier === "" && referenceId === "") return void 0;
|
|
@@ -6794,12 +6959,12 @@ function decodeRmr(seg, delimiters) {
|
|
|
6794
6959
|
qualifier,
|
|
6795
6960
|
referenceId,
|
|
6796
6961
|
paymentActionCode: elementOptional(seg, 3, delimiters),
|
|
6797
|
-
amountPaid: elementDecimalOrZero(seg, 4, delimiters),
|
|
6798
|
-
amountDue: elementDecimal(seg, 5, delimiters)
|
|
6962
|
+
amountPaid: elementDecimalOrZero(seg, 4, delimiters, sink),
|
|
6963
|
+
amountDue: elementDecimal(seg, 5, delimiters, sink)
|
|
6799
6964
|
});
|
|
6800
6965
|
}
|
|
6801
|
-
function decodeAdx(seg, delimiters) {
|
|
6802
|
-
const amount = elementDecimal(seg, 1, delimiters);
|
|
6966
|
+
function decodeAdx(seg, delimiters, sink) {
|
|
6967
|
+
const amount = elementDecimal(seg, 1, delimiters, sink);
|
|
6803
6968
|
if (amount === void 0) return void 0;
|
|
6804
6969
|
return Object.freeze({
|
|
6805
6970
|
amount,
|
|
@@ -6860,6 +7025,9 @@ var Premium820BuildError = class extends Error {
|
|
|
6860
7025
|
function refuseSpec5(message) {
|
|
6861
7026
|
throw new Premium820BuildError(PREMIUM_820_BUILD_ERROR_CODES.X12_820_BUILD_INVALID_SPEC, message);
|
|
6862
7027
|
}
|
|
7028
|
+
function escDec5(value, esc) {
|
|
7029
|
+
return esc(requireCallerDecimal(value, "build820", refuseSpec5).toString());
|
|
7030
|
+
}
|
|
6863
7031
|
var X218_VERSION_RELEASE = "005010X218";
|
|
6864
7032
|
var X12_820_FUNCTIONAL_ID = "RA";
|
|
6865
7033
|
var X12_AGENCY_CODE5 = "X";
|
|
@@ -6878,6 +7046,7 @@ function build820(spec) {
|
|
|
6878
7046
|
};
|
|
6879
7047
|
const esc = makeCallerEscaper(delimiters, "build820", refuseSpec5);
|
|
6880
7048
|
const seg = (parts) => {
|
|
7049
|
+
requireCallerSegment(parts, "build820", refuseSpec5);
|
|
6881
7050
|
let end = parts.length;
|
|
6882
7051
|
while (end > 1 && parts[end - 1] === "") end -= 1;
|
|
6883
7052
|
return parts.slice(0, end).join(elementSeparator) + segmentTerminator;
|
|
@@ -6933,9 +7102,9 @@ function build820(spec) {
|
|
|
6933
7102
|
// GS-02
|
|
6934
7103
|
esc(applicationReceiverCode),
|
|
6935
7104
|
// GS-03
|
|
6936
|
-
groupDate,
|
|
7105
|
+
esc(groupDate),
|
|
6937
7106
|
// GS-04 - CCYYMMDD
|
|
6938
|
-
groupTime,
|
|
7107
|
+
esc(groupTime),
|
|
6939
7108
|
// GS-05 - HHMM
|
|
6940
7109
|
esc(envelope.groupControlNumber),
|
|
6941
7110
|
// GS-06
|
|
@@ -6951,7 +7120,7 @@ function build820(spec) {
|
|
|
6951
7120
|
seg([
|
|
6952
7121
|
"BPR",
|
|
6953
7122
|
esc(spec.payment.transactionHandlingCode),
|
|
6954
|
-
|
|
7123
|
+
escDec5(spec.payment.totalPremiumAmount, esc),
|
|
6955
7124
|
esc(spec.payment.creditDebitFlag),
|
|
6956
7125
|
esc(spec.payment.method),
|
|
6957
7126
|
esc(spec.payment.paymentFormatCode ?? ""),
|
|
@@ -7108,7 +7277,7 @@ function emitRemittance(remittance, body, seg, esc) {
|
|
|
7108
7277
|
body.push(
|
|
7109
7278
|
seg([
|
|
7110
7279
|
"ADX",
|
|
7111
|
-
|
|
7280
|
+
escDec5(adjustment.amount, esc),
|
|
7112
7281
|
esc(adjustment.reasonCode),
|
|
7113
7282
|
esc(adjustment.referenceQualifier ?? ""),
|
|
7114
7283
|
esc(adjustment.referenceId ?? "")
|
|
@@ -7138,8 +7307,8 @@ function emitOpenItem(item, seg, esc) {
|
|
|
7138
7307
|
esc(item.qualifier),
|
|
7139
7308
|
esc(item.referenceId),
|
|
7140
7309
|
esc(item.paymentActionCode ?? ""),
|
|
7141
|
-
|
|
7142
|
-
item.amountDue === void 0 ? "" :
|
|
7310
|
+
escDec5(item.amountPaid, esc),
|
|
7311
|
+
item.amountDue === void 0 ? "" : escDec5(item.amountDue, esc)
|
|
7143
7312
|
]);
|
|
7144
7313
|
}
|
|
7145
7314
|
function emitRef5(ref, seg, esc) {
|
|
@@ -7370,7 +7539,8 @@ async function* get834Enrollments(delimiters, tx) {
|
|
|
7370
7539
|
}
|
|
7371
7540
|
case "AMT": {
|
|
7372
7541
|
if (currentCoverage === void 0) break;
|
|
7373
|
-
const
|
|
7542
|
+
const sink = { warnings: current.warnings, position };
|
|
7543
|
+
const amount = decodeAmt3(seg, delimiters, sink);
|
|
7374
7544
|
if (amount !== void 0) currentCoverage.amounts.push(amount);
|
|
7375
7545
|
break;
|
|
7376
7546
|
}
|
|
@@ -7496,8 +7666,8 @@ function decodeDtp4(seg, delimiters) {
|
|
|
7496
7666
|
value
|
|
7497
7667
|
});
|
|
7498
7668
|
}
|
|
7499
|
-
function decodeAmt3(seg, delimiters) {
|
|
7500
|
-
const amount = elementDecimal(seg, 2, delimiters);
|
|
7669
|
+
function decodeAmt3(seg, delimiters, sink) {
|
|
7670
|
+
const amount = elementDecimal(seg, 2, delimiters, sink);
|
|
7501
7671
|
if (amount === void 0) return void 0;
|
|
7502
7672
|
return Object.freeze({
|
|
7503
7673
|
qualifier: elementValue(seg, 1, delimiters),
|
|
@@ -7559,6 +7729,9 @@ function refuseSpec6(message) {
|
|
|
7559
7729
|
message
|
|
7560
7730
|
);
|
|
7561
7731
|
}
|
|
7732
|
+
function escDec6(value, esc) {
|
|
7733
|
+
return esc(requireCallerDecimal(value, "build834", refuseSpec6).toString());
|
|
7734
|
+
}
|
|
7562
7735
|
var X220A1_VERSION_RELEASE = "005010X220A1";
|
|
7563
7736
|
var X12_834_FUNCTIONAL_ID = "BE";
|
|
7564
7737
|
var X12_AGENCY_CODE6 = "X";
|
|
@@ -7579,6 +7752,7 @@ function build834(spec) {
|
|
|
7579
7752
|
};
|
|
7580
7753
|
const esc = makeCallerEscaper(delimiters, "build834", refuseSpec6);
|
|
7581
7754
|
const seg = (parts) => {
|
|
7755
|
+
requireCallerSegment(parts, "build834", refuseSpec6);
|
|
7582
7756
|
let end = parts.length;
|
|
7583
7757
|
while (end > 1 && parts[end - 1] === "") end -= 1;
|
|
7584
7758
|
return parts.slice(0, end).join(elementSeparator) + segmentTerminator;
|
|
@@ -7634,9 +7808,9 @@ function build834(spec) {
|
|
|
7634
7808
|
// GS-02
|
|
7635
7809
|
esc(applicationReceiverCode),
|
|
7636
7810
|
// GS-03
|
|
7637
|
-
groupDate,
|
|
7811
|
+
esc(groupDate),
|
|
7638
7812
|
// GS-04 - CCYYMMDD
|
|
7639
|
-
groupTime,
|
|
7813
|
+
esc(groupTime),
|
|
7640
7814
|
// GS-05 - HHMM
|
|
7641
7815
|
esc(envelope.groupControlNumber),
|
|
7642
7816
|
// GS-06
|
|
@@ -7817,7 +7991,7 @@ function emitCoverage(coverage, body, seg, esc) {
|
|
|
7817
7991
|
);
|
|
7818
7992
|
for (const date of coverage.dates ?? []) body.push(emitDate4(date, seg, esc));
|
|
7819
7993
|
for (const amount of coverage.amounts ?? []) {
|
|
7820
|
-
body.push(seg(["AMT", esc(amount.qualifier),
|
|
7994
|
+
body.push(seg(["AMT", esc(amount.qualifier), escDec6(amount.amount, esc)]));
|
|
7821
7995
|
}
|
|
7822
7996
|
}
|
|
7823
7997
|
function emitRef6(ref, seg, esc) {
|
|
@@ -8246,6 +8420,7 @@ function buildServicesReview(version, direction, spec) {
|
|
|
8246
8420
|
};
|
|
8247
8421
|
const esc = makeCallerEscaper(delimiters, "build278", refuseSpec7);
|
|
8248
8422
|
const seg = (parts) => {
|
|
8423
|
+
requireCallerSegment(parts, "build278", refuseSpec7);
|
|
8249
8424
|
let end = parts.length;
|
|
8250
8425
|
while (end > 1 && parts[end - 1] === "") end -= 1;
|
|
8251
8426
|
return parts.slice(0, end).join(elementSeparator) + segmentTerminator;
|
|
@@ -8289,8 +8464,8 @@ function buildServicesReview(version, direction, spec) {
|
|
|
8289
8464
|
X12_278_FUNCTIONAL_ID,
|
|
8290
8465
|
esc(applicationSenderCode),
|
|
8291
8466
|
esc(applicationReceiverCode),
|
|
8292
|
-
groupDate,
|
|
8293
|
-
groupTime,
|
|
8467
|
+
esc(groupDate),
|
|
8468
|
+
esc(groupTime),
|
|
8294
8469
|
esc(envelope.groupControlNumber),
|
|
8295
8470
|
X12_AGENCY_CODE7,
|
|
8296
8471
|
version
|
|
@@ -8419,7 +8594,7 @@ function emitReview(review, parentHlId, direction, body, ctx, counter) {
|
|
|
8419
8594
|
const nested = review.reviews ?? [];
|
|
8420
8595
|
const hasChild = nested.length > 0 ? "1" : "0";
|
|
8421
8596
|
const levelCode = review.levelCode ?? DEFAULT_REVIEW_LEVEL;
|
|
8422
|
-
body.push(ctx.seg(["HL", hlId, parentHlId, levelCode, hasChild]));
|
|
8597
|
+
body.push(ctx.seg(["HL", hlId, parentHlId, ctx.esc(levelCode), hasChild]));
|
|
8423
8598
|
for (const trace of review.traces ?? []) {
|
|
8424
8599
|
body.push(
|
|
8425
8600
|
ctx.seg([
|
|
@@ -9066,13 +9241,13 @@ function build999(spec) {
|
|
|
9066
9241
|
// GS-02
|
|
9067
9242
|
esc(envelope.receiverId),
|
|
9068
9243
|
// GS-03
|
|
9069
|
-
groupDate,
|
|
9244
|
+
esc(groupDate),
|
|
9070
9245
|
// GS-04 - CCYYMMDD
|
|
9071
|
-
groupTime,
|
|
9246
|
+
esc(groupTime),
|
|
9072
9247
|
// GS-05 - HHMM
|
|
9073
|
-
envelope.groupControlNumber,
|
|
9248
|
+
esc(envelope.groupControlNumber),
|
|
9074
9249
|
// GS-06
|
|
9075
|
-
groupResponsibleAgency,
|
|
9250
|
+
esc(groupResponsibleAgency),
|
|
9076
9251
|
// GS-07
|
|
9077
9252
|
X231A1_VERSION_RELEASE
|
|
9078
9253
|
// GS-08 - the 999 TR3
|
|
@@ -9082,7 +9257,7 @@ function build999(spec) {
|
|
|
9082
9257
|
);
|
|
9083
9258
|
const stControlNumber = envelope.transactionSetControlNumber;
|
|
9084
9259
|
const st = joinSeg(
|
|
9085
|
-
["ST", "999", stControlNumber, X231A1_VERSION_RELEASE],
|
|
9260
|
+
["ST", "999", esc(stControlNumber), X231A1_VERSION_RELEASE],
|
|
9086
9261
|
elementSeparator,
|
|
9087
9262
|
segmentTerminator
|
|
9088
9263
|
);
|
|
@@ -9115,8 +9290,16 @@ function build999(spec) {
|
|
|
9115
9290
|
const ak9 = buildAk9(functionalGroup, esc, elementSeparator, segmentTerminator);
|
|
9116
9291
|
const bodySegments = [st, ak1, ...responseSegments, ak9];
|
|
9117
9292
|
const seCount = bodySegments.length + 1;
|
|
9118
|
-
const se = joinSeg(
|
|
9119
|
-
|
|
9293
|
+
const se = joinSeg(
|
|
9294
|
+
["SE", String(seCount), esc(stControlNumber)],
|
|
9295
|
+
elementSeparator,
|
|
9296
|
+
segmentTerminator
|
|
9297
|
+
);
|
|
9298
|
+
const ge = joinSeg(
|
|
9299
|
+
["GE", "1", esc(envelope.groupControlNumber)],
|
|
9300
|
+
elementSeparator,
|
|
9301
|
+
segmentTerminator
|
|
9302
|
+
);
|
|
9120
9303
|
const iea = joinSeg(["IEA", "1", interchangeControlNumber], elementSeparator, segmentTerminator);
|
|
9121
9304
|
const raw = isa + gs + bodySegments.join("") + se + ge + iea;
|
|
9122
9305
|
return parseX12(raw);
|
|
@@ -9238,7 +9421,7 @@ function buildIk4(elemError, esc, componentSeparator, elementSeparator, segmentT
|
|
|
9238
9421
|
return joinSeg(parts, elementSeparator, segmentTerminator);
|
|
9239
9422
|
}
|
|
9240
9423
|
function buildIk5(response, esc, elementSeparator, segmentTerminator) {
|
|
9241
|
-
const parts = ["IK5", response.disposition];
|
|
9424
|
+
const parts = ["IK5", esc(response.disposition)];
|
|
9242
9425
|
const codes = response.syntaxErrorCodes ?? [];
|
|
9243
9426
|
if (codes.length > 5) {
|
|
9244
9427
|
throw new AckBuildError(
|
|
@@ -9252,7 +9435,7 @@ function buildIk5(response, esc, elementSeparator, segmentTerminator) {
|
|
|
9252
9435
|
function buildAk9(group, esc, elementSeparator, segmentTerminator) {
|
|
9253
9436
|
const parts = [
|
|
9254
9437
|
"AK9",
|
|
9255
|
-
group.disposition,
|
|
9438
|
+
esc(group.disposition),
|
|
9256
9439
|
String(group.numberOfTransactionSets),
|
|
9257
9440
|
String(group.numberOfReceivedTransactionSets),
|
|
9258
9441
|
String(group.numberOfAcceptedTransactionSets)
|
|
@@ -9268,6 +9451,7 @@ function buildAk9(group, esc, elementSeparator, segmentTerminator) {
|
|
|
9268
9451
|
return joinSeg(parts, elementSeparator, segmentTerminator);
|
|
9269
9452
|
}
|
|
9270
9453
|
function joinSeg(parts, elementSeparator, segmentTerminator) {
|
|
9454
|
+
requireCallerSegment(parts, "build999", refuseSpec8);
|
|
9271
9455
|
return parts.join(elementSeparator) + segmentTerminator;
|
|
9272
9456
|
}
|
|
9273
9457
|
function pad8(value, width) {
|
|
@@ -9622,6 +9806,7 @@ function buildTransaction(tx, esc, elementSeparator, segmentTerminator) {
|
|
|
9622
9806
|
return st + bodySegments + se;
|
|
9623
9807
|
}
|
|
9624
9808
|
function joinSeg2(parts, elementSeparator, segmentTerminator) {
|
|
9809
|
+
requireCallerSegment(parts, "buildInterchange", refuseSpec9);
|
|
9625
9810
|
return parts.join(elementSeparator) + segmentTerminator;
|
|
9626
9811
|
}
|
|
9627
9812
|
function pad9(value, width) {
|
|
@@ -9930,8 +10115,8 @@ var profiles = Object.freeze({
|
|
|
9930
10115
|
});
|
|
9931
10116
|
|
|
9932
10117
|
// src/index.ts
|
|
9933
|
-
var VERSION = "0.0.
|
|
10118
|
+
var VERSION = "0.0.10";
|
|
9934
10119
|
|
|
9935
|
-
export { ACK_BUILD_ERROR_CODES, ALL_WARNING_MESSAGES, AUTH_278_BUILD_ERROR_CODES, AUTH_278_LOOP_2000A, AUTH_278_LOOP_2000B, AUTH_278_LOOP_2000C, AUTH_278_LOOP_2000D, AUTH_278_LOOP_2000E, AUTH_278_LOOP_2000F, AckBuildError, BALANCE_INVARIANTS, BUILD_REFUSAL_VALUE_MAX_LENGTH, BUILD_REFUSAL_VALUE_MAX_RENDERED, CARC, CLAIM_837D_LOOP_2000A, CLAIM_837D_LOOP_2300, CLAIM_837D_LOOP_2400, CLAIM_837I_LOOP_2000A, CLAIM_837I_LOOP_2300, CLAIM_837I_LOOP_2400, CLAIM_837P_LOOP_2000A, CLAIM_837P_LOOP_2300, CLAIM_837P_LOOP_2400, CLAIM_837P_LOOP_2410, CLAIM_837_BUILD_ERROR_CODES, CLAIM_837_LOOP_1000A, CLAIM_837_LOOP_1000B, CLAIM_837_LOOP_2010AA, CLAIM_837_LOOP_2010BA, CLAIM_837_LOOP_2010BB, CLAIM_837_LOOP_2010CA, CLAIM_837_LOOP_2430, CLAIM_ADJUSTMENT_GROUP_CODES, CLAIM_STATUS_277_BUILD_ERROR_CODES, CLAIM_STATUS_CATEGORY_CODES, CLAIM_STATUS_CODES, CLP_STATUS, CONTROL_NUMBER_PAIRS, Claim837BuildError, ClaimStatus277BuildError, DELIMITER_POSITIONS, ELIGIBILITY_271_BUILD_ERROR_CODES, ELIGIBILITY_271_LOOP_2000A, ELIGIBILITY_271_LOOP_2000B, ELIGIBILITY_271_LOOP_2000C, ELIGIBILITY_271_LOOP_2000D, ELIGIBILITY_271_LOOP_2100C, ELIGIBILITY_271_LOOP_2100D, ELIGIBILITY_271_LOOP_2110, ENROLLMENT_834_BUILD_ERROR_CODES, ENROLLMENT_834_LOOP_1000A, ENROLLMENT_834_LOOP_1000B, ENROLLMENT_834_LOOP_2000, ENROLLMENT_834_LOOP_2100A, ENROLLMENT_834_LOOP_2300, ENROLLMENT_834_LOOP_2320, Eligibility271BuildError, Enrollment834BuildError, FATAL_CODES, HI_QUALIFIERS, HL_LEVEL_CODES, IK3_SYNTAX_ERROR_CODES, IK4_SYNTAX_ERROR_CODES, ISA_MIN_LENGTH, LoopSpecDefinitionError, MAINTENANCE_TYPE_CODES, NM1_QUALIFIERS, NON_SPEC_SEGMENT_ID, PREMIUM_820_BUILD_ERROR_CODES, PREMIUM_820_LOOP_1000A, PREMIUM_820_LOOP_1000B, PREMIUM_820_LOOP_2000A, PREMIUM_820_LOOP_2100A, PREMIUM_820_LOOP_2300A, PREMIUM_820_LOOP_2310A, Premium820BuildError, RARC, RELEASE_CHAR, REMIT_835_BUILD_ERROR_CODES, REMIT_835_LOOP_1000A, REMIT_835_LOOP_1000B, REMIT_835_LOOP_2000, REMIT_835_LOOP_2100, REMIT_835_LOOP_2110, REQUIRED_LOOPS, Remit835BuildError, SERVICE_TYPE_CODES, STATUS_277_LOOP_2000A, STATUS_277_LOOP_2000B, STATUS_277_LOOP_2000C, STATUS_277_LOOP_2000D, STATUS_277_LOOP_2000E, STATUS_277_LOOP_2200, STATUS_277_LOOP_2220, ServicesReview278BuildError, TA1_ACK_CODES, TA1_NOTE_CODES, UNEXPECTED_SEGMENT_CONTEXTS, VERSION, WARNING_CODES, X12BuildError, X12Decimal, X12ParseError, X12ProfileError, X12_ACK_DISPOSITION_CODES, X12_BUILD_ERROR_CODES, build271, build277, build277CA, build278Request, build278Response, build820, build834, build835, build837D, build837I, build837P, build999, buildInterchange, buildTA1, checkClaimBalance, checkRemitTotalBalance, checkServiceLineBalance, collectElementValues, componentOptional, controlNumberMismatch, danglingReleaseChar, decodeSegment, defineLoopSpec, defineProfile, detectDelimiters, elementDecimal, elementDecimalOrZero, elementOptional, elementValue, escapeRelease, get271Eligibility, get277CADisposition, get277Status, get278Request, get278Response, get820Payments, get834Enrollments, get834Header, get835, get837Claims, getAllSegmentValues, getDefaultProfile, getSegmentValue, groupCountMismatch, hlParentLevelInvalid, hlParentMismatch, isAcceptDisposition, isClaimAdjustmentGroupCode, isDiagnosisQualifier, isProcedureQualifier, lookupCarc, lookupClaimStatus, lookupClaimStatusCategory, lookupClpStatus, lookupMaintenanceType, lookupRarc, lookupServiceType, missingGe, missingIea, missingRequiredLoop, missingSe, parse999, parseTA1, parseX12, partitionWarnings, pre005010, profiles, remitBalanceMismatch, renderCallerValue, resolveHiQualifier, segmentCountMismatch, serializeX12, setDefaultProfile, trailingGarbage, transactionCountMismatch, unescapeRelease, unexpectedSegment, unknown837Variant, unknownCarc, unknownClaimStatus, unknownClaimStatusCategory, unknownHiQualifier, unknownMaintenanceType, unknownRarc };
|
|
10120
|
+
export { ACK_BUILD_ERROR_CODES, ALL_WARNING_MESSAGES, AUTH_278_BUILD_ERROR_CODES, AUTH_278_LOOP_2000A, AUTH_278_LOOP_2000B, AUTH_278_LOOP_2000C, AUTH_278_LOOP_2000D, AUTH_278_LOOP_2000E, AUTH_278_LOOP_2000F, AckBuildError, BALANCE_INVARIANTS, BUILD_REFUSAL_VALUE_MAX_LENGTH, BUILD_REFUSAL_VALUE_MAX_RENDERED, CARC, CLAIM_837D_LOOP_2000A, CLAIM_837D_LOOP_2300, CLAIM_837D_LOOP_2400, CLAIM_837I_LOOP_2000A, CLAIM_837I_LOOP_2300, CLAIM_837I_LOOP_2400, CLAIM_837P_LOOP_2000A, CLAIM_837P_LOOP_2300, CLAIM_837P_LOOP_2400, CLAIM_837P_LOOP_2410, CLAIM_837_BUILD_ERROR_CODES, CLAIM_837_LOOP_1000A, CLAIM_837_LOOP_1000B, CLAIM_837_LOOP_2010AA, CLAIM_837_LOOP_2010BA, CLAIM_837_LOOP_2010BB, CLAIM_837_LOOP_2010CA, CLAIM_837_LOOP_2430, CLAIM_ADJUSTMENT_GROUP_CODES, CLAIM_STATUS_277_BUILD_ERROR_CODES, CLAIM_STATUS_CATEGORY_CODES, CLAIM_STATUS_CODES, CLP_STATUS, CONTROL_NUMBER_PAIRS, Claim837BuildError, ClaimStatus277BuildError, DELIMITER_POSITIONS, ELIGIBILITY_271_BUILD_ERROR_CODES, ELIGIBILITY_271_LOOP_2000A, ELIGIBILITY_271_LOOP_2000B, ELIGIBILITY_271_LOOP_2000C, ELIGIBILITY_271_LOOP_2000D, ELIGIBILITY_271_LOOP_2100C, ELIGIBILITY_271_LOOP_2100D, ELIGIBILITY_271_LOOP_2110, ENROLLMENT_834_BUILD_ERROR_CODES, ENROLLMENT_834_LOOP_1000A, ENROLLMENT_834_LOOP_1000B, ENROLLMENT_834_LOOP_2000, ENROLLMENT_834_LOOP_2100A, ENROLLMENT_834_LOOP_2300, ENROLLMENT_834_LOOP_2320, Eligibility271BuildError, Enrollment834BuildError, FATAL_CODES, HI_QUALIFIERS, HL_LEVEL_CODES, IK3_SYNTAX_ERROR_CODES, IK4_SYNTAX_ERROR_CODES, ISA_MIN_LENGTH, LoopSpecDefinitionError, MAINTENANCE_TYPE_CODES, NM1_QUALIFIERS, NON_SPEC_SEGMENT_ID, PREMIUM_820_BUILD_ERROR_CODES, PREMIUM_820_LOOP_1000A, PREMIUM_820_LOOP_1000B, PREMIUM_820_LOOP_2000A, PREMIUM_820_LOOP_2100A, PREMIUM_820_LOOP_2300A, PREMIUM_820_LOOP_2310A, Premium820BuildError, RARC, RELEASE_CHAR, REMIT_835_BUILD_ERROR_CODES, REMIT_835_LOOP_1000A, REMIT_835_LOOP_1000B, REMIT_835_LOOP_2000, REMIT_835_LOOP_2100, REMIT_835_LOOP_2110, REQUIRED_LOOPS, Remit835BuildError, SERVICE_TYPE_CODES, STATUS_277_LOOP_2000A, STATUS_277_LOOP_2000B, STATUS_277_LOOP_2000C, STATUS_277_LOOP_2000D, STATUS_277_LOOP_2000E, STATUS_277_LOOP_2200, STATUS_277_LOOP_2220, ServicesReview278BuildError, TA1_ACK_CODES, TA1_NOTE_CODES, UNEXPECTED_SEGMENT_CONTEXTS, VERSION, WARNING_CODES, X12BuildError, X12Decimal, X12ParseError, X12ProfileError, X12_ACK_DISPOSITION_CODES, X12_BUILD_ERROR_CODES, build271, build277, build277CA, build278Request, build278Response, build820, build834, build835, build837D, build837I, build837P, build999, buildInterchange, buildTA1, checkClaimBalance, checkRemitTotalBalance, checkServiceLineBalance, collectElementValues, componentOptional, controlNumberMismatch, danglingReleaseChar, decodeSegment, defineLoopSpec, defineProfile, detectDelimiters, elementDecimal, elementDecimalOrZero, elementOptional, elementValue, escapeRelease, get271Eligibility, get277CADisposition, get277Status, get278Request, get278Response, get820Payments, get834Enrollments, get834Header, get835, get837Claims, getAllSegmentValues, getDefaultProfile, getSegmentValue, groupCountMismatch, hlParentLevelInvalid, hlParentMismatch, isAcceptDisposition, isClaimAdjustmentGroupCode, isDiagnosisQualifier, isProcedureQualifier, lookupCarc, lookupClaimStatus, lookupClaimStatusCategory, lookupClpStatus, lookupMaintenanceType, lookupRarc, lookupServiceType, missingGe, missingIea, missingRequiredLoop, missingSe, parse999, parseTA1, parseX12, partitionWarnings, pre005010, profiles, readElementDecimal, remitBalanceMismatch, renderCallerValue, resolveHiQualifier, segmentCountMismatch, serializeX12, serviceLineDropped, serviceLineNotDecoded, setDefaultProfile, trailingGarbage, transactionCountMismatch, unescapeRelease, unexpectedSegment, unknown837Variant, unknownCarc, unknownClaimStatus, unknownClaimStatusCategory, unknownHiQualifier, unknownMaintenanceType, unknownRarc, unparseableDecimal };
|
|
9936
10121
|
//# sourceMappingURL=index.mjs.map
|
|
9937
10122
|
//# sourceMappingURL=index.mjs.map
|