Skip to content

fix: honor cash drawer setting for cloud print jobs#1171

Open
kilbot wants to merge 7 commits into
mainfrom
feature/cloud-print-cash-drawer
Open

fix: honor cash drawer setting for cloud print jobs#1171
kilbot wants to merge 7 commits into
mainfrom
feature/cloud-print-cash-drawer

Conversation

@kilbot

@kilbot kilbot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Fixes Cloud print (Epson SDP / PrintNode): honor auto-open cash drawer in server-rendered jobs #1169 by persisting autoOpenDrawer / drawerConnector on manual order-based cloud print jobs.
  • Injects provider-correct drawer commands for server-rendered Epson SDP ePOS XML and PrintNode raw ESC/POS jobs, without double-kicking templates that already contain <drawer/>.
  • For PrintNode PDF receipts, submits the PDF first and then sends a best-effort separate raw_base64 drawer-kick job so a drawer failure does not duplicate the receipt.
  • Adds support documentation for cash drawers with cloud printing.

Design decisions (preserve through rebases)

  • Explicit <drawer/> defaults to pin2 / drawer_1 — matches the client-side default pulse behavior; only the auto-injected pulse honors the job drawer_connector.
  • Star providers are intentionally unchanged — Star wire formats need Star drawer commands, not ESC/POS bytes.
  • PrintNode PDF drawer kicks are best-effort after receipt submission — if the raw kick fails, the accepted PDF receipt is still marked printed and the drawer error is recorded.

Companion PRs / cross-repo

Test plan

  • Targeted wp-env PHPUnit: vendor/bin/phpunit -c .phpunit.xml.dist tests/includes/Templates/Thermal/Epos_Xml_Thermal_Emitter_Test.php tests/includes/Templates/Thermal/Escpos_Thermal_Emitter_Test.php tests/includes/Services/Print_Job_Service_Render_Test.php tests/includes/API/Print_Jobs_Controller_Test.php tests/includes/Services/Cloud_Print_Submit_Service_Test.php — OK, 11 tests / 53 assertions.
  • Full PHP suite through wp-env: vendor/bin/phpunit -c .phpunit.xml.dist --verbose --log-junit phpunit.xml — OK, 1477 tests / 6398 assertions, with 6 skipped and 1 incomplete pre-existing documentary test.
  • PHP lint through wp-env: composer run lint — OK, 155 files.
  • Root pnpm run lint checked — repository has no lint script; used composer run lint as the project PHP lint command.

Known blockers

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Added configurable cash drawer auto-opening for cloud print jobs, including support for pin2/pin5.
    • Automatic drawer opening is now applied to PrintNode PDF receipts, using a best-effort drawer “kick” that won’t block printing if it fails.
    • Thermal receipt rendering now injects drawer pulses automatically before the final cut when no explicit drawer command is present.
  • Documentation

    • Updated guidance on cash drawer auto-opening for cloud printing and compatible printer/driver setup.
  • Tests

    • Added coverage for drawer option persistence, provider-specific handling, and auto-injection behavior.

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: wcpos/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: adbba406-5411-42cc-8709-adeab294de03

📥 Commits

Reviewing files that changed from the base of the PR and between 7f2865c and c1e5474.

📒 Files selected for processing (1)
  • includes/Services/Cloud_Print_Trigger_Service.php
🚧 Files skipped from review as they are similar to previous changes (1)
  • includes/Services/Cloud_Print_Trigger_Service.php

📝 Walkthrough

Walkthrough

Adds server-side cash drawer auto-open support for order-based cloud print jobs. Drawer options (autoOpenDrawer, drawerConnector) are extracted from the REST API, persisted in job meta, scoped per-provider (epson-sdp and printnode only), injected as pulses into thermal emitters (ePOS-XML and ESC/POS), and sent as a separate raw ESC/POS drawer-kick job for PrintNode PDF submissions.

Changes

Cash Drawer Auto-Open for Cloud Printing

Layer / File(s) Summary
Print_Job_Service: drawer meta, normalization, render options
includes/Services/Print_Job_Service.php
Adds META_AUTO_OPEN_DRAWER, META_DRAWER_CONNECTOR, META_DRAWER_ERROR constants; persists and reads drawer fields in create()/get(); adds public normalize_drawer_connector() and private drawer_render_options(); updates both Thermal_Renderer::render() call sites to pass drawer options.
Cloud_Print_Trigger_Service: per-provider drawer scoping
includes/Services/Cloud_Print_Trigger_Service.php
enqueue_order_job() gains optional $drawer_options; new drawer_options_for_provider() restricts auto-open/connector to epson-sdp and printnode only; drawer meta is recorded in job payload for both PrintNode and polling paths.
Print_Jobs_Controller: extract and forward drawer options
includes/API/Print_Jobs_Controller.php
create_item() calls new drawer_options_from_request() (supports camelCase/snake_case, sanitizes boolean, normalizes connector); create_order_job() signature extended; enqueue_order_job() call updated to pass drawer options.
Thermal emitters and renderer: options and auto-drawer injection
includes/Templates/Thermal/Thermal_Renderer.php, includes/Templates/Thermal/Escpos_Thermal_Emitter.php, includes/Templates/Thermal/Epos_Xml_Thermal_Emitter.php
Thermal_Renderer::render() gains an $options parameter forwarded to both emitter constructors. Both emitters gain an $options constructor, nodes_with_auto_drawer() injection (splicing a drawer node before trailing cut), nodes_contain_drawer() deduplication, and pulse-emit helpers that normalize connector to pin2/pin5 or drawer_1/drawer_2.
Cloud_Print_Submit_Service: PrintNode PDF drawer-kick
includes/Services/Cloud_Print_Submit_Service.php
After a successful PDF submission, conditionally calls submit_printnode_drawer_kick() when auto_open_drawer is set; kick WP_Error is persisted to META_DRAWER_ERROR and logged without affecting printed status; drawer_kick_bytes() builds pin2/pin5 ESC/POS byte sequences.
Tests: emitters, render service, submit service, controller
tests/includes/Templates/Thermal/Escpos_Thermal_Emitter_Test.php, tests/includes/Templates/Thermal/Epos_Xml_Thermal_Emitter_Test.php, tests/includes/Services/Print_Job_Service_Render_Test.php, tests/includes/Services/Cloud_Print_Submit_Service_Test.php, tests/includes/API/Print_Jobs_Controller_Test.php
Emitter tests verify pulse injection before cut and no duplication of explicit drawer nodes. Render tests assert pulse placement for Epson and PrintNode paths. Submit tests cover dual-request drawer-kick success and failure (PRINTED with drawer error, no retry cron). Controller tests assert options are persisted for Epson SDP and suppressed for Star CloudPRNT.
Documentation
docs/cloud-printing-cash-drawer.md
New doc section describes the server-side limitation, Epson SDP pulse injection behavior, and the PrintNode separate raw ESC/POS drawer-kick approach with printer/driver guidance.

Sequence Diagram(s)

sequenceDiagram
  participant POS_Client
  participant Print_Jobs_Controller
  participant Cloud_Print_Trigger_Service
  participant Print_Job_Service
  participant Thermal_Renderer
  participant Cloud_Print_Submit_Service
  participant PrintNode_Client

  POS_Client->>Print_Jobs_Controller: POST /print-jobs {autoOpenDrawer, drawerConnector}
  Print_Jobs_Controller->>Print_Jobs_Controller: drawer_options_from_request()
  Print_Jobs_Controller->>Cloud_Print_Trigger_Service: enqueue_order_job(..., drawer_options)
  Cloud_Print_Trigger_Service->>Cloud_Print_Trigger_Service: drawer_options_for_provider(provider)
  Cloud_Print_Trigger_Service->>Print_Job_Service: create(job with auto_open_drawer, drawer_connector)

  rect rgba(100, 149, 237, 0.5)
    Note over Print_Job_Service,Thermal_Renderer: Thermal render path (Epson SDP / PrintNode ESC/POS)
    Print_Job_Service->>Print_Job_Service: drawer_render_options(job)
    Print_Job_Service->>Thermal_Renderer: render(template, order, format, options)
    Thermal_Renderer->>Thermal_Renderer: nodes_with_auto_drawer → inject pulse before cut
  end

  rect rgba(144, 238, 144, 0.5)
    Note over Cloud_Print_Submit_Service,PrintNode_Client: PrintNode PDF drawer-kick path
    Cloud_Print_Submit_Service->>PrintNode_Client: submit_job(PDF)
    Cloud_Print_Submit_Service->>PrintNode_Client: submit_job(raw_base64 ESC/POS kick)
    PrintNode_Client-->>Cloud_Print_Submit_Service: kick result (success or WP_Error)
    Cloud_Print_Submit_Service->>Print_Job_Service: mark PRINTED (+ optional META_DRAWER_ERROR)
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

  • #1169 (Cloud print Epson SDP / PrintNode: honor auto-open cash drawer in server-rendered jobs): This PR directly implements all three requirements — transmitting drawer settings to the server via the REST API, injecting <pulse> into ePOS-Print XML for Epson SDP, and submitting a separate raw_base64 ESC/POS drawer-kick job for PrintNode PDF — along with the Star CloudPRNT exclusion and documentation of chosen behavior.

Possibly related PRs

  • wcpos/woocommerce-pos#1092: Both PRs modify the thermal rendering pipeline at the code level—e.g., Print_Job_Service/Cloud_Print_Trigger_Service and especially Thermal_Renderer—so the main PR's drawer-auto-open work is directly layered on top of PR #1092's template-driven thermal rendering changes.
  • wcpos/woocommerce-pos#1106: Both PRs modify includes/Services/Cloud_Print_Trigger_Service.php—specifically enqueue_order_job()—adding provider-aware behavior (main PR adds drawer-options payload/signature + provider scoping; retrieved PR changes enqueue/scheduling logic for non-polling providers like star-online).
  • wcpos/woocommerce-pos#1073: Main PR extends the existing print-jobs enqueue flow (notably Print_Jobs_Controller::create_item and the downstream Print_Job_Service/render path) to persist and inject cash-drawer auto-open options, building directly on the cloud-print queue engine implemented in PR #1073.

Poem

🖨️ The receipt rolls out, crisp and neat,
A pulse kicks the drawer—a satisfying beat.
pin2 or pin5, the connector is known,
ESC/POS bytes to the printer are thrown.
For PDF jobs, a second kick is sent,
And if it fails? The error's just logged, not meant. 🗃️

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely describes the main change: enabling the cash drawer auto-open setting for cloud print jobs.
Linked Issues check ✅ Passed All four objectives from #1169 are met: drawer settings are transmitted to the server [Print_Jobs_Controller.php], appropriate drawer commands are injected for Epson SDP [Epos_Xml_Thermal_Emitter.php], PrintNode PDF submits a separate raw drawer-kick job [Cloud_Print_Submit_Service.php], and provider-specific correctness is enforced via drawer_options_for_provider [Cloud_Print_Trigger_Service.php].
Out of Scope Changes check ✅ Passed All changes are directly aligned with the PR objectives: API changes to transmit drawer settings, emitter updates to inject drawer commands, test coverage for new behavior, and documentation of cloud printing limitations. No unrelated changes detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/cloud-print-cash-drawer

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

github-actions Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

E2E API Test Results

35 tests   35 ✅  3s ⏱️
17 suites   0 💤
 1 files     0 ❌

Results for commit c1e5474.

♻️ This comment has been updated with latest results.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@includes/Services/Cloud_Print_Trigger_Service.php`:
- Around line 160-161: Remove the unnecessary null coalescing operator `??
'pin2'` from the `drawer_connector` assignment in the
Print_Job_Service::normalize_drawer_connector() call. Since
drawer_options_for_provider() already guarantees a non-null drawer_connector
string value, the fallback is unreachable and causes PHPStan static analysis
failures. Apply this fix at both locations where this pattern appears (lines 161
and 184) to simplify the assignment and clear the analysis failure.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: wcpos/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: fcfe8334-1406-4a2d-8ad8-55f36b2893c6

📥 Commits

Reviewing files that changed from the base of the PR and between d3676a7 and 7f2865c.

📒 Files selected for processing (13)
  • docs/cloud-printing-cash-drawer.md
  • includes/API/Print_Jobs_Controller.php
  • includes/Services/Cloud_Print_Submit_Service.php
  • includes/Services/Cloud_Print_Trigger_Service.php
  • includes/Services/Print_Job_Service.php
  • includes/Templates/Thermal/Epos_Xml_Thermal_Emitter.php
  • includes/Templates/Thermal/Escpos_Thermal_Emitter.php
  • includes/Templates/Thermal/Thermal_Renderer.php
  • tests/includes/API/Print_Jobs_Controller_Test.php
  • tests/includes/Services/Cloud_Print_Submit_Service_Test.php
  • tests/includes/Services/Print_Job_Service_Render_Test.php
  • tests/includes/Templates/Thermal/Epos_Xml_Thermal_Emitter_Test.php
  • tests/includes/Templates/Thermal/Escpos_Thermal_Emitter_Test.php

Comment thread includes/Services/Cloud_Print_Trigger_Service.php Outdated

kilbot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor Author

Post-fix triage for dispatch round 2.

Remaining unresolved inline review threads after push: 0.

Thread File Issue Decision Commit
CodeRabbit thread Cloud_Print_Trigger_Service.php PHPStan reported unreachable ?? 'pin2' fallbacks because drawer_options_for_provider() guarantees drawer_connector is present and non-null. Fixed c1e5474

Excluded threads: none.

Validation:

  • composer run phpstan passed: 145/145 files, no errors.
  • composer run lint-report passed: empty checkstyle report.

@github-actions

Copy link
Copy Markdown
Contributor

PHPUnit Test Results

     7 files  ±0     735 suites  ±0   13m 15s ⏱️ - 1m 11s
 1 477 tests ±0   1 470 ✅ ±0   7 💤 ±0  0 ❌ ±0 
10 339 runs  ±0  10 290 ✅ ±0  49 💤 ±0  0 ❌ ±0 

Results for commit c1e5474. ± Comparison against base commit d3676a7.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cloud print (Epson SDP / PrintNode): honor auto-open cash drawer in server-rendered jobs

1 participant