Repository navigation
feat(reports): PDF export for X, Z, daily sales - #1393
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the
|
PR Summary by QodoAdd PDF and date-range exports for X, Z, and daily sales reports
AI Description
Diagram
High-Level Assessment
Files changed (39)
|
Code Review by Qodo
1.
|
…ests/daily-sales-export.test.ts` and `tests/reports-export.test.ts` by unescaping `&` last (after `<`, `>`, `"`, and `'`) in `extractHtmlSummaryMap` and `parseHtmlSummaryMetrics`. Verified with `npx tsx tests/reports-export.test.ts`, `npx tsx tests/daily-sales-export.test.ts`, `npm run lint`, `npm run build`, and `git diff --check`
81234a2 to
9344106
Compare
…` failure (`ci-1`, `github-check-run:123131589299`) in `npm run test:reports-export` (`tests/reports-export.test.ts:1265` and `:1489`). ### Invariant & Root Cause - **Invariant**: PDF report generation (`buildCashCloseReportHtml`, `buildDailySalesReportHtml`) and its real Electron `printToPDF` verification (`extractPdfInfo` / `pdfTextIncludesToken`) must preserve the full multi-script document metadata and verify rendered report tokens across X, Z, and daily-sales exports on every supported platform (macOS, Windows, and headless Linux CI runners with or without optional CJK/Devanagari system fonts). - **Root Cause**: 1. Both PDF HTML templates (`main/services/cash-close-export.ts` and `main/services/daily-sales-export.ts`) only specified generic Latin sans-serif fallbacks (`-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif`) instead of the multi-script system font stack used in `frontend/src/app/globals.css`. 2. On `ubuntu-24.04` GitHub Actions runners (`linux-tests`), `fonts-dejavu-core` and `fonts-liberation` are pre-installed (covering Latin, accented French, Arabic, and currency `₹`), whereas optional CJK and Devanagari system font packages are not pre-installed. When HarfBuzz/FontConfig has no installed font for a character, Chromium's Skia PDF backend maps the character to glyph ID `0` (`.notdef`): the first `.notdef` character/cluster in a font subset is emitted as bare `<0000> Tj` and omitted from `/ToUnicode` (`SkPDFMakeToUnicodeCmap` starts at glyph index `1`), while all subsequent `.notdef` characters in that font subset are emitted via `/Span<</ActualText <FEFF...> >> BDC` (e.g. `'京カフェ'`, `'茶ラテ'`, `'कैफे'`, `'साला चाय'`), and the PDF document metadata dictionary (`/Title <FEFF...>`) always preserves the complete UTF-16BE string (`كافيه النور · 東京カフェ · फ्लो कैफे · Café Élégant <script>alert(1)</script>`). ### Changes 1. Updated the CSS `font-family` fallback stack in `main/services/cash-close-export.ts` and `main/services/daily-sales-export.ts` to include the cross-platform multi-script system fonts (Noto/PingFang/Hiragino/Yu Gothic/Meiryo/Microsoft YaHei/Nirmala UI/Kohinoor). 2. Updated `extractPdfInfo` and added `pdfTextIncludesToken` in `tests/reports-export.test.ts` across all three real Electron `printToPDF` verification blocks (`xPdfInfo`, `zPdfInfo`, `dsPdfInfo`) to decode and assert the full UTF-16BE `/Title` metadata on all three PDFs while matching `/ToUnicode` + `/ActualText` page stream text across both full-font environments and headless Linux runners without CJK/Devanagari system fonts. ### Verification - `npm run test:reports-export` (passed, including real Electron `printToPDF` child-process suite) - `npm run test:daily-sales-export` (248/248 passed) - `npm run lint` (passed, 0 errors) - `npm run build` (passed) - `git diff --check` (clean)
…` failure (`ci-1`, `github-check-run:123144964054`) in `npm run test:reports-export` (`tests/reports-export.test.ts`). ### Invariant & Root Cause - **Invariant**: Headless Electron PDF and layout verification in `tests/reports-export.test.ts` must rely only on deterministic offscreen-safe DOM layout metrics (`executeJavaScript`) and `printToPDF` output, never invoking Viz compositor surface capture (`webContents.capturePage()`) on hidden (`show: false`) windows where X11/Xvfb does not allocate a composited surface. - **Root Cause**: After all X, Z, and daily-sales `printToPDF` assertions succeeded on Linux CI (`ubuntu-24.04` under `xvfb-run`), `verifyHtmlLayoutAndCapturePages` opened a hidden (`show: false`) `BrowserWindow` and called `win.webContents.capturePage()` in a loop to write unused PNG screenshots. On Linux X11/Xvfb, an unmapped (`show: false`) window does not submit frames to the Viz surface, so Electron's `WebContents::CapturePage` callback (`OnCapturePageDone`) receives an empty `SkBitmap` (`bitmap.drawsNothing() === true`) after the ~3.5s Viz copy timeout and rejects with `[Error: UnknownVizError]`. ### Changes - Renamed `verifyHtmlLayoutAndCapturePages` to `verifyHtmlLayout` in `tests/reports-export.test.ts` and removed the `webContents.capturePage()` loop and `FLO_PDF_ARTIFACTS_DIR` artifact-dumping path across all three report layout checks (`xLayout`, `zLayout`, and `dsLayout`), retaining the `executeJavaScript` DOM layout and overflow assertions (`scrollWidth <= clientWidth && overflowingCells === 0`). ### Verification - `npm run test:reports-export` (passed, including real Electron `printToPDF` child-process suite) - `npm run lint` (passed, 0 errors) - `node scripts/ci/check-changed-format.cjs --base 2fa0228` (passed) - `npm run build` (passed) - `git diff --check` (clean)
Fixes #1334
Intent
{"summary": "The developer wanted to align and specify a six-task batch for FloCafe covering routing tests, date-range and PDF sales reports, PIN user switching, payment-method correction, and per-user shifts, and to produce a verified handoff specification covering these decisions and fixes for reproduced defects. For PIN switching, both manual till locking and an optional store-configurable idle auto-lock (disabled by default, with fixed 1, 5, 15, or 30 minute intervals) must preserve the unfinished terminal cart while clearing prior approval and PIN state, rechecking the new user's permissions, and attributing subsequent writes and payment to the newly signed-in user. For payment-method corrections, the developer required supporting cash, card, and active custom tenders while explicitly refusing corrections to or from FloCafe wallet payments. For reporting and accountant exports, daily-sales PDFs must support selected date ranges alongside XLSX and CSV and contain period, daily, payment-method, item, and tax breakdowns (leaving individual payment references to XLSX and CSV), while tax exports must list named taxes separately with labeled shared bases and flag historical records with missing rate or base detail as unknown. Finally, the developer required packaging the work as six separate PRs against main with documented prerequisite order and combined verification, leaving the PRs unmerged after passing tests, review, and CI for later approval."}
What Changed
format=htmlexport support to/api/reports/x-report/export,/api/reports/z-report/export, and/api/reports/daily-sales/exportviaserializeXReportHtml,serializeZReportHtml, andserializeDailySalesExportHtml, producing print-styled HTML documents with regional currency/number formatting, tax breakdowns, and a 15 MB size cap on daily-sales HTML exports, and enabledpreferCSSPageSize: trueinrenderHtmlToPdfBuffer.exportReportAsPdf(frontend/src/lib/export-pdf.ts) and wired localizedPDF (.pdf)export actions (dashboard.exportPdfacross all 24 locales) into the dashboard daily-sales export menu and the X/Z report menus inCashCloseModal, usingwindow.electronAPI.saveHtmlAsPdfon desktop and a gesture-reserved browser print window on web.printToPDFrendering) and updated the API, daily-sales export, and regional-settings documentation.Risk Assessment
✅ Low: The changes cleanly add print-styled HTML serialization (
format=html) and PDF export support for X reports, Z reports, and Daily Sales reports across both desktop (saveHtmlAsPdfIPC with offscreenBrowserWindow.webContents.printToPDFandpreferCSSPageSize: true) and browser print fallbacks. Existing permission boundaries (reports.viewandreports.daily-sales.export), HTML escaping, payload size bounds (MAX_DAILY_SALES_HTML_BYTESmatchingMAX_PDF_HTML_BYTES), popup gesture reservation/cleanup, and regional formatting contracts are properly enforced and covered by unit, integration, and E2E tests.Testing
Ran focused backend, IPC, translation, and real Electron printToPDF suites (
npm run test:reports-export,npm run test:daily-sales-export,tests/printer-ipc.test.ts,npm run test:translations) plus live Chromium Playwright E2E checks (e2e/cash-close-phase1-ui.spec.tsand an interactive browser run covering date-range Daily Sales PDF export and popup-blocked error handling), capturing generated PDFs, rendered report page PNGs, and UI screenshots in the evidence directory; all checks passed.Evidence: Generated Daily Sales date-range PDF via Electron printToPDF
Evidence: Generated X Report PDF via Electron printToPDF
Evidence: Generated Z Report PDF via Electron printToPDF
Evidence: Real Electron printToPDF and layout verification summary
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
✅ **Review** - passed
✅ No issues found.
✅ **Test** - passed
✅ No issues found.
FLO_PDF_ARTIFACTS_DIR=~/.no-mistakes/evidence/01M627TEMQZRV29688GA0TM76X npm run test:reports-exportnpm run test:daily-sales-exportnode tests/run-electron-node-test.cjs tests/printer-ipc.test.tsnpm run test:translationscd frontend && npx playwright test --config=playwright.config.ts --project=chromium e2e/cash-close-phase1-ui.spec.tsLive Chromium + E2E server verification of Dashboard single-day/date-range PDF export, popup-blocked error toast, and Close Day X/Z Report PDF export with screenshot capture✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.