diff --git a/README.md b/README.md index 87f88af..6b66cbb 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,36 @@ Sometimes you may want to set your next invoice number (for instance when you ha Protip: After setting change, you can always go to `Templates` to see a preview with your next invoice number. +## Translation + +With version 0.8.0 we introduced translations for documents. You can now configure language for generated documents. + +**_NOTE:_** We do not support (yet) translations of frontend. + +You can configure language of documents using `medusa-config.js` file. Here is the example of Polish language: +```js +const plugins = [ + // ... other plugins + { + resolve: `@rsc-labs/medusa-documents`, + options: { + enableUI: true, + documentLanguage: 'pl' + } + } +] +``` + +### How to add my own translations? + +You have two options: + +- create `translation.json` under `/assets/i18n/locales/{your-language}` and create a pull requests - we will be more than happy to merge it + +- create `translation.json` only for local purposes. Then you need to go to `node_modules/@rsc-labs/medusa-documents/assets/i18n/locales/{your-language}` and paste there your translation file. + +Please remember that `documentLanguage` in `medusa-config.js` needs to be equal to `{your-language}`. + ## Q&A ### What means "We do not store documents"? diff --git a/package.json b/package.json index b5c9b1f..5e7dfd2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@rsc-labs/medusa-documents", - "version": "0.7.2", + "version": "0.8.0", "description": "Generate documents from Medusa", "main": "dist/index.js", "author": "RSC Labs (https://rsoftcon.com)", @@ -19,10 +19,11 @@ ], "scripts": { "clean": "cross-env ./node_modules/.bin/rimraf dist", + "copy-assets": "cp -rv src/assets dist/assets", "build": "cross-env npm run clean && npm run build:server && npm run build:admin", "build:server": "cross-env npm run clean && tsc -p tsconfig.json", "build:admin": "cross-env medusa-admin build", - "prepare": "cross-env NODE_ENV=production npm run build:server && medusa-admin bundle" + "prepare": "cross-env NODE_ENV=production npm run build:server && npm run copy-assets && medusa-admin bundle" }, "dependencies": { "@medusajs/admin": "7.1.14", @@ -39,7 +40,8 @@ "@emotion/styled": "11.11.5", "lodash": "4.17.21", "pdfkit": "0.15.0", - "moment": "^2.30.1" + "moment": "^2.30.1", + "i18next": "23.11.4" }, "devDependencies": { "@babel/cli": "^7.14.3", diff --git a/src/assets/fonts/IBMPlexSans-Bold.ttf b/src/assets/fonts/IBMPlexSans-Bold.ttf new file mode 100644 index 0000000..e5389d8 Binary files /dev/null and b/src/assets/fonts/IBMPlexSans-Bold.ttf differ diff --git a/src/assets/fonts/IBMPlexSans-Regular.ttf b/src/assets/fonts/IBMPlexSans-Regular.ttf new file mode 100644 index 0000000..b581964 Binary files /dev/null and b/src/assets/fonts/IBMPlexSans-Regular.ttf differ diff --git a/src/assets/i18n/locales/en/translation.json b/src/assets/i18n/locales/en/translation.json new file mode 100644 index 0000000..082969f --- /dev/null +++ b/src/assets/i18n/locales/en/translation.json @@ -0,0 +1,26 @@ +{ + "invoice": "Invoice", + "invoice-number": "Invoice number", + "invoice-date": "Invoice date", + "invoice-customer-details": "Details", + "invoice-bill-to": "Bill to", + "invoice-ship-to": "Ship to", + "invoice-table-header-item": "Item", + "invoice-table-header-description": "Description", + "invoice-table-header-unit-cost": "Unit Cost", + "invoice-table-header-quantity": "Quantity", + "invoice-table-header-line-total": "Line Total", + "invoice-table-shipping": "Shipping", + "invoice-table-tax": "Tax", + "invoice-table-total": "Total", + "packing-slip": "Packing Slip", + "packing-slip-bill-to": "Bill to", + "packing-slip-ship-to": "Ship to", + "packing-slip-table-header-order-number": "Order #", + "packing-slip-table-header-order-date": "Order date", + "packing-slip-table-header-shipping-method": "Shipping method", + "packing-slip-table-header-item": "Item", + "packing-slip-table-header-description": "Description", + "packing-slip-table-header-quantity": "Quantity", + "packing-slip-table-header-total": "Total" +} \ No newline at end of file diff --git a/src/assets/i18n/locales/pl/translation.json b/src/assets/i18n/locales/pl/translation.json new file mode 100644 index 0000000..b4c990f --- /dev/null +++ b/src/assets/i18n/locales/pl/translation.json @@ -0,0 +1,26 @@ +{ + "invoice": "Faktura", + "invoice-number": "Numer faktury", + "invoice-date": "Data faktury", + "invoice-customer-details": "Dane klienta", + "invoice-bill-to": "Nabywca", + "invoice-ship-to": "Wysyłka do", + "invoice-table-header-item": "Produkt", + "invoice-table-header-description": "Opis", + "invoice-table-header-unit-cost": "Cena jedn.", + "invoice-table-header-quantity": "Ilość", + "invoice-table-header-line-total": "Wartość", + "invoice-table-shipping": "Wysyłka", + "invoice-table-tax": "Podatek", + "invoice-table-total": "Suma", + "packing-slip": "List przewozowy", + "packing-slip-bill-to": "Nabywca", + "packing-slip-ship-to": "Wysyłka do", + "packing-slip-table-header-order-number": "Zamówienie nr", + "packing-slip-table-header-order-date": "Data zamówienia", + "packing-slip-table-header-shipping-method": "Metoda wysyłki", + "packing-slip-table-header-item": "Produkt", + "packing-slip-table-header-description": "Opis", + "packing-slip-table-header-quantity": "Ilość", + "packing-slip-table-header-total": "Suma" +} \ No newline at end of file diff --git a/src/loaders/i18next.ts b/src/loaders/i18next.ts new file mode 100644 index 0000000..906fea7 --- /dev/null +++ b/src/loaders/i18next.ts @@ -0,0 +1,58 @@ +import { + ConfigModule, + MedusaContainer, +} from "@medusajs/medusa" + +import i18next from 'i18next'; +import path from "path"; + +export default async ( + container: MedusaContainer, + config: ConfigModule +): Promise => { + console.info("Starting i18next loader...") + + try { + const defaultTranslationsPath = path.resolve(__dirname, `../assets/i18n/locales/en/translation.json`); + const defaultTranslations = await import(defaultTranslationsPath); + + await i18next + .init({ + fallbackLng: 'en', + defaultNS: 'translation', + ns: 'translation', + resources: { + en: { + translation: defaultTranslations + } + } + }).catch((error) => { + console.error(error); + }); + + } catch (error) { + console.error('Error initializing i18next:', error); + } + + + try { + const configLanguage = config['documentLanguage']; + if (configLanguage === undefined) { + console.info('Language is not configured, using "en" by default.') + } else { + console.info(`Language is configured as ${configLanguage}`) + const translationPath = path.resolve(__dirname, `../assets/i18n/locales/${configLanguage}/translation.json`); + const translations = await import(translationPath); + i18next.addResourceBundle( + configLanguage, + 'translation', + translations + ) + i18next.changeLanguage(configLanguage); + } + } catch { + console.error('Error adding language configured in config. Fallback to "en"'); + } + + console.info("Ending i18next loader...") +} \ No newline at end of file diff --git a/src/services/templates/invoices/basic/basic-logo.tsx b/src/services/templates/invoices/basic/basic-logo.ts similarity index 86% rename from src/services/templates/invoices/basic/basic-logo.tsx rename to src/services/templates/invoices/basic/basic-logo.ts index f416707..cf9063e 100644 --- a/src/services/templates/invoices/basic/basic-logo.tsx +++ b/src/services/templates/invoices/basic/basic-logo.ts @@ -19,6 +19,7 @@ import { generateInvoiceTable } from "./parts/table"; import { generateInvoiceInformation } from "./parts/invoice-info"; import { generateHeaderForLogo } from "./parts/header-for-logo"; import { generateHeaderLogo } from "./parts/header-logo"; +import path from "path"; export function validateInput(settings?: DocumentSettings) : ([boolean, string]) { if (settings && settings.store_address && settings.store_address.company && @@ -32,18 +33,22 @@ export function validateInput(settings?: DocumentSettings) : ([boolean, string]) export default async (settings: DocumentSettings, invoice: Invoice, order: Order): Promise => { var doc = new PDFDocument(); + doc.registerFont('Regular', path.resolve(__dirname, '../../../../assets/fonts/IBMPlexSans-Regular.ttf')) + doc.registerFont('Bold', path.resolve(__dirname, '../../../../assets/fonts/IBMPlexSans-Bold.ttf')) + doc.font('Regular'); + + const buffers = [] + doc.on("data", buffers.push.bind(buffers)) + const endHeader = generateHeaderForLogo(doc, 50, settings); await generateHeaderLogo(doc, 50, settings.store_logo_source); const endInvoice = generateInvoiceInformation(doc, endHeader, invoice); const endDetails = generateCustomerInformation(doc, endInvoice, order); generateInvoiceTable(doc, endDetails, order, order.items); - // end and display the document in the iframe to the right doc.end(); const bufferPromise = new Promise(resolve => { - const buffers = [] - doc.on("data", buffers.push.bind(buffers)) doc.on("end", () => { const pdfData = Buffer.concat(buffers) resolve(pdfData) diff --git a/src/services/templates/invoices/basic/basic.tsx b/src/services/templates/invoices/basic/basic.ts similarity index 85% rename from src/services/templates/invoices/basic/basic.tsx rename to src/services/templates/invoices/basic/basic.ts index 9d0f20a..b24f1a0 100644 --- a/src/services/templates/invoices/basic/basic.tsx +++ b/src/services/templates/invoices/basic/basic.ts @@ -18,6 +18,7 @@ import { generateHeader } from "./parts/header"; import { generateCustomerInformation } from "./parts/customer-info"; import { generateInvoiceTable } from "./parts/table"; import { generateInvoiceInformation } from "./parts/invoice-info"; +import path from "path"; export function validateInput(settings?: DocumentSettings) : ([boolean, string]) { if (settings && settings.store_address && settings.store_address.company && @@ -30,6 +31,13 @@ export function validateInput(settings?: DocumentSettings) : ([boolean, string]) export default async (settings: DocumentSettings, invoice: Invoice, order: Order): Promise => { var doc = new PDFDocument(); + doc.registerFont('Regular', path.resolve(__dirname, '../../../../assets/fonts/IBMPlexSans-Regular.ttf')) + doc.registerFont('Bold', path.resolve(__dirname, '../../../../assets/fonts/IBMPlexSans-Bold.ttf')) + doc.font('Regular'); + + const buffers = [] + doc.on("data", buffers.push.bind(buffers)) + const endHeader = generateHeader(doc, 50, settings); const endInvoiceInfo = generateInvoiceInformation(doc, endHeader, invoice); const endY = generateCustomerInformation(doc, endInvoiceInfo, order); @@ -38,13 +46,11 @@ export default async (settings: DocumentSettings, invoice: Invoice, order: Order doc.end(); const bufferPromise = new Promise(resolve => { - const buffers = [] - doc.on("data", buffers.push.bind(buffers)) doc.on("end", () => { const pdfData = Buffer.concat(buffers) resolve(pdfData) }) }) - + return await bufferPromise; }; \ No newline at end of file diff --git a/src/services/templates/invoices/basic/parts/customer-info.ts b/src/services/templates/invoices/basic/parts/customer-info.ts index e7691f1..4568753 100644 --- a/src/services/templates/invoices/basic/parts/customer-info.ts +++ b/src/services/templates/invoices/basic/parts/customer-info.ts @@ -12,12 +12,13 @@ import { Order } from "@medusajs/medusa"; import { generateHr } from "./hr"; +import { t } from "i18next"; export function generateCustomerInformation(doc, y, order: Order) { doc .fillColor("#444444") .fontSize(20) - .text("Details", 50, y + 30); + .text(`${t("invoice-customer-details", "Details")}`, 50, y + 30); generateHr(doc, y + 55); @@ -25,9 +26,10 @@ export function generateCustomerInformation(doc, y, order: Order) { doc .fontSize(10) - .font("Helvetica-Bold") - .text('Bill to:', 50, customerInformationTop, {align: 'left'}) - .font("Helvetica") + .font("Bold") + + .text(`${t("invoice-bill-to", "Bill to")}:`, 50, customerInformationTop, {align: 'left'}) + .font("Regular") .text(`${order.billing_address.first_name} ${order.billing_address.last_name}`, 50, customerInformationTop + 15, {align: 'left'}) .text(`${order.billing_address.city} ${order.billing_address.postal_code}`, 50, customerInformationTop + 30, {align: 'left'}) const billAddress = order.billing_address.address_1; @@ -37,9 +39,9 @@ export function generateCustomerInformation(doc, y, order: Order) { doc .fontSize(10) - .font("Helvetica-Bold") - .text('Ship to:', 50, customerInformationTop, {align: 'right'}) - .font("Helvetica") + .font("Bold") + .text(`${t("invoice-ship-to", "Ship to")}:`, 50, customerInformationTop, {align: 'right'}) + .font("Regular") .text(`${order.shipping_address.first_name} ${order.shipping_address.last_name}`, 50, customerInformationTop + 15, {align: 'right'}) .text(`${order.shipping_address.city} ${order.shipping_address.postal_code}`, 50, customerInformationTop + 30, {align: 'right'}) .moveDown(); diff --git a/src/services/templates/invoices/basic/parts/invoice-info.ts b/src/services/templates/invoices/basic/parts/invoice-info.ts index c9f2275..fa84fd5 100644 --- a/src/services/templates/invoices/basic/parts/invoice-info.ts +++ b/src/services/templates/invoices/basic/parts/invoice-info.ts @@ -12,12 +12,13 @@ import { Invoice } from "../../../../../models/invoice"; import { generateHr } from "./hr"; +import { t } from "i18next"; export function generateInvoiceInformation(doc, y: number, invoice: Invoice) : number { doc .fillColor("#444444") .fontSize(20) - .text("Invoice", 50, y + 40); + .text(t("invoice", "Invoice"), 50, y + 40); generateHr(doc, y + 65); @@ -25,11 +26,11 @@ export function generateInvoiceInformation(doc, y: number, invoice: Invoice) : n doc .fontSize(10) - .text("Invoice Number:", 50, invoiceInformationTop) - .font("Helvetica-Bold") + .text(`${t("invoice-number", "Invoice number")}:`, 50, invoiceInformationTop) + .font("Bold") .text(invoice.display_number, 150, invoiceInformationTop) - .font("Helvetica") - .text("Invoice Date:", 50, invoiceInformationTop + 15) + .font("Regular") + .text(`${t("invoice-date", "Invoice date")}:`, 50, invoiceInformationTop + 15) .text(invoice.created_at.toLocaleDateString(), 150, invoiceInformationTop + 15) .moveDown(); diff --git a/src/services/templates/invoices/basic/parts/table.ts b/src/services/templates/invoices/basic/parts/table.ts index 74dc8d1..669edce 100644 --- a/src/services/templates/invoices/basic/parts/table.ts +++ b/src/services/templates/invoices/basic/parts/table.ts @@ -13,6 +13,7 @@ import { LineItem, Order } from "@medusajs/medusa"; import { generateHr } from "./hr"; import { getDecimalDigits } from "../../../../utils/currency"; +import { t } from "i18next"; function amountToDisplay(amount: number, currencyCode: string) : string { const decimalDigits = getDecimalDigits(currencyCode); @@ -41,18 +42,18 @@ export function generateInvoiceTable(doc, y, order: Order, items: LineItem[]) { let i; const invoiceTableTop = y + 35; - doc.font("Helvetica-Bold"); + doc.font("Bold"); generateTableRow( doc, invoiceTableTop, - "Item", - "Description", - "Unit Cost", - "Quantity", - "Line Total" + t("invoice-table-header-item", "Item"), + t("invoice-table-header-description", "Description"), + t("invoice-table-header-unit-cost", "Unit Cost"), + t("invoice-table-header-quantity", "Quantity"), + t("invoice-table-header-line-total", "Line Total") ); generateHr(doc, invoiceTableTop + 20); - doc.font("Helvetica"); + doc.font("Regular"); for (i = 0; i < items.length; i++) { const item = items[i]; @@ -76,7 +77,7 @@ export function generateInvoiceTable(doc, y, order: Order, items: LineItem[]) { subtotalPosition, "", "", - "Shipping", + t("invoice-table-shipping", "Shipping"), "", amountToDisplay(order.shipping_total, order.currency_code) ); @@ -87,21 +88,21 @@ export function generateInvoiceTable(doc, y, order: Order, items: LineItem[]) { taxPosition, "", "", - "Tax", + t("invoice-table-tax", "Tax"), "", amountToDisplay(order.tax_total, order.currency_code) ); const duePosition = taxPosition + 45; - doc.font("Helvetica-Bold"); + doc.font("Bold"); generateTableRow( doc, duePosition, "", "", - "Total", + t("invoice-table-total", "Total"), "", amountToDisplay(order.total, order.currency_code) ); - doc.font("Helvetica"); + doc.font("Regular"); } \ No newline at end of file diff --git a/src/services/templates/packing-slips/basic/basic.ts b/src/services/templates/packing-slips/basic/basic.ts index dcd580a..33e5eb7 100644 --- a/src/services/templates/packing-slips/basic/basic.ts +++ b/src/services/templates/packing-slips/basic/basic.ts @@ -18,6 +18,7 @@ import { generateHeader } from "./parts/header" import { generateCustomerInformation } from "./parts/customer-info"; import { generateItemsTable } from "./parts/table-items"; import { generateOrderInfoTable } from "./parts/table-order-info"; +import path from "path"; export function validateInput(settings?: DocumentSettings) : ([boolean, string]) { if (settings && settings.store_address && settings.store_address.company && @@ -28,8 +29,16 @@ export function validateInput(settings?: DocumentSettings) : ([boolean, string]) return [false, `Not all settings are defined to generate template. Following settings are checked: company, address, city, postal_code`]; } -export default async (settings: DocumentSettings, packingSlip: PackingSlip, order: Order): Promise => { +export default async (settings: DocumentSettings, packingSlip: PackingSlip, order: Order): Promise => { + var doc = new PDFDocument(); + doc.registerFont('Regular', path.resolve(__dirname, '../../../../assets/fonts/IBMPlexSans-Regular.ttf')) + doc.registerFont('Bold', path.resolve(__dirname, '../../../../assets/fonts/IBMPlexSans-Bold.ttf')) + doc.font('Regular'); + + const buffers = [] + doc.on("data", buffers.push.bind(buffers)) + const endHeader = generateHeader(doc, 30, settings); const endY = generateCustomerInformation(doc, endHeader, order); const endTable = generateOrderInfoTable(doc, endY, order, order.items); @@ -38,8 +47,6 @@ export default async (settings: DocumentSettings, packingSlip: PackingSlip, orde doc.end(); const bufferPromise = new Promise(resolve => { - const buffers = [] - doc.on("data", buffers.push.bind(buffers)) doc.on("end", () => { const pdfData = Buffer.concat(buffers) resolve(pdfData) diff --git a/src/services/templates/packing-slips/basic/parts/customer-info-small.ts b/src/services/templates/packing-slips/basic/parts/customer-info-small.ts index 7f4f501..7df13b7 100644 --- a/src/services/templates/packing-slips/basic/parts/customer-info-small.ts +++ b/src/services/templates/packing-slips/basic/parts/customer-info-small.ts @@ -11,7 +11,8 @@ */ import { Order } from "@medusajs/medusa"; -import { generateHr, generateHrInA7 } from "./hr"; +import { generateHrInA7 } from "./hr"; +import { t } from "i18next"; export function generateCustomerInformation(doc, y, order: Order) { @@ -21,9 +22,9 @@ export function generateCustomerInformation(doc, y, order: Order) { doc .fontSize(6) - .font("Helvetica-Bold") - .text('Bill to:', 25, customerInformationTop, {align: 'left'}) - .font("Helvetica") + .font("Bold") + .text(`${t("packing-slip-bill-to", "Bill to")}:`, 25, customerInformationTop, {align: 'left'}) + .font("Regular") .text(`${order.billing_address.first_name} ${order.billing_address.last_name}`, 25, customerInformationTop + 10, {align: 'left'}) .text(`${order.billing_address.city} ${order.billing_address.postal_code}`, 25, customerInformationTop + 20, {align: 'left'}) const billAddress = order.billing_address.address_1; @@ -35,11 +36,11 @@ export function generateCustomerInformation(doc, y, order: Order) { const RIGHT_WIDTH = 100; doc .fontSize(6) - .font("Helvetica-Bold") + .font("Bold") doc - .text('Ship to:', RIGHT_MARGIN, customerInformationTop, {align: 'right', width: RIGHT_WIDTH}) - .font("Helvetica") + .text(`${t("packing-slip-ship-to", "Ship to")}:`, RIGHT_MARGIN, customerInformationTop, {align: 'right', width: RIGHT_WIDTH}) + .font("Regular") doc .text(`${order.shipping_address.first_name} ${order.shipping_address.last_name}`, RIGHT_MARGIN, customerInformationTop + 10, {align: 'right', width: RIGHT_WIDTH}) diff --git a/src/services/templates/packing-slips/basic/parts/customer-info.ts b/src/services/templates/packing-slips/basic/parts/customer-info.ts index fb53cf2..912e039 100644 --- a/src/services/templates/packing-slips/basic/parts/customer-info.ts +++ b/src/services/templates/packing-slips/basic/parts/customer-info.ts @@ -12,6 +12,7 @@ import { Order } from "@medusajs/medusa"; import { generateHr } from "./hr"; +import { t } from "i18next"; export function generateCustomerInformation(doc, y, order: Order) { @@ -21,9 +22,9 @@ export function generateCustomerInformation(doc, y, order: Order) { doc .fontSize(10) - .font("Helvetica-Bold") - .text('Bill to:', 50, customerInformationTop, {align: 'left'}) - .font("Helvetica") + .font("Bold") + .text(`${t("packing-slip-bill-to", "Bill to")}:`, 50, customerInformationTop, {align: 'left'}) + .font("Regular") .text(`${order.billing_address.first_name} ${order.billing_address.last_name}`, 50, customerInformationTop + 15, {align: 'left'}) .text(`${order.billing_address.city} ${order.billing_address.postal_code}`, 50, customerInformationTop + 30, {align: 'left'}) const billAddress = order.billing_address.address_1; @@ -33,9 +34,9 @@ export function generateCustomerInformation(doc, y, order: Order) { doc .fontSize(10) - .font("Helvetica-Bold") - .text('Ship to:', 50, customerInformationTop, {align: 'right'}) - .font("Helvetica") + .font("Bold") + .text(`${t("packing-slip-ship-to", "Ship to")}:`, 50, customerInformationTop, {align: 'right'}) + .font("Regular") .text(`${order.shipping_address.first_name} ${order.shipping_address.last_name}`, 50, customerInformationTop + 15, {align: 'right'}) .text(`${order.shipping_address.city} ${order.shipping_address.postal_code}`, 50, customerInformationTop + 30, {align: 'right'}) .moveDown(); diff --git a/src/services/templates/packing-slips/basic/parts/header-small.ts b/src/services/templates/packing-slips/basic/parts/header-small.ts index 852ce50..50412a2 100644 --- a/src/services/templates/packing-slips/basic/parts/header-small.ts +++ b/src/services/templates/packing-slips/basic/parts/header-small.ts @@ -11,6 +11,7 @@ */ import { DocumentSettings } from "../../../../../models/document-settings"; +import { t } from "i18next"; export function generateHeader(doc, y: number, documentSettings: DocumentSettings) : number { doc @@ -18,7 +19,7 @@ export function generateHeader(doc, y: number, documentSettings: DocumentSetting .fontSize(12) doc - .text('Packing Slip', 25, y, { align: "left" }) + .text(t("packing-slip", "Packing Slip"), 25, y, { align: "left" }) const heightCompany = doc.heightOfString(documentSettings.store_address.company, { align: "left" }); doc diff --git a/src/services/templates/packing-slips/basic/parts/header.ts b/src/services/templates/packing-slips/basic/parts/header.ts index cee9f10..f34f223 100644 --- a/src/services/templates/packing-slips/basic/parts/header.ts +++ b/src/services/templates/packing-slips/basic/parts/header.ts @@ -11,6 +11,7 @@ */ import { DocumentSettings } from "../../../../../models/document-settings"; +import { t } from "i18next"; export function generateHeader(doc, y: number, documentSettings: DocumentSettings) : number { doc @@ -18,7 +19,7 @@ export function generateHeader(doc, y: number, documentSettings: DocumentSetting .fontSize(20) doc - .text('Packing Slip', 50, y, { align: "left" }) + .text(t("packing-slip", "Packing Slip"), 50, y, { align: "left" }) const heightCompany = doc.heightOfString(documentSettings.store_address.company, { align: "left" }); doc diff --git a/src/services/templates/packing-slips/basic/parts/table-items-small.ts b/src/services/templates/packing-slips/basic/parts/table-items-small.ts index e921466..212cbb0 100644 --- a/src/services/templates/packing-slips/basic/parts/table-items-small.ts +++ b/src/services/templates/packing-slips/basic/parts/table-items-small.ts @@ -12,6 +12,7 @@ import { LineItem, Order } from "@medusajs/medusa"; import { generateHrInA7 } from "./hr"; +import { t } from "i18next"; function generateTableRow( doc, @@ -33,16 +34,16 @@ export function generateItemsTable(doc, y, order: Order, items: LineItem[]) { let totalQuantity = 0; - doc.font("Helvetica-Bold"); + doc.font("Bold"); generateTableRow( doc, invoiceTableTop, - "Item", - "Description", - "Quantity", + t("packing-slip-table-header-item", "Item"), + t("packing-slip-table-header-description", "Description"), + t("packing-slip-table-header-quantity", "Quantity"), ); generateHrInA7(doc, invoiceTableTop + 10); - doc.font("Helvetica"); + doc.font("Regular"); for (i = 0; i < items.length; i++) { const item = items[i]; @@ -60,13 +61,13 @@ export function generateItemsTable(doc, y, order: Order, items: LineItem[]) { } const totalQuantityPosition = invoiceTableTop + (i + 1) * 20; - doc.font("Helvetica-Bold"); + doc.font("Bold"); generateTableRow( doc, totalQuantityPosition, "", - "Total", + t("packing-slip-table-header-total", "Total"), totalQuantity ); - doc.font("Helvetica"); + doc.font("Regular"); } \ No newline at end of file diff --git a/src/services/templates/packing-slips/basic/parts/table-items.ts b/src/services/templates/packing-slips/basic/parts/table-items.ts index 1448af3..a547f76 100644 --- a/src/services/templates/packing-slips/basic/parts/table-items.ts +++ b/src/services/templates/packing-slips/basic/parts/table-items.ts @@ -12,6 +12,7 @@ import { LineItem, Order } from "@medusajs/medusa"; import { generateHr } from "./hr"; +import { t } from "i18next"; function generateTableRow( doc, @@ -33,16 +34,16 @@ export function generateItemsTable(doc, y, order: Order, items: LineItem[]) { let totalQuantity = 0; - doc.font("Helvetica-Bold"); + doc.font("Bold"); generateTableRow( doc, invoiceTableTop, - "Item", - "Description", - "Quantity", + t("packing-slip-table-header-item", "Item"), + t("packing-slip-table-header-description", "Description"), + t("packing-slip-table-header-quantity", "Quantity"), ); generateHr(doc, invoiceTableTop + 20); - doc.font("Helvetica"); + doc.font("Regular"); for (i = 0; i < items.length; i++) { const item = items[i]; @@ -60,13 +61,13 @@ export function generateItemsTable(doc, y, order: Order, items: LineItem[]) { } const totalQuantityPosition = invoiceTableTop + (i + 1) * 30; - doc.font("Helvetica-Bold"); + doc.font("Bold"); generateTableRow( doc, totalQuantityPosition, "", - "Total", + t("packing-slip-table-header-total", "Total"), totalQuantity ); - doc.font("Helvetica"); + doc.font("Regular"); } \ No newline at end of file diff --git a/src/services/templates/packing-slips/basic/parts/table-order-info-small.ts b/src/services/templates/packing-slips/basic/parts/table-order-info-small.ts index 7caedf7..6cc8481 100644 --- a/src/services/templates/packing-slips/basic/parts/table-order-info-small.ts +++ b/src/services/templates/packing-slips/basic/parts/table-order-info-small.ts @@ -12,6 +12,7 @@ import { LineItem, Order } from "@medusajs/medusa"; import { generateHrInA7 } from "./hr"; +import { t } from "i18next"; function generateTableRow( doc, @@ -30,16 +31,16 @@ function generateTableRow( export function generateOrderInfoTable(doc, y, order: Order, items: LineItem[]) : number { const invoiceTableTop = y + 25; - doc.font("Helvetica-Bold"); + doc.font("Bold"); generateTableRow( doc, invoiceTableTop, - "Order #", - "Order date", - "Shipping method", + t("packing-slip-table-header-order-number", "Order #"), + t("packing-slip-table-header-order-date", "Order date"), + t("packing-slip-table-header-shipping-method", "Shipping method"), ); generateHrInA7(doc, invoiceTableTop + 10); - doc.font("Helvetica"); + doc.font("Regular"); const position = invoiceTableTop + 20; diff --git a/src/services/templates/packing-slips/basic/parts/table-order-info.ts b/src/services/templates/packing-slips/basic/parts/table-order-info.ts index 2a207c1..8384393 100644 --- a/src/services/templates/packing-slips/basic/parts/table-order-info.ts +++ b/src/services/templates/packing-slips/basic/parts/table-order-info.ts @@ -12,6 +12,7 @@ import { LineItem, Order } from "@medusajs/medusa"; import { generateHr } from "./hr"; +import { t } from "i18next"; function generateTableRow( doc, @@ -31,16 +32,16 @@ export function generateOrderInfoTable(doc, y, order: Order, items: LineItem[]) let i; const invoiceTableTop = y + 35; - doc.font("Helvetica-Bold"); + doc.font("Bold"); generateTableRow( doc, invoiceTableTop, - "Order #", - "Order date", - "Shipping method", + t("packing-slip-table-header-order-number", "Order #"), + t("packing-slip-table-header-order-date", "Order date"), + t("packing-slip-table-header-shipping-method", "Shipping method"), ); generateHr(doc, invoiceTableTop + 20); - doc.font("Helvetica"); + doc.font("Regular"); const position = invoiceTableTop + 30; diff --git a/src/services/templates/packing-slips/basic/small.ts b/src/services/templates/packing-slips/basic/small.ts index 9e23446..2e5c205 100644 --- a/src/services/templates/packing-slips/basic/small.ts +++ b/src/services/templates/packing-slips/basic/small.ts @@ -18,6 +18,8 @@ import { generateHeader } from "./parts/header-small" import { generateCustomerInformation } from "./parts/customer-info-small"; import { generateItemsTable } from "./parts/table-items-small"; import { generateOrderInfoTable } from "./parts/table-order-info-small"; +import path from "path"; + export function validateInput(settings?: DocumentSettings) : ([boolean, string]) { if (settings && settings.store_address && settings.store_address.company && @@ -30,6 +32,13 @@ export function validateInput(settings?: DocumentSettings) : ([boolean, string]) export default async (settings: DocumentSettings, packingSlip: PackingSlip, order: Order): Promise => { var doc = new PDFDocument({size: 'A7'}); + doc.registerFont('Regular', path.resolve(__dirname, '../../../../assets/fonts/IBMPlexSans-Regular.ttf')) + doc.registerFont('Bold', path.resolve(__dirname, '../../../../assets/fonts/IBMPlexSans-Bold.ttf')) + doc.font('Regular'); + + const buffers = [] + doc.on("data", buffers.push.bind(buffers)) + const endHeader = generateHeader(doc, 30, settings); const endY = generateCustomerInformation(doc, endHeader, order); const endTable = generateOrderInfoTable(doc, endY, order, order.items); @@ -39,8 +48,6 @@ export default async (settings: DocumentSettings, packingSlip: PackingSlip, orde doc.end(); const bufferPromise = new Promise(resolve => { - const buffers = [] - doc.on("data", buffers.push.bind(buffers)) doc.on("end", () => { const pdfData = Buffer.concat(buffers) resolve(pdfData)