Skip to content

feat: combined waiter delta KOT slip printing#129

Draft
anwar-shihab wants to merge 3 commits into
ury-erp:developfrom
anwar-shihab:feature/waiter-delta-kot-print
Draft

feat: combined waiter delta KOT slip printing#129
anwar-shihab wants to merge 3 commits into
ury-erp:developfrom
anwar-shihab:feature/waiter-delta-kot-print

Conversation

@anwar-shihab

@anwar-shihab anwar-shihab commented Jun 18, 2026

Copy link
Copy Markdown

Summary

Adds room-level waiter printing for dine-in orders. Each time an order is saved and KOTs are generated via kot_execute, the system prints one combined waiter slip containing only the delta items from that save (new/changed quantities + cancellations). The slip is not a full POS Invoice copy, does not include prices, and is not split by production unit.

Waiter slips now show old -> new quantity for existing items (including full cancel to 0), and a single quantity for first-time additions.

Kitchen KOT printing remains unchanged — still one slip per production unit on URY KOT.on_submit.


Problem

Waiters need a single, readable slip per order update showing what changed since the last save. Previously there was no dedicated waiter print path that:

  • Printed only delta items (not the full bill)
  • Combined items across multiple production-unit KOTs into one slip
  • Included cancellations on the same slip
  • Showed old vs new quantity for reordered items
  • Was configurable per room/printer

Solution Overview

POS order save
    └── kot_execute()
            ├── process_items_for_kot()        → KOT-1, KOT-2 (per production unit)
            ├── process_items_for_cancel_kot() → CNCL-1
            └── print_combined_waiter_order_slip()
                    └── build_combined_kot_doc([KOT-1, KOT-2, CNCL-1])
                            ├── _aggregate_kot_items()
                            ├── _enrich_item_display_fields()  → old_qty / new_qty / display_mode
                            └── print_by_server("URY KOT", doc=combined_doc)
                                    → 1 waiter slip to room printer(s)

Quantity Display Behaviour

Scenario Waiter slip qty display
First-time add Single qty (e.g. 3)
Existing item qty increase Old -> new (e.g. 3 -> 5)
Existing item qty decrease Old -> new (e.g. 10 -> 7)
Full cancel Old -> 0 (e.g. 10 -> 0)

Implementation Details

1. Custom fields — URY Printer Settings

Field Type Purpose
custom_waiter_print Check Enable waiter slip printing for this room printer
custom_waiter_print_format Link → Print Format Format used for waiter slip (site-managed or app default)

Exported via hooks.py fixtures. After merge, run bench migrate on each site.

2. Module — ury_waiter_print.py

build_combined_kot_doc(kot_names)

  • Loads all KOT documents created in the current kot_execute call
  • Copies the first KOT as the base combined document
  • Attaches waiter from the linked POS Invoice
  • Merges kot_items via _aggregate_kot_items():
    • Add lines (New Order, Order Modified): aggregate by (item, comments), sum quantity
    • Cancel lines (Partially cancelled, Cancelled): aggregate by (item, comments), sum cancelled_qty
  • Enriches rows via _enrich_item_display_fields() with display_mode, old_qty, new_qty
  • Returns a single in-memory URY KOT document (not saved to DB)

print_combined_waiter_order_slip(invoice_id, kot_names, restaurant_table)

  • Eligibility guards (silent skip unless config error):
    • No invoice / no KOT names
    • No table or takeaway table (URY Table.is_take_away)
    • No restaurant_room on table
    • No printers with custom_waiter_print = 1 in that room
    • Combined doc has no kot_items
  • Print format validation (logs to Error Log, skips printer):
    • Format must be set, must exist, and doc_type must be URY KOT
  • Print call: print_by_server("URY KOT", kot_names[0], printer, format, doc=combined_doc, no_letterhead=1)
  • Prints to all waiter-enabled printers in the room (ordered by idx)

3. Changes — ury_kot_generate.py

  • create_kot_doc() / create_cancel_kot_doc() return the created KOT name
  • process_items_for_kot() / process_items_for_cancel_kot() collect and return lists of KOT names
  • At end of kot_execute(), calls print_combined_waiter_order_slip() once with all created KOT names

Important: Waiter print is triggered from kot_execute only — not from URY KOT.on_submit. KOT reprint (ury_kot_reprint) is unaffected.

4. Print format — app default + site customizable

  • App ships URY Waiter Order Slip JSON (doc_type = URY KOT, iterates doc.kot_items, no pricing)
  • Template renders old_qty -> new_qty when display_mode == "old_new", otherwise single quantity
  • Migration patch fix_waiter_order_slip_print_format updates existing site formats on bench migrate
  • Sites can still customize the Print Format in Desk or point room printers to a different format

Behaviour Matrix

Scenario Waiter slip? Notes
Dine-in, new items on save Yes Delta items only
Existing item qty change Yes Shows old -> new
Full item cancel Yes Shows old -> 0
Items span 2+ production units Yes 1 combined slip
Item cancellation on same save Yes Cancel line on same slip
Takeaway table No Skipped
Room without waiter printer No Skipped
Format missing/wrong doctype No Error Log entry
KOT reprint from POS No Separate flow
Kitchen KOT print Unchanged Per production unit on submit

Files Changed

File Change
ury/fixtures/custom_field.json Add custom_waiter_print, custom_waiter_print_format
ury/hooks.py Export new custom fields in fixtures
ury/ury/api/ury_waiter_print.py Combined doc builder, display enrichment, print logic
ury/ury/api/ury_kot_generate.py Return KOT names; call waiter print at end of kot_execute
ury/ury/api/test_ury_waiter_print.py Unit/integration tests (18 tests)
ury/ury/print_format/ury_waiter_order_slip/ury_waiter_order_slip.json App default waiter slip template
ury/patches/v2_0/fix_waiter_order_slip_print_format.py One-time patch to sync template on existing sites
ury/patches.txt Register print format patch

Test Plan

Automated tests

bench --site <site> run-tests --module ury.ury.api.test_ury_waiter_print

Verified on ury.localhost: 18 tests, all passing.

Test Covers
test_build_combined_kot_doc_merges_multiple_kots Multi-KOT merge into one slip
test_build_combined_kot_doc_aggregates_same_item Same item qty summed across KOTs
test_build_combined_kot_doc_includes_cancel_lines Cancellation rows with old/new qty
test_first_time_add_shows_single_quantity First-time add shows single qty
test_existing_item_increase_shows_old_new Qty increase shows old -> new
test_existing_item_partial_cancel_shows_old_new Partial cancel shows old -> new
test_full_cancel_shows_old_to_zero Full cancel shows old -> 0
test_prints_combined_kot_for_dine_in Prints URY KOT with combined doc
test_skips_when_combined_items_empty No print when no items
test_skips_takeaway_tables Takeaway guard
test_skips_without_restaurant_table No table guard
test_skips_when_no_waiter_printers Room without waiter printer
test_skips_when_printer_format_not_set Missing format logs + skips
test_skips_when_format_missing Non-existent format
test_skips_when_format_wrong_doctype Rejects POS Invoice format
test_kot_execute_prints_once_with_all_created_kots Single print call per save
test_kot_reprint_does_not_call_waiter_print KOT reprint decoupled
test_waiter_format_excludes_pricing_sections Site format has no pricing fields

Manual verification

  • bench --site <site> migrate — custom fields + print format patch applied
  • Enable waiter print on target room printer
  • Place dine-in order → slip shows only new items with single qty
  • Increase qty on existing item → slip shows old -> new
  • Cancel item fully → slip shows old -> 0
  • Add item spanning 2 production units → one slip with all new items
  • Takeaway / disabled room → no slip

Deployment Notes

  1. Merge and deploy app update
  2. bench --site <site> migrate — syncs custom fields and waiter print format template
  3. Enable waiter print per room on URY Printer Settings (optionally customize Print Format)
  4. Test on a dine-in table before enabling in production rooms

Out of Scope

  • No waiter print on URY KOT.on_submit
  • Kitchen KOT printing unchanged

Add room-level waiter printing on URY Printer Settings and print one combined
URY KOT slip per order save with delta items only, including cancellations.
Print format remains site-managed on URY KOT doctype.

Co-authored-by: Cursor <cursoragent@cursor.com>
@shzdb shzdb requested a review from swafa-as June 18, 2026 12:36
@anwar-shihab anwar-shihab marked this pull request as draft June 22, 2026 05:28
anwar-shihab and others added 2 commits June 22, 2026 11:23
Enrich combined waiter slip items with display_mode, old_qty, and new_qty
so existing order changes render as old -> new (including full cancel to 0),
while first-time additions keep a single quantity.

Ship the URY Waiter Order Slip app print format and a migration patch so
existing sites receive the updated template on bench migrate. Sites can
still customize the Print Format or select another format per room printer.

Co-authored-by: Cursor <cursoragent@cursor.com>
@anwar-shihab anwar-shihab force-pushed the feature/waiter-delta-kot-print branch from 6044174 to f929b3d Compare June 22, 2026 06:34
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.

1 participant