@things-factory/invoice 10.1.227 → 10.1.229
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-client/document/document-form.js +1 -1
- package/dist-client/document/document-form.js.map +1 -1
- package/dist-client/document/document-lines.js +3 -3
- package/dist-client/document/document-lines.js.map +1 -1
- package/dist-client/document/document-party.js +1 -1
- package/dist-client/document/document-party.js.map +1 -1
- package/dist-client/document/document-preview.js +1 -1
- package/dist-client/document/document-preview.js.map +1 -1
- package/dist-client/entity360/invoice-360.js +2 -1
- package/dist-client/entity360/invoice-360.js.map +1 -1
- package/dist-client/pages/invoice-editor.js +3 -3
- package/dist-client/pages/invoice-editor.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/index.js +2 -0
- package/dist-server/index.js.map +1 -1
- package/dist-server/service/invoice/invoice-subject.d.ts +9 -0
- package/dist-server/service/invoice/invoice-subject.js +26 -0
- package/dist-server/service/invoice/invoice-subject.js.map +1 -0
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/dist-shared/document-print.js +1 -1
- package/dist-shared/document-print.js.map +1 -1
- package/package.json +9 -9
- package/shared/document-print.ts +1 -1
- package/translations/en.json +1 -7
- package/translations/es.json +10 -11
- package/translations/ja.json +10 -11
- package/translations/ko.json +1 -7
- package/translations/ms.json +10 -11
- package/translations/zh.json +10 -11
- package/tsconfig.shared.tsbuildinfo +1 -1
|
@@ -50,7 +50,7 @@ function documentBody(document, { language, t: word, title, terms, numberLabel =
|
|
|
50
50
|
/* A table's cells carry numbers; the total carries its currency, as the print's language writes money. */
|
|
51
51
|
const amount = (value) => escape((0, document_money_js_1.documentNumber)(value ?? 0, document.currency, language, true));
|
|
52
52
|
const money = (value) => escape((0, document_money_js_1.documentAmount)(value ?? 0, document.currency, language));
|
|
53
|
-
const kind = (taxKind) => taxKind === 'ZERO_RATED' ? t('text.
|
|
53
|
+
const kind = (taxKind) => taxKind === 'ZERO_RATED' ? t('text.tax-kind-zero-rated') : taxKind === 'EXEMPT' ? t('text.tax-kind-exempt') : t('text.tax-kind-taxable');
|
|
54
54
|
const party = (label, name, address, number) => `<section><h2>${label}</h2><strong>${escape(name)}</strong><p class="text">${escape(address)}</p><p>${escape(number)}</p></section>`;
|
|
55
55
|
return `<div class="sheet">
|
|
56
56
|
<header><h1>${escape(title)}</h1><div><p>${t(numberLabel)}: ${escape(document.number)}</p><p>${t('field.invoice-issue-date')}: ${escape(document.issueDate)}</p>${terms
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document-print.js","sourceRoot":"","sources":["../shared/document-print.ts"],"names":[],"mappings":"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","sourcesContent":["import { documentAmount, documentNumber } from './document-money.js'\n\n/*\n * A commercial document as the buyer reads it - the one layout every print of an invoice or a quotation is, made by\n * the server from the stored document (ADR-0170 decision 10): the preview's page, the PDF to download and what the\n * browser prints are this page. Pure - no i18next: the words come in as a translator of the print's language.\n */\n\nexport type PrintedDocument = Record<string, any>\n\n/** The languages the print has words for - this package's and sales' print words in each (ADR-0170 decision 9). */\nexport const PRINT_LANGUAGES = ['ko', 'en'] as const\nexport type PrintLanguage = (typeof PRINT_LANGUAGES)[number]\n\n/** The language as one the print has words for, or undefined - the caller refuses it or falls back. */\nexport function printLanguageOf(language: unknown): PrintLanguage | undefined {\n return (PRINT_LANGUAGES as readonly unknown[]).includes(language) ? (language as PrintLanguage) : undefined\n}\n\nexport type PrintOptions = {\n /** The language of the print - its words and how it writes money. */\n language: PrintLanguage\n /** The words of the print, in `language`. */\n t: (key: string) => string\n /** The kind's title - 「청구서」, 「견적서」. */\n title: string\n /** The kind's own terms beside the number - the due date; the version and the last day of an offer. */\n terms: { label: string; value?: string | null }[]\n /** How the kind names its number. */\n numberLabel?: string\n}\n\nconst escape = (text: unknown) => String(text ?? '').replace(/[&<>\"']/g, c => ({ '&': '&', '<': '<', '>': '>', '\"': '"', \"'\": ''' })[c]!)\n\n/** The look of the printed page - A4 with its margins. */\nexport const DOCUMENT_CSS = `\n @page{size:A4;margin:18mm}\n body{font:13px/1.5 system-ui,sans-serif;color:#000}\n h1{font-size:26px;margin:0}\n h2{font-size:13px;color:#555;margin:0 0 4px}\n header,.parties{display:flex;justify-content:space-between;gap:32px}\n .parties section{flex:1}\n table{width:100%;border-collapse:collapse;margin:24px 0}\n th,td{padding:8px;border-bottom:1px solid #999;text-align:right;font-variant-numeric:tabular-nums}\n th:first-child,td:first-child{text-align:left}\n .text{white-space:pre-wrap}\n .totals{width:50%;margin-left:auto}\n .grand td{font-weight:600;font-size:15px}\n tr{break-inside:avoid}\n`\n\n/**\n * On a screen, the page as a sheet of A4 on a grey desk with the print's margins - the preview reads as the PDF will.\n * Printing and the PDF read the print media, where none of this applies.\n */\nexport const DOCUMENT_SCREEN_CSS = `\n@media screen {\n html{background:#e9edf1}\n body{margin:0;padding:24px 0}\n .sheet{box-sizing:border-box;width:210mm;min-height:297mm;margin:0 auto;padding:18mm;background:#fff;\n box-shadow:0 1px 3px rgba(23,36,44,.12),0 8px 24px rgba(23,36,44,.08)}\n}\n@media screen and (max-width:210mm) {\n .sheet{width:auto;min-height:0;margin:0 8px;padding:8mm}\n}\n`\n\n/** The document's sheet - the head, the parties, the lines, the totals and the terms - without a page around it. */\nexport function documentBody(document: PrintedDocument, { language, t: word, title, terms, numberLabel = 'field.invoice-number' }: PrintOptions): string {\n const t = (key: string) => escape(word(key))\n /* A table's cells carry numbers; the total carries its currency, as the print's language writes money. */\n const amount = (value: number) => escape(documentNumber(value ?? 0, document.currency, language, true))\n const money = (value: number) => escape(documentAmount(value ?? 0, document.currency, language))\n const kind = (taxKind: string) =>\n taxKind === 'ZERO_RATED' ? t('text.invoice-tax-kind-zero-rated') : taxKind === 'EXEMPT' ? t('text.invoice-tax-kind-exempt') : t('text.invoice-tax-kind-taxable')\n const party = (label: string, name: string, address: string, number: string) =>\n `<section><h2>${label}</h2><strong>${escape(name)}</strong><p class=\"text\">${escape(address)}</p><p>${escape(number)}</p></section>`\n\n return `<div class=\"sheet\">\n <header><h1>${escape(title)}</h1><div><p>${t(numberLabel)}: ${escape(document.number)}</p><p>${t('field.invoice-issue-date')}: ${escape(document.issueDate)}</p>${terms\n .map(one => `<p>${escape(one.label)}: ${escape(one.value)}</p>`)\n .join('')}</div></header>\n <div class=\"parties\">${party(t('field.invoice-supplier-name'), document.supplierName, document.supplierAddress, document.supplierRegistrationNumber)}${party(\n t('field.invoice-buyer-name'),\n document.buyerName,\n document.buyerAddress,\n document.buyerRegistrationNumber\n )}</div>\n ${document.purchaseOrder ? `<p>${t('field.invoice-purchase-order')}: ${escape(document.purchaseOrder)}</p>` : ''}\n <table><thead><tr><th>${t('field.invoice-line-description')}</th><th>${t('field.invoice-quantity')}</th><th>${t('field.invoice-unit')}</th><th>${t('field.invoice-unit-price')}</th><th>${t(\n 'field.invoice-discount'\n )}</th><th>${t('field.invoice-tax-kind')}</th><th>${t('field.invoice-supply-amount')}</th></tr></thead><tbody>${(document.items ?? [])\n .map(\n (item: any) =>\n `<tr><td>${escape(item.description)}</td><td>${escape(item.quantity)}</td><td>${escape(item.unit)}</td><td>${amount(item.unitPrice)}</td><td>${amount(item.discount)}</td><td>${kind(item.taxKind)} ${escape(\n item.taxRate\n )}%</td><td>${amount(item.supplyAmount)}</td></tr>`\n )\n .join('')}</tbody></table>\n <table class=\"totals\"><tbody>${\n Number(document.discountAmount) > 0\n ? `<tr><td>${t('field.invoice-line-sum')}</td><td>${amount(document.lineSupplyAmount)}</td><td></td></tr><tr><td>${t('field.invoice-discount')}</td><td>− ${amount(document.discountAmount)}</td><td></td></tr>`\n : ''\n }${(document.taxGroups ?? [])\n .map((group: any) => `<tr><td>${kind(group.taxKind)} ${escape(group.taxRate)}%</td><td>${amount(group.supplyAmount)}</td><td>${amount(group.taxAmount)}</td></tr>`)\n .join('')}<tr><td>${t('field.invoice-sum')}</td><td>${amount(document.supplyAmount)}</td><td>${amount(document.taxAmount)}</td></tr><tr class=\"grand\"><td colspan=\"2\">${t(\n 'field.invoice-total-amount'\n )}</td><td>${money(document.totalAmount)}</td></tr></tbody></table>\n ${['paymentTerms', 'bankDetails', 'notes']\n .filter(key => document[key])\n .map(key => `<p class=\"text\">${escape(document[key])}</p>`)\n .join('')}\n </div>`\n}\n\n/**\n * The document as one HTML page - what the preview shows and the browser prints. Only escaped business data enters\n * the page.\n */\nexport function documentHtml(document: PrintedDocument, options: PrintOptions): string {\n return `<!doctype html><html lang=\"${options.language}\"><head><meta charset=\"utf-8\"><title>${escape(document.number)}</title><style>${DOCUMENT_CSS}${DOCUMENT_SCREEN_CSS}</style></head><body>${documentBody(\n document,\n options\n )}</body></html>`\n}\n\n/** 「견적서-Q2026-001.pdf」 - the kind's word and the number, without what a file name may not hold. */\nexport function documentFileName(word: string, number: string, extension: 'html' | 'pdf'): string {\n const safe = (text: string) => String(text ?? '').trim().replace(/[\\\\/:*?\"<>|\\s]+/g, '-')\n return `${[safe(word), safe(number)].filter(Boolean).join('-')}.${extension}`\n}\n"]}
|
|
1
|
+
{"version":3,"file":"document-print.js","sourceRoot":"","sources":["../shared/document-print.ts"],"names":[],"mappings":"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","sourcesContent":["import { documentAmount, documentNumber } from './document-money.js'\n\n/*\n * A commercial document as the buyer reads it - the one layout every print of an invoice or a quotation is, made by\n * the server from the stored document (ADR-0170 decision 10): the preview's page, the PDF to download and what the\n * browser prints are this page. Pure - no i18next: the words come in as a translator of the print's language.\n */\n\nexport type PrintedDocument = Record<string, any>\n\n/** The languages the print has words for - this package's and sales' print words in each (ADR-0170 decision 9). */\nexport const PRINT_LANGUAGES = ['ko', 'en'] as const\nexport type PrintLanguage = (typeof PRINT_LANGUAGES)[number]\n\n/** The language as one the print has words for, or undefined - the caller refuses it or falls back. */\nexport function printLanguageOf(language: unknown): PrintLanguage | undefined {\n return (PRINT_LANGUAGES as readonly unknown[]).includes(language) ? (language as PrintLanguage) : undefined\n}\n\nexport type PrintOptions = {\n /** The language of the print - its words and how it writes money. */\n language: PrintLanguage\n /** The words of the print, in `language`. */\n t: (key: string) => string\n /** The kind's title - 「청구서」, 「견적서」. */\n title: string\n /** The kind's own terms beside the number - the due date; the version and the last day of an offer. */\n terms: { label: string; value?: string | null }[]\n /** How the kind names its number. */\n numberLabel?: string\n}\n\nconst escape = (text: unknown) => String(text ?? '').replace(/[&<>\"']/g, c => ({ '&': '&', '<': '<', '>': '>', '\"': '"', \"'\": ''' })[c]!)\n\n/** The look of the printed page - A4 with its margins. */\nexport const DOCUMENT_CSS = `\n @page{size:A4;margin:18mm}\n body{font:13px/1.5 system-ui,sans-serif;color:#000}\n h1{font-size:26px;margin:0}\n h2{font-size:13px;color:#555;margin:0 0 4px}\n header,.parties{display:flex;justify-content:space-between;gap:32px}\n .parties section{flex:1}\n table{width:100%;border-collapse:collapse;margin:24px 0}\n th,td{padding:8px;border-bottom:1px solid #999;text-align:right;font-variant-numeric:tabular-nums}\n th:first-child,td:first-child{text-align:left}\n .text{white-space:pre-wrap}\n .totals{width:50%;margin-left:auto}\n .grand td{font-weight:600;font-size:15px}\n tr{break-inside:avoid}\n`\n\n/**\n * On a screen, the page as a sheet of A4 on a grey desk with the print's margins - the preview reads as the PDF will.\n * Printing and the PDF read the print media, where none of this applies.\n */\nexport const DOCUMENT_SCREEN_CSS = `\n@media screen {\n html{background:#e9edf1}\n body{margin:0;padding:24px 0}\n .sheet{box-sizing:border-box;width:210mm;min-height:297mm;margin:0 auto;padding:18mm;background:#fff;\n box-shadow:0 1px 3px rgba(23,36,44,.12),0 8px 24px rgba(23,36,44,.08)}\n}\n@media screen and (max-width:210mm) {\n .sheet{width:auto;min-height:0;margin:0 8px;padding:8mm}\n}\n`\n\n/** The document's sheet - the head, the parties, the lines, the totals and the terms - without a page around it. */\nexport function documentBody(document: PrintedDocument, { language, t: word, title, terms, numberLabel = 'field.invoice-number' }: PrintOptions): string {\n const t = (key: string) => escape(word(key))\n /* A table's cells carry numbers; the total carries its currency, as the print's language writes money. */\n const amount = (value: number) => escape(documentNumber(value ?? 0, document.currency, language, true))\n const money = (value: number) => escape(documentAmount(value ?? 0, document.currency, language))\n const kind = (taxKind: string) =>\n taxKind === 'ZERO_RATED' ? t('text.tax-kind-zero-rated') : taxKind === 'EXEMPT' ? t('text.tax-kind-exempt') : t('text.tax-kind-taxable')\n const party = (label: string, name: string, address: string, number: string) =>\n `<section><h2>${label}</h2><strong>${escape(name)}</strong><p class=\"text\">${escape(address)}</p><p>${escape(number)}</p></section>`\n\n return `<div class=\"sheet\">\n <header><h1>${escape(title)}</h1><div><p>${t(numberLabel)}: ${escape(document.number)}</p><p>${t('field.invoice-issue-date')}: ${escape(document.issueDate)}</p>${terms\n .map(one => `<p>${escape(one.label)}: ${escape(one.value)}</p>`)\n .join('')}</div></header>\n <div class=\"parties\">${party(t('field.invoice-supplier-name'), document.supplierName, document.supplierAddress, document.supplierRegistrationNumber)}${party(\n t('field.invoice-buyer-name'),\n document.buyerName,\n document.buyerAddress,\n document.buyerRegistrationNumber\n )}</div>\n ${document.purchaseOrder ? `<p>${t('field.invoice-purchase-order')}: ${escape(document.purchaseOrder)}</p>` : ''}\n <table><thead><tr><th>${t('field.invoice-line-description')}</th><th>${t('field.invoice-quantity')}</th><th>${t('field.invoice-unit')}</th><th>${t('field.invoice-unit-price')}</th><th>${t(\n 'field.invoice-discount'\n )}</th><th>${t('field.invoice-tax-kind')}</th><th>${t('field.invoice-supply-amount')}</th></tr></thead><tbody>${(document.items ?? [])\n .map(\n (item: any) =>\n `<tr><td>${escape(item.description)}</td><td>${escape(item.quantity)}</td><td>${escape(item.unit)}</td><td>${amount(item.unitPrice)}</td><td>${amount(item.discount)}</td><td>${kind(item.taxKind)} ${escape(\n item.taxRate\n )}%</td><td>${amount(item.supplyAmount)}</td></tr>`\n )\n .join('')}</tbody></table>\n <table class=\"totals\"><tbody>${\n Number(document.discountAmount) > 0\n ? `<tr><td>${t('field.invoice-line-sum')}</td><td>${amount(document.lineSupplyAmount)}</td><td></td></tr><tr><td>${t('field.invoice-discount')}</td><td>− ${amount(document.discountAmount)}</td><td></td></tr>`\n : ''\n }${(document.taxGroups ?? [])\n .map((group: any) => `<tr><td>${kind(group.taxKind)} ${escape(group.taxRate)}%</td><td>${amount(group.supplyAmount)}</td><td>${amount(group.taxAmount)}</td></tr>`)\n .join('')}<tr><td>${t('field.invoice-sum')}</td><td>${amount(document.supplyAmount)}</td><td>${amount(document.taxAmount)}</td></tr><tr class=\"grand\"><td colspan=\"2\">${t(\n 'field.invoice-total-amount'\n )}</td><td>${money(document.totalAmount)}</td></tr></tbody></table>\n ${['paymentTerms', 'bankDetails', 'notes']\n .filter(key => document[key])\n .map(key => `<p class=\"text\">${escape(document[key])}</p>`)\n .join('')}\n </div>`\n}\n\n/**\n * The document as one HTML page - what the preview shows and the browser prints. Only escaped business data enters\n * the page.\n */\nexport function documentHtml(document: PrintedDocument, options: PrintOptions): string {\n return `<!doctype html><html lang=\"${options.language}\"><head><meta charset=\"utf-8\"><title>${escape(document.number)}</title><style>${DOCUMENT_CSS}${DOCUMENT_SCREEN_CSS}</style></head><body>${documentBody(\n document,\n options\n )}</body></html>`\n}\n\n/** 「견적서-Q2026-001.pdf」 - the kind's word and the number, without what a file name may not hold. */\nexport function documentFileName(word: string, number: string, extension: 'html' | 'pdf'): string {\n const safe = (text: string) => String(text ?? '').trim().replace(/[\\\\/:*?\"<>|\\s]+/g, '-')\n return `${[safe(word), safe(number)].filter(Boolean).join('-')}.${extension}`\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@things-factory/invoice",
|
|
3
|
-
"version": "10.1.
|
|
3
|
+
"version": "10.1.229",
|
|
4
4
|
"main": "dist-server/index.js",
|
|
5
5
|
"browser": "dist-client/index.js",
|
|
6
6
|
"things-factory": true,
|
|
@@ -32,13 +32,13 @@
|
|
|
32
32
|
"@operato/shell": "^10.0.0",
|
|
33
33
|
"@operato/styles": "^10.29.1",
|
|
34
34
|
"@operato/utils": "^10.0.0",
|
|
35
|
-
"@things-factory/ai-assistant": "^10.1.
|
|
36
|
-
"@things-factory/attachment-base": "^10.1.
|
|
37
|
-
"@things-factory/auth-base": "^10.1.
|
|
38
|
-
"@things-factory/biz-base": "^10.1.
|
|
39
|
-
"@things-factory/pdf": "^10.1.
|
|
40
|
-
"@things-factory/setting-base": "^10.1.
|
|
41
|
-
"@things-factory/shell": "^10.1.
|
|
35
|
+
"@things-factory/ai-assistant": "^10.1.229",
|
|
36
|
+
"@things-factory/attachment-base": "^10.1.228",
|
|
37
|
+
"@things-factory/auth-base": "^10.1.228",
|
|
38
|
+
"@things-factory/biz-base": "^10.1.228",
|
|
39
|
+
"@things-factory/pdf": "^10.1.228",
|
|
40
|
+
"@things-factory/setting-base": "^10.1.228",
|
|
41
|
+
"@things-factory/shell": "^10.1.228",
|
|
42
42
|
"graphql-upload": "^15.0.2"
|
|
43
43
|
},
|
|
44
44
|
"publishConfig": {
|
|
@@ -51,5 +51,5 @@
|
|
|
51
51
|
"url": "git+https://github.com/hatiolab/things-factory.git",
|
|
52
52
|
"directory": "packages/invoice"
|
|
53
53
|
},
|
|
54
|
-
"gitHead": "
|
|
54
|
+
"gitHead": "df6361882dc166ef3f8bd54492113253c802f879"
|
|
55
55
|
}
|
package/shared/document-print.ts
CHANGED
|
@@ -72,7 +72,7 @@ export function documentBody(document: PrintedDocument, { language, t: word, tit
|
|
|
72
72
|
const amount = (value: number) => escape(documentNumber(value ?? 0, document.currency, language, true))
|
|
73
73
|
const money = (value: number) => escape(documentAmount(value ?? 0, document.currency, language))
|
|
74
74
|
const kind = (taxKind: string) =>
|
|
75
|
-
taxKind === 'ZERO_RATED' ? t('text.
|
|
75
|
+
taxKind === 'ZERO_RATED' ? t('text.tax-kind-zero-rated') : taxKind === 'EXEMPT' ? t('text.tax-kind-exempt') : t('text.tax-kind-taxable')
|
|
76
76
|
const party = (label: string, name: string, address: string, number: string) =>
|
|
77
77
|
`<section><h2>${label}</h2><strong>${escape(name)}</strong><p class="text">${escape(address)}</p><p>${escape(number)}</p></section>`
|
|
78
78
|
|
package/translations/en.json
CHANGED
|
@@ -41,9 +41,7 @@
|
|
|
41
41
|
"text.invoice-section-files": "Files",
|
|
42
42
|
"button.invoice-counterparty-clear": "Clear",
|
|
43
43
|
"button.invoice-download-pdf": "Download PDF",
|
|
44
|
-
"button.invoice-preview": "Preview",
|
|
45
44
|
"text.invoice-counterparty-search": "Find by name or business number",
|
|
46
|
-
"field.invoice-counterparty": "Counterparty",
|
|
47
45
|
"field.invoice-payment-terms": "Payment terms",
|
|
48
46
|
"field.invoice-purchase-order": "Purchase order",
|
|
49
47
|
"field.invoice-quantity": "Quantity",
|
|
@@ -85,9 +83,6 @@
|
|
|
85
83
|
"text.invoice-status-void": "Void",
|
|
86
84
|
"text.invoice-tax-basis-calculated": "Calculated",
|
|
87
85
|
"text.invoice-tax-basis-received": "As received",
|
|
88
|
-
"text.invoice-tax-kind-exempt": "Exempt",
|
|
89
|
-
"text.invoice-tax-kind-taxable": "Taxable",
|
|
90
|
-
"text.invoice-tax-kind-zero-rated": "Zero-rated",
|
|
91
86
|
"text.invoice-void-confirm": "A voided invoice cannot be restored.",
|
|
92
87
|
"title.invoice": "Invoice",
|
|
93
88
|
"title.invoice-list": "Invoices",
|
|
@@ -118,6 +113,5 @@
|
|
|
118
113
|
"text.invoice-period-last-year": "Last year",
|
|
119
114
|
"text.invoice-period-this-month": "This month",
|
|
120
115
|
"text.invoice-period-this-year": "This year",
|
|
121
|
-
"text.invoice-totals-shown": "Totals on this page (voided left out)"
|
|
122
|
-
"title.invoice-preview": "Preview"
|
|
116
|
+
"text.invoice-totals-shown": "Totals on this page (voided left out)"
|
|
123
117
|
}
|
package/translations/es.json
CHANGED
|
@@ -22,9 +22,7 @@
|
|
|
22
22
|
"error.invoice-counterparty-not-found": "No se encontró la contraparte. Vuelva a cargar y elija de nuevo.",
|
|
23
23
|
"error.invoice-file-not-on-invoice": "Un archivo no está en esta factura. Vuelva a cargar e inténtelo de nuevo.",
|
|
24
24
|
"field.invoice-bank-details": "Datos bancarios",
|
|
25
|
-
"field.invoice-buyer-address": "Dirección del comprador",
|
|
26
25
|
"field.invoice-buyer-name": "Comprador",
|
|
27
|
-
"field.invoice-buyer-registration-number": "Número de registro del comprador",
|
|
28
26
|
"field.invoice-counterpart": "Contraparte",
|
|
29
27
|
"field.invoice-currency": "Moneda",
|
|
30
28
|
"field.invoice-direction": "Tipo de operación",
|
|
@@ -42,11 +40,8 @@
|
|
|
42
40
|
"text.invoice-files-none": "No hay archivos adjuntos.",
|
|
43
41
|
"text.invoice-section-files": "Archivos",
|
|
44
42
|
"button.invoice-counterparty-clear": "Quitar",
|
|
45
|
-
"button.invoice-counterparty-find": "Buscar",
|
|
46
43
|
"button.invoice-download-pdf": "Descargar PDF",
|
|
47
|
-
"button.invoice-preview": "Vista previa",
|
|
48
44
|
"text.invoice-counterparty-search": "Buscar por nombre o número fiscal",
|
|
49
|
-
"field.invoice-counterparty": "Contraparte",
|
|
50
45
|
"field.invoice-payment-terms": "Condiciones de pago",
|
|
51
46
|
"field.invoice-purchase-order": "Pedido de compra",
|
|
52
47
|
"field.invoice-quantity": "Cantidad",
|
|
@@ -55,9 +50,7 @@
|
|
|
55
50
|
"field.invoice-source-reference": "Documento de origen",
|
|
56
51
|
"field.invoice-status": "Estado",
|
|
57
52
|
"field.invoice-sum": "Suma",
|
|
58
|
-
"field.invoice-supplier-address": "Dirección del proveedor",
|
|
59
53
|
"field.invoice-supplier-name": "Proveedor",
|
|
60
|
-
"field.invoice-supplier-registration-number": "Número de registro del proveedor",
|
|
61
54
|
"field.invoice-supply-amount": "Importe del suministro",
|
|
62
55
|
"field.invoice-document-discount": "Descuento total",
|
|
63
56
|
"field.invoice-line-sum": "Total de líneas",
|
|
@@ -89,9 +82,6 @@
|
|
|
89
82
|
"text.invoice-status-void": "Anulada",
|
|
90
83
|
"text.invoice-tax-basis-calculated": "Calculado",
|
|
91
84
|
"text.invoice-tax-basis-received": "Según lo recibido",
|
|
92
|
-
"text.invoice-tax-kind-exempt": "Exento",
|
|
93
|
-
"text.invoice-tax-kind-taxable": "Gravado",
|
|
94
|
-
"text.invoice-tax-kind-zero-rated": "Tipo cero",
|
|
95
85
|
"text.invoice-void-confirm": "Una factura anulada no se puede restaurar.",
|
|
96
86
|
"title.invoice": "Factura",
|
|
97
87
|
"title.invoice-list": "Facturas",
|
|
@@ -114,5 +104,14 @@
|
|
|
114
104
|
"text.invoice-period-this-month": "Este mes",
|
|
115
105
|
"text.invoice-period-this-year": "Este año",
|
|
116
106
|
"text.invoice-totals-shown": "Totales de esta página (sin anuladas)",
|
|
117
|
-
"
|
|
107
|
+
"field.invoice-defaults-payment-days": "días hasta el vencimiento de la factura",
|
|
108
|
+
"field.invoice-defaults-valid-days": "días de validez del presupuesto",
|
|
109
|
+
"field.invoice-party-address": "dirección",
|
|
110
|
+
"field.invoice-party-name": "razón social",
|
|
111
|
+
"field.invoice-party-registration-number": "n.º de registro",
|
|
112
|
+
"task.invoice.defaults-reading.description": "Lee los datos de la empresa con los que empiezan los presupuestos y facturas nuevos: nuestra parte, la cuenta de cobro y las condiciones de pago.",
|
|
113
|
+
"task.invoice.defaults-reading.name": "consultar los valores por defecto de los documentos",
|
|
114
|
+
"text.invoice-counterparty-none": "no se encontró ninguna contraparte",
|
|
115
|
+
"text.invoice-defaults-terms-hint": "Una por línea. La primera son las condiciones de pago de un documento nuevo; las demás se eligen en el documento.",
|
|
116
|
+
"title.invoice-document-defaults": "valores por defecto de presupuestos y facturas"
|
|
118
117
|
}
|
package/translations/ja.json
CHANGED
|
@@ -22,9 +22,7 @@
|
|
|
22
22
|
"error.invoice-counterparty-not-found": "取引先が見つかりません。再読み込みしてから選び直してください。",
|
|
23
23
|
"error.invoice-file-not-on-invoice": "この請求書にないファイルです。再読み込みしてから操作してください。",
|
|
24
24
|
"field.invoice-bank-details": "振込口座",
|
|
25
|
-
"field.invoice-buyer-address": "購入者住所",
|
|
26
25
|
"field.invoice-buyer-name": "購入者",
|
|
27
|
-
"field.invoice-buyer-registration-number": "購入者登録番号",
|
|
28
26
|
"field.invoice-counterpart": "取引先",
|
|
29
27
|
"field.invoice-currency": "通貨",
|
|
30
28
|
"field.invoice-direction": "区分",
|
|
@@ -42,11 +40,8 @@
|
|
|
42
40
|
"text.invoice-files-none": "添付ファイルはありません。",
|
|
43
41
|
"text.invoice-section-files": "添付ファイル",
|
|
44
42
|
"button.invoice-counterparty-clear": "クリア",
|
|
45
|
-
"button.invoice-counterparty-find": "検索",
|
|
46
43
|
"button.invoice-download-pdf": "PDFをダウンロード",
|
|
47
|
-
"button.invoice-preview": "プレビュー",
|
|
48
44
|
"text.invoice-counterparty-search": "名前または事業者番号で検索",
|
|
49
|
-
"field.invoice-counterparty": "取引先",
|
|
50
45
|
"field.invoice-payment-terms": "支払条件",
|
|
51
46
|
"field.invoice-purchase-order": "発注番号",
|
|
52
47
|
"field.invoice-quantity": "数量",
|
|
@@ -55,9 +50,7 @@
|
|
|
55
50
|
"field.invoice-source-reference": "根拠文書",
|
|
56
51
|
"field.invoice-status": "状態",
|
|
57
52
|
"field.invoice-sum": "合計",
|
|
58
|
-
"field.invoice-supplier-address": "供給者住所",
|
|
59
53
|
"field.invoice-supplier-name": "供給者",
|
|
60
|
-
"field.invoice-supplier-registration-number": "供給者登録番号",
|
|
61
54
|
"field.invoice-supply-amount": "供給価額",
|
|
62
55
|
"field.invoice-document-discount": "全体値引き",
|
|
63
56
|
"field.invoice-line-sum": "品目合計",
|
|
@@ -89,9 +82,6 @@
|
|
|
89
82
|
"text.invoice-status-void": "取消",
|
|
90
83
|
"text.invoice-tax-basis-calculated": "合計で計算",
|
|
91
84
|
"text.invoice-tax-basis-received": "受領のまま",
|
|
92
|
-
"text.invoice-tax-kind-exempt": "免税",
|
|
93
|
-
"text.invoice-tax-kind-taxable": "課税",
|
|
94
|
-
"text.invoice-tax-kind-zero-rated": "ゼロ税率",
|
|
95
85
|
"text.invoice-void-confirm": "発行を取り消すと元に戻せません。",
|
|
96
86
|
"title.invoice": "請求書",
|
|
97
87
|
"title.invoice-list": "請求書",
|
|
@@ -114,5 +104,14 @@
|
|
|
114
104
|
"text.invoice-period-this-month": "今月",
|
|
115
105
|
"text.invoice-period-this-year": "今年",
|
|
116
106
|
"text.invoice-totals-shown": "このページの合計(取消を除く)",
|
|
117
|
-
"
|
|
107
|
+
"field.invoice-defaults-payment-days": "支払期限日数",
|
|
108
|
+
"field.invoice-defaults-valid-days": "見積有効日数",
|
|
109
|
+
"field.invoice-party-address": "住所",
|
|
110
|
+
"field.invoice-party-name": "商号",
|
|
111
|
+
"field.invoice-party-registration-number": "登録番号",
|
|
112
|
+
"task.invoice.defaults-reading.description": "新しい見積書・請求書の初期値となる会社の情報(自社、入金口座、支払条件)を読む。",
|
|
113
|
+
"task.invoice.defaults-reading.name": "見積・請求書の初期値の閲覧",
|
|
114
|
+
"text.invoice-counterparty-none": "該当する取引先がありません",
|
|
115
|
+
"text.invoice-defaults-terms-hint": "1行に1つ。最初の行が新しい文書の支払条件になり、残りは文書で選んで入れます。",
|
|
116
|
+
"title.invoice-document-defaults": "見積・請求書の初期値"
|
|
118
117
|
}
|
package/translations/ko.json
CHANGED
|
@@ -41,9 +41,7 @@
|
|
|
41
41
|
"text.invoice-section-files": "첨부 파일",
|
|
42
42
|
"button.invoice-counterparty-clear": "지우기",
|
|
43
43
|
"button.invoice-download-pdf": "PDF로 내려받기",
|
|
44
|
-
"button.invoice-preview": "미리 보기",
|
|
45
44
|
"text.invoice-counterparty-search": "이름이나 사업자번호로 찾기",
|
|
46
|
-
"field.invoice-counterparty": "거래처",
|
|
47
45
|
"field.invoice-payment-terms": "결제 조건",
|
|
48
46
|
"field.invoice-purchase-order": "발주 번호",
|
|
49
47
|
"field.invoice-quantity": "수량",
|
|
@@ -85,9 +83,6 @@
|
|
|
85
83
|
"text.invoice-status-void": "취소",
|
|
86
84
|
"text.invoice-tax-basis-calculated": "합계로 계산",
|
|
87
85
|
"text.invoice-tax-basis-received": "받은 그대로",
|
|
88
|
-
"text.invoice-tax-kind-exempt": "면세",
|
|
89
|
-
"text.invoice-tax-kind-taxable": "과세",
|
|
90
|
-
"text.invoice-tax-kind-zero-rated": "영세율",
|
|
91
86
|
"text.invoice-void-confirm": "발행을 취소하면 되돌릴 수 없습니다.",
|
|
92
87
|
"title.invoice": "청구서",
|
|
93
88
|
"title.invoice-list": "청구서",
|
|
@@ -118,6 +113,5 @@
|
|
|
118
113
|
"text.invoice-period-last-year": "지난해",
|
|
119
114
|
"text.invoice-period-this-month": "이번 달",
|
|
120
115
|
"text.invoice-period-this-year": "올해",
|
|
121
|
-
"text.invoice-totals-shown": "이 페이지 합계(취소 제외)"
|
|
122
|
-
"title.invoice-preview": "미리 보기"
|
|
116
|
+
"text.invoice-totals-shown": "이 페이지 합계(취소 제외)"
|
|
123
117
|
}
|
package/translations/ms.json
CHANGED
|
@@ -22,9 +22,7 @@
|
|
|
22
22
|
"error.invoice-counterparty-not-found": "Pihak berurusan tidak ditemui. Muat semula dan pilih semula.",
|
|
23
23
|
"error.invoice-file-not-on-invoice": "Fail itu tiada pada invois ini. Muat semula dan cuba lagi.",
|
|
24
24
|
"field.invoice-bank-details": "Butiran bank",
|
|
25
|
-
"field.invoice-buyer-address": "Alamat pembeli",
|
|
26
25
|
"field.invoice-buyer-name": "Pembeli",
|
|
27
|
-
"field.invoice-buyer-registration-number": "Nombor pendaftaran pembeli",
|
|
28
26
|
"field.invoice-counterpart": "Pihak berurusan",
|
|
29
27
|
"field.invoice-currency": "Mata wang",
|
|
30
28
|
"field.invoice-direction": "Arah",
|
|
@@ -42,11 +40,8 @@
|
|
|
42
40
|
"text.invoice-files-none": "Tiada fail dilampirkan.",
|
|
43
41
|
"text.invoice-section-files": "Fail",
|
|
44
42
|
"button.invoice-counterparty-clear": "Kosongkan",
|
|
45
|
-
"button.invoice-counterparty-find": "Cari",
|
|
46
43
|
"button.invoice-download-pdf": "Muat turun PDF",
|
|
47
|
-
"button.invoice-preview": "Pratonton",
|
|
48
44
|
"text.invoice-counterparty-search": "Cari mengikut nama atau nombor perniagaan",
|
|
49
|
-
"field.invoice-counterparty": "Pihak berurusan",
|
|
50
45
|
"field.invoice-payment-terms": "Terma pembayaran",
|
|
51
46
|
"field.invoice-purchase-order": "Pesanan belian",
|
|
52
47
|
"field.invoice-quantity": "Kuantiti",
|
|
@@ -55,9 +50,7 @@
|
|
|
55
50
|
"field.invoice-source-reference": "Rujukan sumber",
|
|
56
51
|
"field.invoice-status": "Status",
|
|
57
52
|
"field.invoice-sum": "Jumlah",
|
|
58
|
-
"field.invoice-supplier-address": "Alamat pembekal",
|
|
59
53
|
"field.invoice-supplier-name": "Pembekal",
|
|
60
|
-
"field.invoice-supplier-registration-number": "Nombor pendaftaran pembekal",
|
|
61
54
|
"field.invoice-supply-amount": "Jumlah bekalan",
|
|
62
55
|
"field.invoice-document-discount": "Diskaun keseluruhan",
|
|
63
56
|
"field.invoice-line-sum": "Jumlah baris",
|
|
@@ -89,9 +82,6 @@
|
|
|
89
82
|
"text.invoice-status-void": "Dibatalkan",
|
|
90
83
|
"text.invoice-tax-basis-calculated": "Dikira",
|
|
91
84
|
"text.invoice-tax-basis-received": "Seperti diterima",
|
|
92
|
-
"text.invoice-tax-kind-exempt": "Dikecualikan",
|
|
93
|
-
"text.invoice-tax-kind-taxable": "Bercukai",
|
|
94
|
-
"text.invoice-tax-kind-zero-rated": "Kadar sifar",
|
|
95
85
|
"text.invoice-void-confirm": "Invois yang dibatalkan tidak boleh dipulihkan.",
|
|
96
86
|
"title.invoice": "Invois",
|
|
97
87
|
"title.invoice-list": "Invois",
|
|
@@ -114,5 +104,14 @@
|
|
|
114
104
|
"text.invoice-period-this-month": "Bulan ini",
|
|
115
105
|
"text.invoice-period-this-year": "Tahun ini",
|
|
116
106
|
"text.invoice-totals-shown": "Jumlah halaman ini (tanpa yang dibatalkan)",
|
|
117
|
-
"
|
|
107
|
+
"field.invoice-defaults-payment-days": "hari sehingga invois perlu dibayar",
|
|
108
|
+
"field.invoice-defaults-valid-days": "hari sebut harga sah",
|
|
109
|
+
"field.invoice-party-address": "alamat",
|
|
110
|
+
"field.invoice-party-name": "nama",
|
|
111
|
+
"field.invoice-party-registration-number": "no. pendaftaran",
|
|
112
|
+
"task.invoice.defaults-reading.description": "Membaca maklumat syarikat yang menjadi permulaan sebut harga dan invois baharu - pihak kita, akaun pembayaran dan terma pembayaran.",
|
|
113
|
+
"task.invoice.defaults-reading.name": "membaca nilai lalai dokumen",
|
|
114
|
+
"text.invoice-counterparty-none": "tiada rakan niaga ditemui",
|
|
115
|
+
"text.invoice-defaults-terms-hint": "Satu setiap baris. Baris pertama ialah terma pembayaran dokumen baharu; yang lain dipilih dalam dokumen.",
|
|
116
|
+
"title.invoice-document-defaults": "nilai lalai sebut harga dan invois"
|
|
118
117
|
}
|
package/translations/zh.json
CHANGED
|
@@ -22,9 +22,7 @@
|
|
|
22
22
|
"error.invoice-counterparty-not-found": "找不到该往来单位。请重新加载后再选择。",
|
|
23
23
|
"error.invoice-file-not-on-invoice": "该文件不在此发票上。请重新加载后再试。",
|
|
24
24
|
"field.invoice-bank-details": "收款账户",
|
|
25
|
-
"field.invoice-buyer-address": "购买方地址",
|
|
26
25
|
"field.invoice-buyer-name": "购买方",
|
|
27
|
-
"field.invoice-buyer-registration-number": "购买方登记号",
|
|
28
26
|
"field.invoice-counterpart": "往来单位",
|
|
29
27
|
"field.invoice-currency": "币种",
|
|
30
28
|
"field.invoice-direction": "方向",
|
|
@@ -42,11 +40,8 @@
|
|
|
42
40
|
"text.invoice-files-none": "没有附件。",
|
|
43
41
|
"text.invoice-section-files": "附件",
|
|
44
42
|
"button.invoice-counterparty-clear": "清除",
|
|
45
|
-
"button.invoice-counterparty-find": "查找",
|
|
46
43
|
"button.invoice-download-pdf": "下载 PDF",
|
|
47
|
-
"button.invoice-preview": "预览",
|
|
48
44
|
"text.invoice-counterparty-search": "按名称或营业执照号查找",
|
|
49
|
-
"field.invoice-counterparty": "往来单位",
|
|
50
45
|
"field.invoice-payment-terms": "付款条件",
|
|
51
46
|
"field.invoice-purchase-order": "采购订单号",
|
|
52
47
|
"field.invoice-quantity": "数量",
|
|
@@ -55,9 +50,7 @@
|
|
|
55
50
|
"field.invoice-source-reference": "依据单据",
|
|
56
51
|
"field.invoice-status": "状态",
|
|
57
52
|
"field.invoice-sum": "合计",
|
|
58
|
-
"field.invoice-supplier-address": "销售方地址",
|
|
59
53
|
"field.invoice-supplier-name": "销售方",
|
|
60
|
-
"field.invoice-supplier-registration-number": "销售方登记号",
|
|
61
54
|
"field.invoice-supply-amount": "不含税金额",
|
|
62
55
|
"field.invoice-document-discount": "整单折扣",
|
|
63
56
|
"field.invoice-line-sum": "明细合计",
|
|
@@ -89,9 +82,6 @@
|
|
|
89
82
|
"text.invoice-status-void": "已作废",
|
|
90
83
|
"text.invoice-tax-basis-calculated": "按合计计算",
|
|
91
84
|
"text.invoice-tax-basis-received": "按收到原样",
|
|
92
|
-
"text.invoice-tax-kind-exempt": "免税",
|
|
93
|
-
"text.invoice-tax-kind-taxable": "应税",
|
|
94
|
-
"text.invoice-tax-kind-zero-rated": "零税率",
|
|
95
85
|
"text.invoice-void-confirm": "作废后无法恢复。",
|
|
96
86
|
"title.invoice": "发票",
|
|
97
87
|
"title.invoice-list": "发票",
|
|
@@ -114,5 +104,14 @@
|
|
|
114
104
|
"text.invoice-period-this-month": "本月",
|
|
115
105
|
"text.invoice-period-this-year": "今年",
|
|
116
106
|
"text.invoice-totals-shown": "本页合计(不含已作废)",
|
|
117
|
-
"
|
|
107
|
+
"field.invoice-defaults-payment-days": "付款期限天数",
|
|
108
|
+
"field.invoice-defaults-valid-days": "报价有效天数",
|
|
109
|
+
"field.invoice-party-address": "地址",
|
|
110
|
+
"field.invoice-party-name": "名称",
|
|
111
|
+
"field.invoice-party-registration-number": "登记号",
|
|
112
|
+
"task.invoice.defaults-reading.description": "读取新报价单和发票默认使用的公司信息(本方、收款账户、付款条件)。",
|
|
113
|
+
"task.invoice.defaults-reading.name": "查看报价单和发票默认值",
|
|
114
|
+
"text.invoice-counterparty-none": "未找到往来单位",
|
|
115
|
+
"text.invoice-defaults-terms-hint": "每行一条。第一行是新文档的付款条件,其余可在文档中选择填入。",
|
|
116
|
+
"title.invoice-document-defaults": "报价单和发票默认值"
|
|
118
117
|
}
|