Project

General

Profile

Actions

Feature #170

open
NP NP

Canteen: coupons — issue, print, redeem at POS, liability report feed

Feature #170: Canteen: coupons — issue, print, redeem at POS, liability report feed

Added by Navya P. about 1 month ago. Updated about 1 month ago.

Status:
Resolved
Priority:
Normal
Assignee:
Target version:
-
Start date:
09/29/2026
Due date:
09/29/2026 (45 days late)
% Done:

100%

Estimated time:
Resolved By:

Description

Prepaid meal coupons, issued in books and redeemed at the till.

  • CouponBook (book number from Admin's canteen-coupon-book sequence, purpose, department, cost centre, quantity, value, price list, valid till) and its Coupon rows.
  • CouponCodeGenerator: CP-0914-0001-K7 shape, a check character that catches every single-character typo, alphabet excludes I, L, O, U.
  • GET coupons/resolve?code= -> valid / expired / redeemed / void / book closed.
  • POS Coupon tab: the coupon covers up to its value, any remainder is cash. Redemption marks the coupon under a row lock, inside the same transaction that numbers the sale.
  • A void un-redeems the coupon; two concurrent redemptions of one coupon settle to exactly one success; closing a book voids only the unredeemed coupons.
  • /coupons page with an issue dialog and an A4 print sheet (3x7 cut-outs, barcode).
    Depends on: Admin's coupon-book number sequence.

NP Updated by Navya P. about 1 month ago Actions #1

  • Status changed from New to In Progress

Backend done, tested, on integration/canteen-v1 (7 commits):

  • CouponCodeGenerator: format + check digit, catches every single-character typo
  • CouponBook / Coupon entities: issue, redeem, void, close-voids-unredeemed
  • Database table + migration (coupon codes are per-hospital unique, not global -- caught by a test)
  • ICouponService: issue a book, resolve a code (always 200), close a book
  • Coupon redeemable at the till: prices at the book's Staff/Visitor rate, under a row lock so two tills can never redeem the same coupon
  • Void gives a coupon back (V20/V21), race-tested

Still to do: API controller + permissions, portal /coupons page, POS Coupon tab, print page.

API: 503 unit + 621 integration tests, all green.

NP Updated by Navya P. about 1 month ago Actions #2

Backend complete, tested, on integration/canteen-v1 (8 commits):

  • CouponCodeGenerator, CouponBook/Coupon entities, database, ICouponService
  • Redeemable at the till under a row lock; void gives the coupon back (V20/V21)
  • CouponsController: issue/list/get/close a book, resolve a code at the till -- all gated, tested

API: 503 unit + 632 integration tests, all green.

Left: portal /coupons page (issue dialog, print page), POS Coupon tab.

NP Updated by Navya P. about 1 month ago Actions #3

  • % Done changed from 0 to 70

NP Updated by Navya P. about 1 month ago Actions #4

Coupons (V1-8) done end to end, on integration/canteen-v1, pushed (11 commits):

  • Issue a book -> generates every coupon, individually coded, check-digit protected
  • Print: A4 sheet, hand-rolled Code 128 barcode under each code (no library added, per plan)
  • POS Coupon tab: scan, see the book's price and value, ring it at the till, priced at Staff or Visitor per the book
  • Void gives the coupon back (V20/V21), race-tested
  • Close voids every unredeemed coupon; liability stat cards on /coupons

API: 503 unit + 632 integration. Portal: 445 tests. All green, tsc clean.

One caveat worth a manual check at UAT: the barcode's symbol table was hand-transcribed from the
Code 128 spec (no library) and could not be verified against a real scanner in this environment --
worth a physical scan test before relying on it.

NP Updated by Navya P. about 1 month ago Actions #5

  • Status changed from In Progress to Resolved
  • Resolved By set to Navya P.

NP Updated by Navya P. about 1 month ago Actions #6

  • Due date set to 09/29/2026
  • % Done changed from 70 to 100
Actions

Also available in: PDF Atom