facturas 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +95 -34
- package/dist/{chunk-XNBD5NVL.mjs → chunk-ALH5IPSY.mjs} +2 -57
- package/dist/chunk-ALH5IPSY.mjs.map +1 -0
- package/dist/{chunk-RCM4NAAG.mjs → chunk-QHHLHSBW.mjs} +9 -122
- package/dist/chunk-QHHLHSBW.mjs.map +1 -0
- package/dist/{chunk-4QVFXT35.mjs → chunk-UDX6HLAU.mjs} +1 -17
- package/dist/{chunk-4QVFXT35.mjs.map → chunk-UDX6HLAU.mjs.map} +1 -1
- package/dist/index.d.ts +62 -12
- package/dist/index.mjs +265 -87
- package/dist/index.mjs.map +1 -1
- package/dist/{wsfe-DF0jAE2k.d.ts → wsfe-DDY9E1GJ.d.ts} +1 -25
- package/dist/wsfe.d.ts +1 -1
- package/dist/wsfe.mjs +2 -2
- package/dist/wsmtxca.d.ts +1 -17
- package/dist/wsmtxca.mjs +2 -2
- package/package.json +1 -1
- package/dist/chunk-RCM4NAAG.mjs.map +0 -1
- package/dist/chunk-XNBD5NVL.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
normalizeWsfeDateInput,
|
|
11
11
|
normalizeWsfeVoucherInput,
|
|
12
12
|
serializeArcaExchangeRate
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-QHHLHSBW.mjs";
|
|
14
14
|
import {
|
|
15
15
|
ARCA_CURRENCY_IDS,
|
|
16
16
|
ARCA_DOCUMENT_TYPES,
|
|
@@ -22,8 +22,8 @@ import {
|
|
|
22
22
|
} from "./chunk-76WU5BVI.mjs";
|
|
23
23
|
import {
|
|
24
24
|
createWsmtxcaService
|
|
25
|
-
} from "./chunk-
|
|
26
|
-
import "./chunk-
|
|
25
|
+
} from "./chunk-ALH5IPSY.mjs";
|
|
26
|
+
import "./chunk-UDX6HLAU.mjs";
|
|
27
27
|
import {
|
|
28
28
|
ArcaAuthenticationError,
|
|
29
29
|
ArcaConfigurationError,
|
|
@@ -379,18 +379,15 @@ function deriveWsfeInvoice(input, now = /* @__PURE__ */ new Date()) {
|
|
|
379
379
|
],
|
|
380
380
|
"input"
|
|
381
381
|
);
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
"issuer",
|
|
385
|
-
"responsable_inscripto, monotributo, exento, or no_alcanzado"
|
|
386
|
-
);
|
|
387
|
-
}
|
|
388
|
-
if (!Number.isSafeInteger(input.salesPoint) || input.salesPoint < 1 || input.salesPoint > 99999) {
|
|
389
|
-
invalid("salesPoint", "an integer from 1 through 99999");
|
|
390
|
-
}
|
|
382
|
+
assertIssuerCondition(input.issuer);
|
|
383
|
+
assertSalesPoint(input.salesPoint);
|
|
391
384
|
const receiver = deriveReceiver(input.to);
|
|
392
|
-
const voucherClass =
|
|
393
|
-
const { data: amountsData, amounts } = calculateWsfeAmounts(
|
|
385
|
+
const voucherClass = resolveInvoiceClass(input.issuer, input.to.condition);
|
|
386
|
+
const { data: amountsData, amounts } = calculateWsfeAmounts({
|
|
387
|
+
voucherClass,
|
|
388
|
+
items: input.items,
|
|
389
|
+
total: input.total
|
|
390
|
+
});
|
|
394
391
|
const currency = deriveCurrency(input);
|
|
395
392
|
if (input.to.condition === "consumidor_final" && receiver.documentType === ARCA_DOCUMENT_TYPES.CONSUMIDOR_FINAL) {
|
|
396
393
|
const [whole, fraction = ""] = currency.exchangeRate.split(".");
|
|
@@ -430,6 +427,22 @@ function deriveWsfeInvoice(input, now = /* @__PURE__ */ new Date()) {
|
|
|
430
427
|
}
|
|
431
428
|
return { data, voucherClass, amounts };
|
|
432
429
|
}
|
|
430
|
+
function assertIssuerCondition(issuer) {
|
|
431
|
+
if (typeof issuer !== "string" || !Object.hasOwn(ARCA_ISSUER_CONDITION_IDS, issuer)) {
|
|
432
|
+
invalid(
|
|
433
|
+
"issuer",
|
|
434
|
+
"responsable_inscripto, monotributo, exento, or no_alcanzado"
|
|
435
|
+
);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
function assertSalesPoint(salesPoint) {
|
|
439
|
+
if (!Number.isSafeInteger(salesPoint) || salesPoint < 1 || salesPoint > 99999) {
|
|
440
|
+
invalid("salesPoint", "an integer from 1 through 99999");
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
function resolveInvoiceClass(issuer, condition) {
|
|
444
|
+
return ARCA_INVOICE_CLASS_BY_ISSUER[issuer][condition];
|
|
445
|
+
}
|
|
433
446
|
function deriveReceiver(to) {
|
|
434
447
|
assertIssueObject(to, "to");
|
|
435
448
|
assertIssueKeys(to, ["condition", "cuit", "dni"], "to");
|
|
@@ -544,11 +557,11 @@ function assertIssueObject(value, field) {
|
|
|
544
557
|
invalid(field, "an object");
|
|
545
558
|
}
|
|
546
559
|
}
|
|
547
|
-
function assertIssueKeys(value, keys, prefix) {
|
|
560
|
+
function assertIssueKeys(value, keys, prefix, method = "issue()") {
|
|
548
561
|
for (const key of Object.keys(value)) {
|
|
549
562
|
if (!keys.includes(key)) {
|
|
550
563
|
const field = prefix === "input" ? key : `${prefix}.${key}`;
|
|
551
|
-
throw new ArcaInputError(`${field} is not supported by
|
|
564
|
+
throw new ArcaInputError(`${field} is not supported by ${method}.`, {
|
|
552
565
|
code: "ARCA_INPUT_RESERVED_FIELD",
|
|
553
566
|
field,
|
|
554
567
|
expected: "a supported facade field; use the exact API for other fiscal fields"
|
|
@@ -564,7 +577,7 @@ function invalid(field, expected) {
|
|
|
564
577
|
});
|
|
565
578
|
}
|
|
566
579
|
|
|
567
|
-
// src/services/wsfe-
|
|
580
|
+
// src/services/wsfe-credit-note.ts
|
|
568
581
|
var NOTES = {
|
|
569
582
|
1: { voucherType: 3, voucherClass: "A" },
|
|
570
583
|
6: { voucherType: 8, voucherClass: "B" },
|
|
@@ -572,7 +585,7 @@ var NOTES = {
|
|
|
572
585
|
};
|
|
573
586
|
function invalid2(reason) {
|
|
574
587
|
throw new ArcaInputError(
|
|
575
|
-
`
|
|
588
|
+
`issueCreditNote cannot proceed: ${reason}. Use wsfe.issue() for exact control.`,
|
|
576
589
|
{ code: "ARCA_INPUT_INVALID_VALUE" }
|
|
577
590
|
);
|
|
578
591
|
}
|
|
@@ -582,7 +595,52 @@ function required(value, field) {
|
|
|
582
595
|
}
|
|
583
596
|
return value;
|
|
584
597
|
}
|
|
585
|
-
function
|
|
598
|
+
function deriveWsfeFullCreditNote(original, input, now = /* @__PURE__ */ new Date()) {
|
|
599
|
+
const { note, header } = prepareCreditNote(original, input, now);
|
|
600
|
+
const data = {
|
|
601
|
+
...header,
|
|
602
|
+
totalAmount: required(original.totalAmount, "totalAmount"),
|
|
603
|
+
netAmount: required(original.netAmount, "netAmount"),
|
|
604
|
+
vatAmount: required(original.vatAmount, "vatAmount"),
|
|
605
|
+
exemptAmount: required(original.exemptAmount, "exemptAmount"),
|
|
606
|
+
nonTaxableAmount: required(original.nonTaxableAmount, "nonTaxableAmount"),
|
|
607
|
+
taxAmount: required(original.taxAmount, "taxAmount"),
|
|
608
|
+
...original.vatRates === void 0 ? {} : { vatRates: original.vatRates.map((rate) => ({ ...rate })) }
|
|
609
|
+
};
|
|
610
|
+
normalizeWsfeVoucherInput(data);
|
|
611
|
+
const total = Number(
|
|
612
|
+
normalizeArcaAmountToMinorUnits(data.totalAmount, "totalAmount")
|
|
613
|
+
);
|
|
614
|
+
return {
|
|
615
|
+
data,
|
|
616
|
+
voucherClass: note.voucherClass,
|
|
617
|
+
amounts: { computedTotal: total, sentTotal: total, vatAdjustment: 0 }
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
function deriveWsfePartialCreditNote(original, input, now = /* @__PURE__ */ new Date()) {
|
|
621
|
+
if (input.items === void 0) {
|
|
622
|
+
invalid2("items is required to credit chosen lines");
|
|
623
|
+
}
|
|
624
|
+
const { note, header } = prepareCreditNote(original, input, now);
|
|
625
|
+
const { data: amountsData, amounts } = calculateWsfeAmounts({
|
|
626
|
+
voucherClass: note.voucherClass,
|
|
627
|
+
items: input.items,
|
|
628
|
+
total: input.total
|
|
629
|
+
});
|
|
630
|
+
const originalTotal = normalizeArcaAmountToMinorUnits(
|
|
631
|
+
required(original.totalAmount, "totalAmount"),
|
|
632
|
+
"totalAmount"
|
|
633
|
+
);
|
|
634
|
+
if (BigInt(amounts.sentTotal) > originalTotal) {
|
|
635
|
+
invalid2(
|
|
636
|
+
"the note total is greater than the original; the SDK does not track earlier notes against an original"
|
|
637
|
+
);
|
|
638
|
+
}
|
|
639
|
+
const data = { ...header, ...amountsData };
|
|
640
|
+
normalizeWsfeVoucherInput(data);
|
|
641
|
+
return { data, voucherClass: note.voucherClass, amounts };
|
|
642
|
+
}
|
|
643
|
+
function prepareCreditNote(original, input, now) {
|
|
586
644
|
const note = NOTES[original.voucherType ?? 0];
|
|
587
645
|
if (!note) {
|
|
588
646
|
invalid2("original must be an invoice of type 1, 6 or 11");
|
|
@@ -595,7 +653,7 @@ function deriveWsfeCancellation(original, date, now = /* @__PURE__ */ new Date()
|
|
|
595
653
|
invalid2("unsupported currency; only ARS and USD are supported");
|
|
596
654
|
}
|
|
597
655
|
const voucherDate = normalizeWsfeDateInput(
|
|
598
|
-
date ?? buenosAiresDate(now),
|
|
656
|
+
input.date ?? buenosAiresDate(now),
|
|
599
657
|
"date"
|
|
600
658
|
);
|
|
601
659
|
const originalDate = normalizeWsfeDateInput(
|
|
@@ -607,8 +665,8 @@ function deriveWsfeCancellation(original, date, now = /* @__PURE__ */ new Date()
|
|
|
607
665
|
"original date is later than the note and outside its month (10210)"
|
|
608
666
|
);
|
|
609
667
|
}
|
|
610
|
-
const
|
|
611
|
-
salesPoint: required(original.salesPoint, "salesPoint"),
|
|
668
|
+
const header = {
|
|
669
|
+
salesPoint: input.salesPoint ?? required(original.salesPoint, "salesPoint"),
|
|
612
670
|
voucherType: note.voucherType,
|
|
613
671
|
concept: required(original.concept, "concept"),
|
|
614
672
|
documentType: required(original.documentType, "documentType"),
|
|
@@ -620,13 +678,6 @@ function deriveWsfeCancellation(original, date, now = /* @__PURE__ */ new Date()
|
|
|
620
678
|
currencyId: original.currencyId,
|
|
621
679
|
exchangeRate: required(original.exchangeRate, "exchangeRate"),
|
|
622
680
|
voucherDate,
|
|
623
|
-
totalAmount: required(original.totalAmount, "totalAmount"),
|
|
624
|
-
netAmount: required(original.netAmount, "netAmount"),
|
|
625
|
-
vatAmount: required(original.vatAmount, "vatAmount"),
|
|
626
|
-
exemptAmount: required(original.exemptAmount, "exemptAmount"),
|
|
627
|
-
nonTaxableAmount: required(original.nonTaxableAmount, "nonTaxableAmount"),
|
|
628
|
-
taxAmount: required(original.taxAmount, "taxAmount"),
|
|
629
|
-
...original.vatRates === void 0 ? {} : { vatRates: original.vatRates.map((rate) => ({ ...rate })) },
|
|
630
681
|
associatedVouchers: [
|
|
631
682
|
{
|
|
632
683
|
type: required(original.voucherType, "voucherType"),
|
|
@@ -636,16 +687,8 @@ function deriveWsfeCancellation(original, date, now = /* @__PURE__ */ new Date()
|
|
|
636
687
|
}
|
|
637
688
|
]
|
|
638
689
|
};
|
|
639
|
-
copyServiceDates(original,
|
|
640
|
-
|
|
641
|
-
const total = Number(
|
|
642
|
-
normalizeArcaAmountToMinorUnits(data.totalAmount, "totalAmount")
|
|
643
|
-
);
|
|
644
|
-
return {
|
|
645
|
-
data,
|
|
646
|
-
voucherClass: note.voucherClass,
|
|
647
|
-
amounts: { computedTotal: total, sentTotal: total, vatAdjustment: 0 }
|
|
648
|
-
};
|
|
690
|
+
copyServiceDates(original, header);
|
|
691
|
+
return { note, header };
|
|
649
692
|
}
|
|
650
693
|
function rejectExtensions(original) {
|
|
651
694
|
for (const [field, rawField] of [
|
|
@@ -668,15 +711,15 @@ function rejectExtensions(original) {
|
|
|
668
711
|
function present(value) {
|
|
669
712
|
return value !== void 0 && value !== null && value !== "" && (!Array.isArray(value) || value.length > 0);
|
|
670
713
|
}
|
|
671
|
-
function copyServiceDates(original,
|
|
672
|
-
if (
|
|
714
|
+
function copyServiceDates(original, header) {
|
|
715
|
+
if (header.concept !== 2 && header.concept !== 3) {
|
|
673
716
|
return;
|
|
674
717
|
}
|
|
675
|
-
|
|
718
|
+
header.serviceStartDate = required(
|
|
676
719
|
original.serviceStartDate,
|
|
677
720
|
"serviceStartDate"
|
|
678
721
|
);
|
|
679
|
-
|
|
722
|
+
header.serviceEndDate = required(
|
|
680
723
|
original.serviceEndDate,
|
|
681
724
|
"serviceEndDate"
|
|
682
725
|
);
|
|
@@ -684,7 +727,134 @@ function copyServiceDates(original, data) {
|
|
|
684
727
|
required(original.paymentDueDate, "paymentDueDate"),
|
|
685
728
|
"original.paymentDueDate"
|
|
686
729
|
);
|
|
687
|
-
|
|
730
|
+
header.paymentDueDate = due < header.voucherDate ? header.voucherDate : due;
|
|
731
|
+
}
|
|
732
|
+
var CREDIT_NOTE_KEYS = ["for", "salesPoint", "date", "items", "total", "all"];
|
|
733
|
+
var TARGET_BOUNDS = [
|
|
734
|
+
["salesPoint", 99999],
|
|
735
|
+
["voucherType", 999],
|
|
736
|
+
["number", 99999999]
|
|
737
|
+
];
|
|
738
|
+
function assertCreditNoteInput(input) {
|
|
739
|
+
assertIssueObject(input, "input");
|
|
740
|
+
if ("associatedPeriod" in input) {
|
|
741
|
+
throw new ArcaInputError(
|
|
742
|
+
"issueCreditNote does not support associatedPeriod; a note against a period is exact-layer work. Use wsfe.issue() for exact control.",
|
|
743
|
+
{
|
|
744
|
+
code: "ARCA_INPUT_RESERVED_FIELD",
|
|
745
|
+
field: "associatedPeriod",
|
|
746
|
+
expected: "an associated invoice through for"
|
|
747
|
+
}
|
|
748
|
+
);
|
|
749
|
+
}
|
|
750
|
+
assertIssueKeys(input, CREDIT_NOTE_KEYS, "input", "issueCreditNote()");
|
|
751
|
+
const target = assertCreditNoteTarget(input.for);
|
|
752
|
+
if (input.salesPoint !== void 0) {
|
|
753
|
+
assertCreditNoteBound(input.salesPoint, 99999, "salesPoint");
|
|
754
|
+
}
|
|
755
|
+
const date = input.date === void 0 ? void 0 : normalizeWsfeDateInput(input.date, "date");
|
|
756
|
+
const common = {
|
|
757
|
+
for: target,
|
|
758
|
+
...input.salesPoint === void 0 ? {} : { salesPoint: input.salesPoint },
|
|
759
|
+
...date === void 0 ? {} : { date }
|
|
760
|
+
};
|
|
761
|
+
if (input.items === void 0 === (input.all === void 0)) {
|
|
762
|
+
throw new ArcaInputError(
|
|
763
|
+
"issueCreditNote needs exactly one mode: items for the credited lines, or all: true for the whole original.",
|
|
764
|
+
{
|
|
765
|
+
code: "ARCA_INPUT_INVALID_VALUE",
|
|
766
|
+
field: input.items === void 0 ? "input.items" : "input.all",
|
|
767
|
+
expected: "either items or all: true, never both and never neither"
|
|
768
|
+
}
|
|
769
|
+
);
|
|
770
|
+
}
|
|
771
|
+
if (input.all !== void 0) {
|
|
772
|
+
if (input.all !== true) {
|
|
773
|
+
throw new ArcaInputError(
|
|
774
|
+
"issueCreditNote accepts only all: true; pass items to credit chosen lines.",
|
|
775
|
+
{
|
|
776
|
+
code: "ARCA_INPUT_INVALID_VALUE",
|
|
777
|
+
field: "input.all",
|
|
778
|
+
expected: "the literal true"
|
|
779
|
+
}
|
|
780
|
+
);
|
|
781
|
+
}
|
|
782
|
+
if (input.total !== void 0) {
|
|
783
|
+
throw new ArcaInputError(
|
|
784
|
+
"issueCreditNote takes total only with items; all: true credits the original's own total.",
|
|
785
|
+
{
|
|
786
|
+
code: "ARCA_INPUT_INVALID_VALUE",
|
|
787
|
+
field: "input.total",
|
|
788
|
+
expected: "no total when all is true"
|
|
789
|
+
}
|
|
790
|
+
);
|
|
791
|
+
}
|
|
792
|
+
return { ...common, all: true };
|
|
793
|
+
}
|
|
794
|
+
return {
|
|
795
|
+
...common,
|
|
796
|
+
items: copyCreditNoteItems(input.items),
|
|
797
|
+
...input.total === void 0 ? {} : { total: input.total }
|
|
798
|
+
};
|
|
799
|
+
}
|
|
800
|
+
function assertCreditNoteTarget(value) {
|
|
801
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
802
|
+
throw new ArcaInputError(
|
|
803
|
+
"issueCreditNote requires for: the coordinates of the authorized invoice the note corrects.",
|
|
804
|
+
{
|
|
805
|
+
code: "ARCA_INPUT_MISSING_FIELD",
|
|
806
|
+
field: "input.for",
|
|
807
|
+
expected: "{ salesPoint, voucherType, number }"
|
|
808
|
+
}
|
|
809
|
+
);
|
|
810
|
+
}
|
|
811
|
+
assertIssueKeys(
|
|
812
|
+
value,
|
|
813
|
+
["salesPoint", "voucherType", "number"],
|
|
814
|
+
"input.for",
|
|
815
|
+
"issueCreditNote()"
|
|
816
|
+
);
|
|
817
|
+
for (const [field, max] of TARGET_BOUNDS) {
|
|
818
|
+
assertCreditNoteBound(value[field], max, `for.${field}`);
|
|
819
|
+
}
|
|
820
|
+
if (![1, 6, 11].includes(value.voucherType)) {
|
|
821
|
+
throw new ArcaInputError(
|
|
822
|
+
"issueCreditNote requires an authorized invoice of type 1, 6 or 11 in for.voucherType. Use wsfe.issue() for exact control.",
|
|
823
|
+
{
|
|
824
|
+
code: "ARCA_INPUT_INVALID_VALUE",
|
|
825
|
+
field: "input.for.voucherType",
|
|
826
|
+
expected: "1, 6 or 11"
|
|
827
|
+
}
|
|
828
|
+
);
|
|
829
|
+
}
|
|
830
|
+
return {
|
|
831
|
+
salesPoint: value.salesPoint,
|
|
832
|
+
voucherType: value.voucherType,
|
|
833
|
+
number: value.number
|
|
834
|
+
};
|
|
835
|
+
}
|
|
836
|
+
function assertCreditNoteBound(value, max, path) {
|
|
837
|
+
if (!Number.isSafeInteger(value) || value < 1 || value > max) {
|
|
838
|
+
throw new ArcaInputError(
|
|
839
|
+
`issueCreditNote requires input.${path} to be an integer from 1 through ${max}.`,
|
|
840
|
+
{ code: "ARCA_INPUT_INVALID_VALUE", field: `input.${path}` }
|
|
841
|
+
);
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
function copyCreditNoteItems(items) {
|
|
845
|
+
if (!Array.isArray(items)) {
|
|
846
|
+
throw new ArcaInputError(
|
|
847
|
+
"issueCreditNote requires items to be a non-empty array of items.",
|
|
848
|
+
{
|
|
849
|
+
code: "ARCA_INPUT_INVALID_VALUE",
|
|
850
|
+
field: "input.items",
|
|
851
|
+
expected: "a non-empty array of items"
|
|
852
|
+
}
|
|
853
|
+
);
|
|
854
|
+
}
|
|
855
|
+
return items.map(
|
|
856
|
+
(item) => item === null || typeof item !== "object" ? item : { ...item }
|
|
857
|
+
);
|
|
688
858
|
}
|
|
689
859
|
|
|
690
860
|
// src/services/wsfe-identity.ts
|
|
@@ -932,8 +1102,13 @@ function associationIdentity(vouchers) {
|
|
|
932
1102
|
// src/services/vouchers.ts
|
|
933
1103
|
function createVouchersService(wsfe, context) {
|
|
934
1104
|
return {
|
|
935
|
-
|
|
936
|
-
const result = await
|
|
1105
|
+
issueCreditNote: async (input, options) => {
|
|
1106
|
+
const result = await issueCreditNote(
|
|
1107
|
+
wsfe,
|
|
1108
|
+
input,
|
|
1109
|
+
options === void 0 ? {} : options,
|
|
1110
|
+
context
|
|
1111
|
+
);
|
|
937
1112
|
return result;
|
|
938
1113
|
},
|
|
939
1114
|
issue: async (input, options) => {
|
|
@@ -944,7 +1119,27 @@ function createVouchersService(wsfe, context) {
|
|
|
944
1119
|
context
|
|
945
1120
|
);
|
|
946
1121
|
return result;
|
|
947
|
-
}
|
|
1122
|
+
},
|
|
1123
|
+
preview: (input, options) => previewInvoice(input, options === void 0 ? {} : options)
|
|
1124
|
+
};
|
|
1125
|
+
}
|
|
1126
|
+
function previewInvoice(input, options) {
|
|
1127
|
+
assertIssueObject(options, "options");
|
|
1128
|
+
assertIssueKeys(options, ["representedTaxId"], "options");
|
|
1129
|
+
if (options.representedTaxId !== void 0) {
|
|
1130
|
+
issueDocumentNumber(
|
|
1131
|
+
options.representedTaxId,
|
|
1132
|
+
"options.representedTaxId",
|
|
1133
|
+
11,
|
|
1134
|
+
11
|
|
1135
|
+
);
|
|
1136
|
+
}
|
|
1137
|
+
const { data, voucherClass, amounts } = deriveWsfeInvoice(input);
|
|
1138
|
+
return {
|
|
1139
|
+
voucherClass,
|
|
1140
|
+
voucherType: data.voucherType,
|
|
1141
|
+
amounts,
|
|
1142
|
+
request: data
|
|
948
1143
|
};
|
|
949
1144
|
}
|
|
950
1145
|
async function issueInvoice(wsfe, input, options, context) {
|
|
@@ -1042,7 +1237,7 @@ function validateKeyStore(options, context) {
|
|
|
1042
1237
|
function readRecord(json) {
|
|
1043
1238
|
try {
|
|
1044
1239
|
const record = JSON.parse(json);
|
|
1045
|
-
if (!record || record.v !== 1 || !["issue", "
|
|
1240
|
+
if (!record || record.v !== 1 || !["issue", "creditNote"].includes(record.operation) || typeof record.inputHash !== "string" || !record.sent || !Number.isSafeInteger(record.number) || record.number < 1 || record.number > 99999999 || record.sent.salesPoint !== record.salesPoint || record.sent.voucherType !== record.voucherType) {
|
|
1046
1241
|
throw new Error("Invalid reservation structure");
|
|
1047
1242
|
}
|
|
1048
1243
|
normalizeWsfeVoucherInput(record.sent);
|
|
@@ -1339,59 +1534,41 @@ function replayEvidence() {
|
|
|
1339
1534
|
observations: []
|
|
1340
1535
|
};
|
|
1341
1536
|
}
|
|
1342
|
-
async function
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
assertIssueObject(target, "target");
|
|
1348
|
-
for (const [field, max] of [
|
|
1349
|
-
["salesPoint", 99999],
|
|
1350
|
-
["voucherType", 999],
|
|
1351
|
-
["number", 99999999]
|
|
1352
|
-
]) {
|
|
1353
|
-
if (!Number.isSafeInteger(target[field]) || target[field] < 1 || target[field] > max) {
|
|
1354
|
-
throw new ArcaInputError(`Invalid cancel target ${field}.`, {
|
|
1355
|
-
code: "ARCA_INPUT_INVALID_VALUE",
|
|
1356
|
-
field
|
|
1357
|
-
});
|
|
1358
|
-
}
|
|
1359
|
-
}
|
|
1360
|
-
if (![1, 6, 11].includes(target.voucherType)) {
|
|
1361
|
-
throw new ArcaInputError(
|
|
1362
|
-
"cancel requires an invoice of type 1, 6 or 11; use wsfe.issue() for exact control.",
|
|
1363
|
-
{ code: "ARCA_INPUT_INVALID_VALUE" }
|
|
1364
|
-
);
|
|
1365
|
-
}
|
|
1366
|
-
if (date !== void 0) {
|
|
1367
|
-
normalizeWsfeDateInput(date, "date");
|
|
1368
|
-
}
|
|
1537
|
+
async function issueCreditNote(wsfe, input, options, context) {
|
|
1538
|
+
validateOptions(options);
|
|
1539
|
+
validateKeyStore(options, context);
|
|
1540
|
+
const note = assertCreditNoteInput(input);
|
|
1541
|
+
const target = note.for;
|
|
1369
1542
|
return await runOperation(
|
|
1370
1543
|
wsfe,
|
|
1371
|
-
"
|
|
1372
|
-
|
|
1544
|
+
"creditNote",
|
|
1545
|
+
note,
|
|
1373
1546
|
async () => {
|
|
1374
1547
|
const original = await wsfe.lookupVoucher({
|
|
1375
|
-
representedTaxId:
|
|
1376
|
-
forceRefresh:
|
|
1548
|
+
representedTaxId: options.representedTaxId,
|
|
1549
|
+
forceRefresh: options.forceRefresh,
|
|
1377
1550
|
salesPoint: target.salesPoint,
|
|
1378
1551
|
voucherType: target.voucherType,
|
|
1379
1552
|
number: target.number
|
|
1380
1553
|
});
|
|
1381
1554
|
if (original.kind === "not_found") {
|
|
1382
|
-
throw new ArcaInputError(
|
|
1383
|
-
|
|
1384
|
-
|
|
1555
|
+
throw new ArcaInputError(
|
|
1556
|
+
"issueCreditNote failed: original voucher not found.",
|
|
1557
|
+
{
|
|
1558
|
+
code: "ARCA_INPUT_INVALID_VALUE",
|
|
1559
|
+
field: "input.for"
|
|
1560
|
+
}
|
|
1561
|
+
);
|
|
1385
1562
|
}
|
|
1386
1563
|
if (original.voucher.salesPoint !== target.salesPoint || original.voucher.voucherType !== target.voucherType || original.voucher.voucherNumber !== target.number) {
|
|
1387
1564
|
throw new ArcaInputError(
|
|
1388
|
-
"
|
|
1389
|
-
{ code: "ARCA_INPUT_INVALID_VALUE" }
|
|
1565
|
+
"issueCreditNote failed: the original lookup coordinates do not match input.for.",
|
|
1566
|
+
{ code: "ARCA_INPUT_INVALID_VALUE", field: "input.for" }
|
|
1390
1567
|
);
|
|
1391
1568
|
}
|
|
1392
|
-
return
|
|
1569
|
+
return note.all === true ? deriveWsfeFullCreditNote(original.voucher, note) : deriveWsfePartialCreditNote(original.voucher, note);
|
|
1393
1570
|
},
|
|
1394
|
-
|
|
1571
|
+
options,
|
|
1395
1572
|
context
|
|
1396
1573
|
);
|
|
1397
1574
|
}
|
|
@@ -2278,7 +2455,8 @@ function createArcaClient(config = {}) {
|
|
|
2278
2455
|
return {
|
|
2279
2456
|
config: publicConfig,
|
|
2280
2457
|
issue: vouchers.issue,
|
|
2281
|
-
|
|
2458
|
+
preview: vouchers.preview,
|
|
2459
|
+
issueCreditNote: vouchers.issueCreditNote,
|
|
2282
2460
|
wsfe,
|
|
2283
2461
|
wsmtxca: createWsmtxcaService({ config: normalizedConfig, auth, soap }),
|
|
2284
2462
|
padron: createPadronService({ config: normalizedConfig, auth, soap })
|