@softwear/latestcollectioncore 1.0.188 → 1.0.189

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@softwear/latestcollectioncore",
3
- "version": "1.0.188",
3
+ "version": "1.0.189",
4
4
  "description": "Core functions for LatestCollections applications",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/reports.ts CHANGED
@@ -32,6 +32,12 @@ export interface PdfImageAsset {
32
32
  export interface GenPdfOptions {
33
33
  onAlert?: (alert: GenPdfAlert) => void
34
34
  translate?: (key: string) => string
35
+ /**
36
+ * Called for layout fields with `format: 'currency'`. Receives the raw string from `source` (e.g. `"123.45"`).
37
+ * Return the exact string to draw. Callers normally pass a closure created next to `genPDF` so it can read
38
+ * `printBuffer`, tenant currency, locale, etc. If omitted, defaults to a euro prefix plus two decimals (`€ 123.45`).
39
+ */
40
+ formatCurrency?: (rawAmountString: string) => string
35
41
  resolveLogoUrl?: () => string | undefined
36
42
  isCustomPdfFont?: (fontFamily: string) => boolean
37
43
  getPdfFontDefinition?: (fontFamily: string) => PdfFontDefinition | undefined
@@ -353,7 +359,10 @@ function drawSimpleObject(x: number, y: number, doc: jsPDF, object: LayoutObject
353
359
  options.onAlert?.({ header: 'fieldnotfound', body: object.source, type: 'warning', timeout: 10000 })
354
360
  text = ''
355
361
  }
356
- if (object.format == 'currency') text = String.fromCharCode(128) + ' ' + parseFloat(text).toFixed(2)
362
+ if (object.format == 'currency') {
363
+ const raw = text
364
+ text = options.formatCurrency ? options.formatCurrency(raw) : '€ ' + parseFloat(raw).toFixed(2)
365
+ }
357
366
  }
358
367
  // Manipulate case as specified in object
359
368
  if ((object.type === 'text' || object.type === 'field') && object.case === 1) text = text.toUpperCase()
@@ -586,12 +595,7 @@ addObjectToPDF = function (
586
595
  const layoutYtenths = originY + object.y
587
596
  const rawPrintOnlyAtStartOffset = printOnlyAtStartContainersOffset ?? 0
588
597
  /** Must consult current page on every read: `addPage` can move to page 2+ mid-invocation while this call stays open. */
589
- const effectivePrintOnlyAtStartContainersOffsetNow = (): number =>
590
- containerChain.length === 0 &&
591
- rawPrintOnlyAtStartOffset > 0 &&
592
- getCurrentPageNumber(doc, context) === 1
593
- ? rawPrintOnlyAtStartOffset
594
- : 0
598
+ const effectivePrintOnlyAtStartContainersOffsetNow = (): number => (containerChain.length === 0 && rawPrintOnlyAtStartOffset > 0 && getCurrentPageNumber(doc, context) === 1 ? rawPrintOnlyAtStartOffset : 0)
595
599
 
596
600
  const x = layoutXtenths / 10
597
601
  const y = (layoutYtenths + effectivePrintOnlyAtStartContainersOffsetNow()) / 10
@@ -331,4 +331,62 @@ describe('genPDF', () => {
331
331
  expect(chromeMatches?.length ?? 0).toBeGreaterThanOrEqual(doc.getNumberOfPages())
332
332
  expect(pdfText).toContain('SKU_20')
333
333
  })
334
+
335
+ it('uses GenPdfOptions.formatCurrency for currency fields when provided', async () => {
336
+ const layout: Layout = {
337
+ name: 'currency-inject',
338
+ paperSize: { width: 210, height: 297, footerHeight: 20 },
339
+ objects: [
340
+ {
341
+ type: 'field' as const,
342
+ name: 'amount',
343
+ x: 20,
344
+ y: 20,
345
+ width: 500,
346
+ height: 50,
347
+ active: true,
348
+ source: 'amount',
349
+ format: 'currency' as const,
350
+ textAlign: 1 as const,
351
+ fontFamily: 'Helvetica',
352
+ fontSize: 32,
353
+ fontStyle: 0,
354
+ },
355
+ ],
356
+ }
357
+ const printBuffer = { amount: '99.5', currency: 'USD' }
358
+ const doc = await genPDF(layout, printBuffer, {
359
+ formatCurrency: (raw) => `USD ${raw} BUF:${printBuffer.currency}`,
360
+ })
361
+ const pdfText = Buffer.from(doc.output('arraybuffer')).toString('latin1')
362
+ expect(pdfText).toContain('USD 99.5 BUF:USD')
363
+ })
364
+
365
+ it('defaults currency fields to euro-style prefix when formatCurrency is omitted', async () => {
366
+ const layout: Layout = {
367
+ name: 'currency-default',
368
+ paperSize: { width: 210, height: 297, footerHeight: 20 },
369
+ objects: [
370
+ {
371
+ type: 'field' as const,
372
+ name: 'amount',
373
+ x: 20,
374
+ y: 20,
375
+ width: 500,
376
+ height: 50,
377
+ active: true,
378
+ source: 'amount',
379
+ format: 'currency' as const,
380
+ textAlign: 1 as const,
381
+ fontFamily: 'Helvetica',
382
+ fontSize: 32,
383
+ fontStyle: 0,
384
+ },
385
+ ],
386
+ }
387
+ const doc = await genPDF(layout, { amount: '10' })
388
+ const pdfText = Buffer.from(doc.output('arraybuffer')).toString('latin1')
389
+ // jsPDF encodes U+20AC as WinAnsi 0x80 in the text operator; still one glyph before digits.
390
+ expect(pdfText).toMatch(/\(\s*.\s*10\.00\) Tj/)
391
+ })
334
392
  })