@design.estate/dees-document 3.3.0 → 3.4.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/dist_bundle/bundle.js +296 -241
- package/dist_bundle/bundle.js.map +1 -1
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.pdfservice.d.ts +3 -0
- package/dist_ts/classes.pdfservice.js +5 -1
- package/dist_ts_shared/index.d.ts +1 -0
- package/dist_ts_shared/index.js +2 -1
- package/dist_ts_shared/paidamount.d.ts +42 -0
- package/dist_ts_shared/paidamount.js +141 -0
- package/dist_ts_shared/translation.d.ts +11 -0
- package/dist_ts_shared/translation.js +23 -1
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/dist_ts_web/elements/contentinvoice.d.ts +29 -1
- package/dist_ts_web/elements/contentinvoice.js +125 -20
- package/dist_ts_web/elements/document.js +13 -1
- package/package.json +2 -2
- package/readme.md +11 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.pdfservice.ts +4 -0
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/elements/contentinvoice.ts +142 -19
- package/ts_web/elements/document.ts +11 -0
|
@@ -452,6 +452,21 @@ export class DeContentInvoice extends DeesElement {
|
|
|
452
452
|
font-weight: bold;
|
|
453
453
|
}
|
|
454
454
|
|
|
455
|
+
/* the tax an advance payment contains is stated, not added up */
|
|
456
|
+
.sums .sumline--contained .label,
|
|
457
|
+
.sums .sumline--contained .value {
|
|
458
|
+
font-weight: normal;
|
|
459
|
+
font-size: 11px;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
.advancePayment {
|
|
463
|
+
margin-top: 2px;
|
|
464
|
+
padding-left: 20%;
|
|
465
|
+
font-size: 11px;
|
|
466
|
+
text-align: right;
|
|
467
|
+
color: #555;
|
|
468
|
+
}
|
|
469
|
+
|
|
455
470
|
.divider {
|
|
456
471
|
margin-top: 8px;
|
|
457
472
|
border-top: 1px dotted #ccc;
|
|
@@ -747,20 +762,28 @@ export class DeContentInvoice extends DeesElement {
|
|
|
747
762
|
|
|
748
763
|
/**
|
|
749
764
|
* The due date, which only an accounting document and a payment reminder
|
|
750
|
-
* have: it counts `dueInDays` from the letter's date.
|
|
765
|
+
* have: it counts `dueInDays` from the letter's date. A document that
|
|
766
|
+
* states a paid amount names the amount due, since the total is not what
|
|
767
|
+
* remains to be paid.
|
|
751
768
|
*/
|
|
752
769
|
private renderPaymentTerms(optionsArg: {
|
|
753
770
|
date: number;
|
|
754
771
|
dueInDays: number;
|
|
755
772
|
labelKey: plugins.shared.translation.TranslationKey;
|
|
756
773
|
textKey: plugins.shared.translation.TranslationKey;
|
|
774
|
+
/** the amount due, when the document states a paid amount */
|
|
775
|
+
amountDue?: number;
|
|
757
776
|
}): TemplateResult {
|
|
758
777
|
return html`<div class="infoBox">
|
|
759
778
|
<div>
|
|
760
779
|
<div>
|
|
761
780
|
<div class="label">${this.translateKey(optionsArg.labelKey)}</div>
|
|
762
781
|
<span>
|
|
763
|
-
${
|
|
782
|
+
${optionsArg.amountDue === undefined
|
|
783
|
+
? this.translateKey(optionsArg.textKey)
|
|
784
|
+
: html`${this.translateKey("payment.amountDue")}:
|
|
785
|
+
${this.formatPrice(optionsArg.amountDue)}
|
|
786
|
+
${this.translateKey("payment.terms.amountDue")}`}
|
|
764
787
|
${this.formatDay(
|
|
765
788
|
new Date(optionsArg.date).setDate(
|
|
766
789
|
new Date(optionsArg.date).getDate() + optionsArg.dueInDays
|
|
@@ -824,6 +847,115 @@ export class DeContentInvoice extends DeesElement {
|
|
|
824
847
|
</div>`;
|
|
825
848
|
}
|
|
826
849
|
|
|
850
|
+
/**
|
|
851
|
+
* The paid amount and the amount due, below the gross total, when the
|
|
852
|
+
* document states a paid amount (EN 16931 BT-113 and BT-115). The advance
|
|
853
|
+
* payments a final invoice deducts are deducted as the gross total received,
|
|
854
|
+
* with the tax it contains stated per rate, as Abschnitt 14.8 Abs. 7 Satz 3
|
|
855
|
+
* UStAE allows: "Statt der vorausgezahlten Entgelte oder Teilentgelte und
|
|
856
|
+
* der Steuerbeträge können auch die Gesamtbeträge der Voraus- oder
|
|
857
|
+
* Anzahlungen abgesetzt und die darin enthaltenen Steuerbeträge zusätzlich
|
|
858
|
+
* angegeben werden." More paid than the total prints as a credit balance.
|
|
859
|
+
*/
|
|
860
|
+
private renderPaidAmountSums(
|
|
861
|
+
summaryArg: plugins.shared.IPaidAmountSummary
|
|
862
|
+
): TemplateResult {
|
|
863
|
+
return html`<div class="sumline">
|
|
864
|
+
<div class="label">${this.translateKey("payment.paid")}</div>
|
|
865
|
+
<div class="value rightAlign amountCell">
|
|
866
|
+
${this.formatPrice(summaryArg.paidAmount)}
|
|
867
|
+
</div>
|
|
868
|
+
</div>
|
|
869
|
+
${summaryArg.advancePaymentTaxes.map(
|
|
870
|
+
(taxArg) => html`<div class="sumline sumline--contained">
|
|
871
|
+
<div class="label">
|
|
872
|
+
${this.translateKey("advancePayment.vat")} ${taxArg.percentage}%
|
|
873
|
+
</div>
|
|
874
|
+
<div class="value rightAlign amountCell">
|
|
875
|
+
${this.formatPrice(taxArg.vat)}
|
|
876
|
+
</div>
|
|
877
|
+
</div>`
|
|
878
|
+
)}
|
|
879
|
+
<div class="sumline">
|
|
880
|
+
<div class="label">
|
|
881
|
+
${this.translateKey(
|
|
882
|
+
summaryArg.amountDue < 0 ? "payment.creditBalance" : "payment.amountDue"
|
|
883
|
+
)}
|
|
884
|
+
</div>
|
|
885
|
+
<div class="value value--total rightAlign amountCell">
|
|
886
|
+
${this.formatPrice(Math.abs(summaryArg.amountDue))}
|
|
887
|
+
</div>
|
|
888
|
+
</div>`;
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
/**
|
|
892
|
+
* The advance payments the paid amount deducts, one line each, by the
|
|
893
|
+
* advance invoice's number and date and the day the payment was received,
|
|
894
|
+
* as far as the document states them. Each line is its own block, so a long
|
|
895
|
+
* list flows across pages.
|
|
896
|
+
*/
|
|
897
|
+
private renderAdvancePayments(
|
|
898
|
+
summaryArg: plugins.shared.IPaidAmountSummary
|
|
899
|
+
): TemplateResult[] {
|
|
900
|
+
return summaryArg.advancePayments.map(
|
|
901
|
+
(paymentArg) => html`<div class="advancePayment">
|
|
902
|
+
${this.translateKey("advancePayment.title")}${paymentArg.invoice
|
|
903
|
+
? html` ${this.translateKey("advancePayment.invoice")}
|
|
904
|
+
${paymentArg.invoice.documentId}${paymentArg.invoice.issueDate !== undefined
|
|
905
|
+
? html` ${this.translateKey("advancePayment.invoiceDate")}
|
|
906
|
+
${this.formatDay(paymentArg.invoice.issueDate)}`
|
|
907
|
+
: null}`
|
|
908
|
+
: null}${paymentArg.receivedOn !== undefined
|
|
909
|
+
? html`, ${this.translateKey("advancePayment.received")}
|
|
910
|
+
${this.formatDay(paymentArg.receivedOn)}`
|
|
911
|
+
: null}
|
|
912
|
+
</div>`
|
|
913
|
+
);
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
/**
|
|
917
|
+
* What the document asks to be paid: the payment terms and the QR pay box
|
|
918
|
+
* for the gross total, or for the amount due when the document states a
|
|
919
|
+
* paid amount. When nothing is due, it says so, and names the credit
|
|
920
|
+
* balance when more was paid than the total; there are no terms and no QR
|
|
921
|
+
* pay box then.
|
|
922
|
+
*/
|
|
923
|
+
private renderPaymentRequest(
|
|
924
|
+
accountingDocArg: plugins.tsclass.finance.TAccountingDoc,
|
|
925
|
+
summaryArg: plugins.shared.IPaidAmountSummary | null
|
|
926
|
+
): TemplateResult {
|
|
927
|
+
if (summaryArg && summaryArg.amountDue <= 0) {
|
|
928
|
+
return html`<div class="infoBox">
|
|
929
|
+
<div>
|
|
930
|
+
<div>
|
|
931
|
+
<div class="label">${this.translateKey("invoice@@payment.terms")}</div>
|
|
932
|
+
<span>
|
|
933
|
+
${summaryArg.amountDue === 0
|
|
934
|
+
? this.translateKey("payment.nothingDue")
|
|
935
|
+
: html`${this.translateKey("payment.nothingDue.creditBalance")}
|
|
936
|
+
${this.formatPrice(-summaryArg.amountDue)}.`}
|
|
937
|
+
</span>
|
|
938
|
+
</div>
|
|
939
|
+
</div>
|
|
940
|
+
</div>`;
|
|
941
|
+
}
|
|
942
|
+
return html`
|
|
943
|
+
${this.renderPaymentTerms({
|
|
944
|
+
date: accountingDocArg.date,
|
|
945
|
+
dueInDays: accountingDocArg.dueInDays,
|
|
946
|
+
labelKey: "invoice@@payment.terms",
|
|
947
|
+
textKey: "invoice@@payment.terms.direct",
|
|
948
|
+
amountDue: summaryArg?.amountDue,
|
|
949
|
+
})}
|
|
950
|
+
${this.renderPaymentInfo({
|
|
951
|
+
from: accountingDocArg.from,
|
|
952
|
+
currency: accountingDocArg.currency,
|
|
953
|
+
amount: summaryArg ? summaryArg.amountDue : this.getTotalGross(),
|
|
954
|
+
reference: accountingDocArg.id,
|
|
955
|
+
})}
|
|
956
|
+
`;
|
|
957
|
+
}
|
|
958
|
+
|
|
827
959
|
/**
|
|
828
960
|
* The reverse-charge statement. § 14a UStG requires the words
|
|
829
961
|
* "Steuerschuldnerschaft des Leistungsempfängers": Abs. 5 for a domestic
|
|
@@ -1200,6 +1332,10 @@ export class DeContentInvoice extends DeesElement {
|
|
|
1200
1332
|
return;
|
|
1201
1333
|
}
|
|
1202
1334
|
const accountingDoc = this.accountingDoc;
|
|
1335
|
+
// throws when the advance payments do not add up to the paid amount
|
|
1336
|
+
const paidAmountSummary = accountingDoc
|
|
1337
|
+
? plugins.shared.getPaidAmountSummary(accountingDoc, this.getTotalGross())
|
|
1338
|
+
: null;
|
|
1203
1339
|
render(
|
|
1204
1340
|
html`
|
|
1205
1341
|
${this.renderCorrection()}
|
|
@@ -1296,7 +1432,9 @@ export class DeContentInvoice extends DeesElement {
|
|
|
1296
1432
|
${this.formatPrice(this.getTotalGross())}
|
|
1297
1433
|
</div>
|
|
1298
1434
|
</div>
|
|
1435
|
+
${paidAmountSummary ? this.renderPaidAmountSums(paidAmountSummary) : null}
|
|
1299
1436
|
</div>
|
|
1437
|
+
${paidAmountSummary ? this.renderAdvancePayments(paidAmountSummary) : null}
|
|
1300
1438
|
<div class="divider"></div>
|
|
1301
1439
|
|
|
1302
1440
|
${accountingDoc?.reverseCharge ? this.renderReverseChargeNote() : ``}
|
|
@@ -1307,24 +1445,9 @@ export class DeContentInvoice extends DeesElement {
|
|
|
1307
1445
|
<!-- NOTES -->
|
|
1308
1446
|
${this.renderNotes(accountingDoc?.notes)}
|
|
1309
1447
|
|
|
1310
|
-
<!-- PAYMENT TERMS -->
|
|
1311
|
-
${accountingDoc && this.docContent.requestsPayment
|
|
1312
|
-
? this.renderPaymentTerms({
|
|
1313
|
-
date: accountingDoc.date,
|
|
1314
|
-
dueInDays: accountingDoc.dueInDays,
|
|
1315
|
-
labelKey: "invoice@@payment.terms",
|
|
1316
|
-
textKey: "invoice@@payment.terms.direct",
|
|
1317
|
-
})
|
|
1318
|
-
: null}
|
|
1319
|
-
|
|
1320
|
-
<!-- PAYMENT INFO -->
|
|
1448
|
+
<!-- PAYMENT TERMS AND PAYMENT INFO -->
|
|
1321
1449
|
${accountingDoc && this.docContent.requestsPayment
|
|
1322
|
-
? this.
|
|
1323
|
-
from: accountingDoc.from,
|
|
1324
|
-
currency: accountingDoc.currency,
|
|
1325
|
-
amount: this.getTotalGross(),
|
|
1326
|
-
reference: accountingDoc.id,
|
|
1327
|
-
})
|
|
1450
|
+
? this.renderPaymentRequest(accountingDoc, paidAmountSummary)
|
|
1328
1451
|
: null}
|
|
1329
1452
|
`,
|
|
1330
1453
|
contentNodes.currentContent
|
|
@@ -151,6 +151,17 @@ export class DeDocument extends DeesElement {
|
|
|
151
151
|
public paginationInfo: IPagePaginationInfo[] = [];
|
|
152
152
|
|
|
153
153
|
public async renderDocument() {
|
|
154
|
+
// a document whose advance payments do not add up to its paid amount is
|
|
155
|
+
// refused: no page of it, and none of the letter before it, stays on screen
|
|
156
|
+
try {
|
|
157
|
+
plugins.shared.assertPaidAmountMatchesAdvancePayments(this.letterData);
|
|
158
|
+
} catch (error) {
|
|
159
|
+
this.latestDocumentSettings = this.documentSettings;
|
|
160
|
+
this.latestRenderedLetterData = this.letterData;
|
|
161
|
+
this.paginationInfo = [];
|
|
162
|
+
this.shadowRoot?.querySelector(".documentContainer")?.replaceChildren();
|
|
163
|
+
throw error;
|
|
164
|
+
}
|
|
154
165
|
this.latestDocumentSettings = this.documentSettings;
|
|
155
166
|
this.latestRenderedLetterData = this.letterData;
|
|
156
167
|
this.paginationInfo = [];
|