Skip to main content

Background PDF print

Menu: all PDF print actions (Sales, Purchase, Receipt, Quote, Report → PDF, and similar)

PDF documents are generated in a background worker instead of inside the web server request. Staff still click Print or PDF as before; a short wait spinner appears, then the PDF opens in a new tab.

Heavy PDF rendering (PagedJs / Node) used to hold Apache workers and could slow the whole admin for other users. Background print keeps the browser responsive and frees web workers for normal page loads.

What staff see​

  1. Click Print Mini, Print Large, PDF, or any print action that exports PDF.
  2. A progress indicator appears while the document is prepared.
  3. When ready, the PDF opens in a new browser tab (same as before).
  4. If generation fails, an alert explains the error—try Print again.

There is no change to print layouts, report names, or which buttons appear on each screen.

Special features​

  • Same UX — print buttons and PDF content are unchanged; only the generation path moved off Apache.
  • All PDF reports — sales mini/large, purchase mini/large, receipt, quote, sales return, and Report module PDF exports use the same queue when enabled on the server.
  • Fresh data on every print — each Print click creates a new job that reads the current database state (important after confirm payment or invoice changes).
  • XLSX unchanged — Excel exports from reports still download directly (not queued).
  • Audit log — each print job is recorded in the report_pdf_job table (who, which report, when, success/fail).

Workflows​

Sales and purchase documents are often printed before order confirm, then again after confirm when invoice codes and status change.

Steps

  1. Save the sale or purchase and print (ORDER / mini) if needed — PDF reflects data at that moment.
  2. Confirm payment or confirm the document when your process requires it.
  3. Print again — the new PDF is built from live data, not a cached file from the first print.
  4. Compare ORDER#, status, invoice code, and totals on the second PDF against the confirmed record.

Report module PDF export​

Steps

  1. Open Report from the top menu.
  2. Choose a report, click Show Report, set filters.
  3. Click PDF — a short “Generating PDF…” page may appear, then the file opens.
  4. Re-run with new filters anytime; each export is a new generation.

Validation rules​

RuleDetail
Print type reportsRequire a record_id (open sale, purchase, receipt, etc.)
Re-print after editsAlways click Print again; do not rely on an old browser tab
Confirmed vs draftPDF always matches DB at generation time — confirm before final customer copy if your policy requires it
Failed jobCheck alert message; retry Print; ask admin if failures repeat
XLSXNot affected by background PDF queue

Operations (server)​

Summary for administrators deploying or troubleshooting BAWAS.

Architecture​

Browser → enqueue job (report_pdf_job) → CLI worker → PagedJs PDF → temp file
← poll status ←────────────────────────────────────────────┘
Browser → download PDF → delete temp file (regenerate if file missing on retry)
ComponentPurpose
report_pdf_jobJob queue and audit log (pending → processing → ready / failed)
bin/report-pdf-worker.phpCLI entry point; runs outside Apache
media/temp/pdf-jobs/Short-lived PDF files (not deployed by rsync; created on server)
cp-log/report-pdf-worker.logWorker stdout/stderr

Configuration (admin/lib/config.php)​

SettingRole
cp.report.asyncPdfEnabledMaster switch (true on UAT/production)
cp.report.asyncPdfExcludeOptional list of report names to keep synchronous
cp.report.asyncPdfPhpBinPHP binary for worker (e.g. /opt/remi/php81/root/bin/php)
cp.report.asyncPdfHttpHostHost passed to worker bootstrap

File lifecycle​

  • PDF is deleted after it is successfully served to the browser (disk cleanup).
  • If the file is gone but the job is still ready, the next open regenerates from current DB params (same record_id).
  • Database rows in report_pdf_job are kept as a log; only files are removed.

Deploy checklist​

  • Run Doctrine migration for report_pdf_job.
  • CI post-deploy: mkdir -p media/temp/pdf-jobs, chmod +x bin/report-pdf-worker.php.
  • Gulp rebuilds admin/js/app.min.js on deploy (async polling lives in general-util-service.js).
  • Verify Node / PagedJs paths in cp.report.pdfLibPath for the worker environment.

Troubleshooting​

SymptomCheck
Spinner never finishesreport_pdf_job row status; cp-log/report-pdf-worker.log
“Could not create PDF job directory”media/temp/pdf-jobs exists and is writable
Wrong data on PDFRe-print after confirm; do not reuse an old download URL from history
PHP warnings in logWorker sets REQUEST_URI / QUERY_STRING for CLI bootstrap