@design.estate/dees-document 3.1.1 → 3.2.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.
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@design.estate/dees-document',
6
- version: '3.1.1',
6
+ version: '3.2.0',
7
7
  description: 'A sophisticated framework for dynamically generating and rendering business documents like invoices with modern web technologies, featuring PDF creation, templating, and automation.'
8
8
  }
@@ -511,15 +511,33 @@ export class DeContentInvoice extends DeesElement {
511
511
  </div>`;
512
512
  }
513
513
 
514
+ /**
515
+ * The QR pay box. It is printed only when the payment has a valid EPC QR
516
+ * code: a euro amount to the sender's IBAN, which a document in another
517
+ * currency or without the sender's IBAN does not have.
518
+ */
514
519
  private renderPaymentInfo(
515
520
  accountingDocArg: plugins.tsclass.finance.TAccountingDoc
516
- ): TemplateResult {
521
+ ): TemplateResult | null {
517
522
  const bic = accountingDocArg.from.sepaConnection?.bic;
518
523
  const name = accountingDocArg.from.name;
519
524
  const iban = accountingDocArg.from.sepaConnection?.iban;
520
525
  const currency = accountingDocArg.currency;
521
526
  const totalGross = this.getTotalGross();
522
527
  const reference = accountingDocArg.id;
528
+ if (
529
+ typeof iban !== "string" ||
530
+ plugins.shared.buildEpcQrPayload({
531
+ bic,
532
+ name,
533
+ iban,
534
+ currency,
535
+ amount: totalGross,
536
+ remittanceInformation: reference,
537
+ }) === null
538
+ ) {
539
+ return null;
540
+ }
523
541
 
524
542
  return html`<div class="infoBox">
525
543
  <div>
@@ -539,6 +557,26 @@ export class DeContentInvoice extends DeesElement {
539
557
  </div>`;
540
558
  }
541
559
 
560
+ /**
561
+ * The reverse-charge statement. § 14a UStG requires the words
562
+ * "Steuerschuldnerschaft des Leistungsempfängers": Abs. 5 for a domestic
563
+ * supply whose recipient owes the tax under § 13b, Abs. 1 for a supply in
564
+ * another member state whose recipient owes the tax there, such as a
565
+ * business-to-business service under Art. 196 of the VAT Directive. They are
566
+ * printed on every reverse-charge document, and a document in another language adds its own
567
+ * line, in English "Reverse charge", the words of Art. 226 Nr. 11a of the VAT
568
+ * Directive (2006/112/EC).
569
+ */
570
+ private renderReverseChargeNote(): TemplateResult {
571
+ const localizedLine = this.translateKey("invoice@@vat.reverseCharge.note");
572
+ return html`<div class="taxNote">
573
+ <div>${plugins.shared.translation.REVERSE_CHARGE_STATUTORY_PHRASE_DE}</div>
574
+ ${localizedLine === plugins.shared.translation.REVERSE_CHARGE_STATUTORY_PHRASE_DE
575
+ ? null
576
+ : html`<div>${localizedLine}</div>`}
577
+ </div>`;
578
+ }
579
+
542
580
  /** The earlier documents a correction answers, by number and, when known, by date. */
543
581
  private renderRelatedDocuments(): TemplateResult | null {
544
582
  const relatedDocuments = this.accountingDoc?.relatedDocuments;
@@ -699,11 +737,7 @@ export class DeContentInvoice extends DeesElement {
699
737
  </div>
700
738
  <div class="divider"></div>
701
739
 
702
- ${accountingDoc?.reverseCharge
703
- ? html`<div class="taxNote">
704
- ${this.translateKey("invoice@@vat.reverseCharge.note")}
705
- </div>`
706
- : ``}
740
+ ${accountingDoc?.reverseCharge ? this.renderReverseChargeNote() : ``}
707
741
 
708
742
  <!-- REFERENCED CONTRACT -->
709
743
  ${this.renderReferencedContract()}
@@ -53,25 +53,34 @@ export class DedocumentPaymentCode extends DeesElement {
53
53
  @property()
54
54
  accessor reference!: string;
55
55
 
56
+ /** The EPC QR code content, or null when the payment has no valid code (see buildEpcQrPayload). */
57
+ private get payload(): string | null {
58
+ if (
59
+ typeof this.name !== "string" ||
60
+ typeof this.iban !== "string" ||
61
+ typeof this.currency !== "string" ||
62
+ typeof this.totalGross !== "number" ||
63
+ typeof this.reference !== "string"
64
+ ) {
65
+ return null;
66
+ }
67
+ return plugins.shared.buildEpcQrPayload({
68
+ bic: typeof this.bic === "string" ? this.bic : undefined,
69
+ name: this.name,
70
+ iban: this.iban,
71
+ currency: this.currency,
72
+ amount: this.totalGross,
73
+ remittanceInformation: this.reference,
74
+ });
75
+ }
76
+
56
77
  private updateQRCode(): void {
57
- if (!this.canvasEl) return;
78
+ const payload = this.payload;
79
+ if (!this.canvasEl || payload === null) return;
58
80
 
59
- plugins.qrcode.toCanvas(
60
- this.canvasEl,
61
- `BCD
62
- 001
63
- 1
64
- SCT
65
- ${this.bic}
66
- ${this.name}
67
- ${this.iban}
68
- ${this.currency}${this.totalGross?.toFixed?.(2)}
69
-
70
- ${this.reference}`,
71
- (error) => {
72
- if (error) console.error(error);
73
- }
74
- );
81
+ plugins.qrcode.toCanvas(this.canvasEl, payload, (error) => {
82
+ if (error) console.error(error);
83
+ });
75
84
  }
76
85
 
77
86
  public override update(
@@ -82,14 +91,6 @@ ${this.reference}`,
82
91
  }
83
92
 
84
93
  public render(): TemplateResult | null {
85
- const allDataAvailable =
86
- typeof this.bic === "string" &&
87
- typeof this.name === "string" &&
88
- typeof this.iban === "string" &&
89
- typeof this.currency === "string" &&
90
- typeof this.totalGross === "number" &&
91
- typeof this.reference === "string";
92
-
93
- return allDataAvailable ? html`<canvas></canvas>` : null;
94
+ return this.payload === null ? null : html`<canvas></canvas>`;
94
95
  }
95
96
  }