feat: enhance translation and invoice layout

This commit is contained in:
2025-03-24 08:55:27 +00:00
parent 1106b9648d
commit 04e668ff83
20 changed files with 2138 additions and 780 deletions

View File

@@ -5,29 +5,31 @@ import {
customElement,
type TemplateResult,
css,
cssManager,
unsafeCSS,
domtools,
} from '@design.estate/dees-element';
} from "@design.estate/dees-element";
import * as plugins from '../plugins.js';
import { dedocumentSharedStyle } from '../style.js';
import * as plugins from "../plugins.js";
import { dedocumentSharedStyle } from "../style.js";
declare global {
interface HTMLElementTagNameMap {
'dedocument-letterheader': DeLetterHeader;
"dedocument-letterheader": DeLetterHeader;
}
}
@customElement('dedocument-letterheader')
@customElement("dedocument-letterheader")
export class DeLetterHeader extends DeesElement {
public static demo = () => html`
<dedocument-letterheader .format="${'a4'}" .letterData=${plugins.shared.demoLetter}></dedocument-letterheader>
<dedocument-letterheader
.format="${"a4"}"
.letterData=${plugins.shared.demoLetter}
></dedocument-letterheader>
`;
@property({
type: Object,
reflect: true
reflect: true,
})
public letterData: plugins.tsclass.business.ILetter;
@@ -43,6 +45,12 @@ export class DeLetterHeader extends DeesElement {
})
public pageTotalNumber: number = 1;
@property({
type: Object,
reflect: true,
})
public documentSettings: plugins.shared.interfaces.IDocumentSettings;
constructor() {
super();
domtools.DomTools.setupDomTools();
@@ -52,19 +60,29 @@ export class DeLetterHeader extends DeesElement {
domtools.elementBasic.staticStyles,
dedocumentSharedStyle,
css`
:host {
color: #333;
.address {
position: absolute;
top: calc(var(--DPI-FACTOR) * 4.5);
left: var(--LEFT-MARGIN);
}
.date {
position: absolute;
top: calc(var(--DPI-FACTOR) * 4.5);
right: var(--RIGHT-MARGIN);
text-align: right;
}
.recepientInfo {
position: absolute;
display: block;
overflow: hidden;
top: 200px;
right: ${unsafeCSS(plugins.shared.rightMargin + 'px')};
top: calc(var(--DPI-FACTOR) * 5.5);
right: var(--RIGHT-MARGIN);
width: 200px;
text-align: right;
}
.recepientInfo .label {
margin-top: 10px;
margin-bottom: 3px;
@@ -72,19 +90,6 @@ export class DeLetterHeader extends DeesElement {
font-weight: bold;
}
.date {
position: absolute;
top: 180px;
right: ${unsafeCSS(plugins.shared.rightMargin + 'px')};
text-align: right;
}
.address {
position: absolute;
top: 180px;
left: ${unsafeCSS(plugins.shared.leftMargin + 'px')};
}
.address .from {
font-size: 10px;
}
@@ -95,31 +100,97 @@ export class DeLetterHeader extends DeesElement {
`,
];
private renderDeliveryDate(from: Date, to: Date): TemplateResult {
if (this.letterData.type !== "invoice") return null;
const dateFormat = new Intl.DateTimeFormat(
this.documentSettings.languageCode,
{ dateStyle: this.documentSettings.dateStyle }
);
let formattedFrom = from ? dateFormat.format(from) : null;
let formattedTo = to ? dateFormat.format(to) : null;
const isSameDay = formattedFrom === formattedTo;
if (isSameDay) {
return html`<div class="label">
${plugins.shared.translation.translate(
this.documentSettings.languageCode,
"letterhead@@periodOfPerformance.day"
)}
</div>
<span> ${formattedFrom} </span>`;
} else {
return html`<div class="label">
${plugins.shared.translation.translate(
this.documentSettings.languageCode,
"letterhead@@periodOfPerformance.range"
)}
</div>
<span> ${formattedFrom} - ${formattedTo}</span>`;
}
}
public render(): TemplateResult {
return html`
<div class="date">
${new Date(this.letterData.date).getDate()}. ${new Date(this.letterData.date).toLocaleString('default', { month: 'long' })}
${new Date(this.letterData.date).getFullYear()}
${new Intl.DateTimeFormat(this.documentSettings.languageCode, {
dateStyle: "long",
}).format(new Date(this.letterData.date))}
</div>
<div class="address">
<div class="from">
${this.letterData.from.name}, ${this.letterData.from.address.streetName}
${this.letterData.from.address.houseNumber}, ${this.letterData.from.address.postalCode}
${this.letterData.from.address.city}, ${this.letterData.from.address.country}
${this.letterData.from.name},
${this.letterData.from.address.streetName}
${this.letterData.from.address.houseNumber},
${this.letterData.from.address.postalCode}
${this.letterData.from.address.city},
${this.letterData.from.address.country}
</div>
<div class="to">
${this.letterData.to.name}<br />
${this.letterData.to.address.streetName} ${this.letterData.to.address.houseNumber}<br />
${this.letterData.to.address.postalCode} ${this.letterData.to.address.city}<br />
${this.letterData.to.address.streetName}
${this.letterData.to.address.houseNumber}<br />
${this.letterData.to.address.postalCode}
${this.letterData.to.address.city}<br />
${this.letterData.from.address.country}
</div>
</div>
<div class="recepientInfo">
<div class="label">your customer id:</div>
${this.letterData.to.customerNumber || 'not registered'}
<div class="label">
${plugins.shared.translation.translate(
this.documentSettings.languageCode,
"letterhead@@customer.number"
)}
</div>
${this.letterData.to.customerNumber || "not registered"}
<div class="label">your vat id on file:</div>
${this.letterData.to.vatId || 'not provided'}
<div class="label">
${plugins.shared.translation.translate(
this.documentSettings.languageCode,
"letterhead@@vat.yourId"
)}
</div>
${this.letterData.to.vatId || "not provided"}
<!-- TODO: Make use of components -->
${this.letterData.type === "invoice"
? html` <div class="label">
${plugins.shared.translation.translate(
this.documentSettings.languageCode,
"letterhead@@invoice.number"
)}
</div>
${this.letterData.content.invoiceData.id || "not registered"}`
: null}
${this.renderDeliveryDate(
new Date(
this.letterData.content?.invoiceData?.periodOfPerformance?.from
),
new Date(
this.letterData.content?.invoiceData?.periodOfPerformance?.to
)
)}
</div>
`;
}