VENUE/i — Event Venue Box-Office & Settlement

SteelFrame X application operation manual  ·  ← back to Operation Manuals  ·  Sign On

VENUE/i is the box office of a live-event venue: halls subdivided into price zones, events booked into a hall for a promoter, ticket capture and priced ticket sales that relieve seat inventory by zone, concessions sales against stand stock, per-event settlement to the promoter (gross ticket sales less venue fee, facility fee and tax = promoter payout), an AP open-item ledger of what the venue owes each promoter, payout application, AP ageing, and a balanced GL feed. The application is classic ILE: RPG programs drive keyed physical/logical files, one COBOL control report, one SQLRPGLE GL post, DDS display/printer files for the online screens and the ageing report, and CL that wires the object build and the three job cycles. This manual is the reference for the operator who runs the box office and the periodic cycles, and for the developer maintaining the application. It is grounded entirely in the committed source under venue-app/ (src/sources.mjs, src/seed.mjs, and the test/vn_*.mjs drivers).

Contents

A. Overview & Architecture ↑ top

A.1 What it does

VENUE/i runs the full commercial life of a live event, from putting seats on sale to paying the promoter and feeding the general ledger:

A.2 Program-per-step architecture: keyed files, one step per program

VENUE/i is a conventional ILE application, not a two-layer SQL-PL design. The business rules live in the RPG programs themselves, each of which does exactly one step of the cycle against keyed native physical and logical files. The pattern is deliberate and repeated:

The benefit for operations: each step is independently runnable and re-runnable, the CL cycles are thin CALL chains, and the effect of any step is visible in one DSPLY line and in the file it touched. Everything runs in library VENUE.

A.3 Component & flow

  SETUP                 ONLINE                  BATCH (periodic)
  -----                 ------                  ----------------
  VNSETUP  (CL)         VNMENU (5250)           DAILY   VNDAILY (CL)
    CRT* objects          opt 1 -> VNEVQIQ        VNPRICE   (price order lines)
    compile pgms          opt 2 -> VNTKTIQ        VNSELL    (sell / relieve VNZONE)
  VNREFLD  (seed)                                 VNCONCPOST(post VNCSAL / relieve VNCONC)
    halls/proms/patrons VNEVQIQ  event avail
    events/zones/conc   VNTKTIQ  order+subfile   SETTLE  VNSETTLE (CL)
                                                   VNSETTL   (VNSETL + VNAPOP, event->S)
                                                   VNPAYAP   (apply VNPAY -> VNAPOP)

                                                 MONTHLY VNMONTH (CL)
                                                   VNAGE     (age VNAPOP via VNAPDLF)
                                                   VNSTMT    (print VNAGEP)
                                                   VNGLPST   (post VNGLDIST, SQL)
                                                   VNAPRPT   (COBOL AP control report)

  files: VNHALL VNPROM VNPATR VNEVNT VNZONE VNTKTH VNTKTL(+VNTKTLLF)
         VNCONC VNCSAL VNSETL VNAPOP(+VNAPDLF) VNPAY VNGLDIST

A single ticket transaction flows: a patron order is captured into VNTKTH/VNTKTL as new (OSTAT='N', lines LSTAT='O') → the daily cycle prices it (VNPRICE), then sells it (VNSELL) — each fitting line relieves its zone and goes LSTAT='S', the order goes 'P' (or 'H' if any line was rejected) → after the event, VNSETTL sums the sold lines for the event, computes the payout, writes VNSETL and raises the VNAPOP open item, and flips the event to ESTAT='S'.

A.4 Object inventory

ObjectTypeRole
VNHALLPFVenue hall master (physical capacity HCAP).
VNPROMPFPromoter master (the AP "vendor"; PRTERMS payout days).
VNPATRPFPatron (ticket-buyer) master.
VNEVNTPFEvent/performance header (fee%, facility fee, tax%, status).
VNZONEPFPrice zones per event (ZCAP/ZSOLD).
VNTKTHPFTicket order header.
VNTKTLPFTicket order lines (one per zone per order).
VNTKTLLFLFTicket lines keyed EVNTID+ZONEID (settlement/availability path).
VNCONCPFConcessions item master (on-hand CONHAND).
VNCSALPFConcessions sales journal.
VNSETLPFPer-event settlement (gross/fees/tax/payout).
VNAPOPPFAP open items owed to promoters.
VNAPDLFLFSame AP items keyed by due date (ageing path).
VNPAYPFPayout runs (payments to promoters).
VNGLDISTSQL tableGL distribution (DR/CR journal), + index VNGLDACC.
VNEVQD / VNTKTD / VNMENUDDSPFEvent-avail / ticket-subfile / menu screens.
VNAGEPPRTFAP settlement ageing report.
VNREFLDRPGLESeeds the reference data.
VNPRICE / VNSELL / VNCONCPOSTRPGLEDaily-cycle steps.
VNSETTL / VNPAYAPRPGLESettle-cycle steps.
VNAGE / VNSTMTRPGLEMonthly ageing & print.
VNGLPSTSQLRPGLEMonthly GL post (embedded SQL).
VNAPRPTILE COBOLMonthly AP control report.
VNEVQIQ / VNTKTIQ / VNMENURPGLEInteractive inquiry / subfile / menu drivers.
VNSETUPCLPObject build + program compile.
VNDAILY / VNSETTLE / VNMONTHCLPThe three job-cycle chains.

The catalogue is 13 physical files + 2 logical files + 1 SQL table (with its index), 3 display files and 1 printer file, driven by 12 RPG programs, 1 SQLRPGLE, 1 ILE COBOL program and 4 CL programs. Sections D and F expand each.

B. Online Transactions & Screens ↑ top

B.1 The command/entry line

VENUE/i has no CICS transaction identifiers. On IBM i each program is reached by name from a 5250 command-entry line (or a JOBQ/scheduler for the batch cycles). The operator equivalent of "type a transid and Enter" is "type a CALL command and Enter". Before invoking anything, the job's library list must include VENUE — the tested jobs run with LIBL = QSYS QGPL VENUE QTEMP and CURLIB = VENUE.

To do thisType on the command line
Open the operator main menuCALL VENUE/VNMENU
Event availability inquiry (direct)CALL VENUE/VNEVQIQ
Ticket order inquiry (direct)CALL VENUE/VNTKTIQ
Build/compile every object (first install)CALL VENUE/VNSETUP
Seed the reference dataCALL VENUE/VNREFLD
Run the daily box-office cycleCALL VENUE/VNDAILY (or SBMJOB it)
Run the per-event settlement cycleCALL VENUE/VNSETTLE
Run the monthly AP closeCALL VENUE/VNMONTH

None of the batch programs take CALL parameters — each walks its file(s) from *LOVAL and processes every eligible row, so a scheduled submission is a bare CALL. Only VNMENU, VNEVQIQ and VNTKTIQ are interactive; the batch programs run to completion and DSPLY a one-line result per step.

B.2 The menu & inquiry screens

VNMENU (VNMENUD) is the operator entry point. It EXFMTs the menu, routes option 1 to a program CALL of VNEVQIQ and option 2 to VNTKTIQ, reports "Invalid option." for anything else, and exits on F3.

VENUE/i Main Menu 1. Event Availability Inquiry 2. Ticket Order Inquiry Option . . . . : _ F3=Exit Enter=Select

Event Availability Inquiry (VNEVQIQ / VNEVQD)

A plain (non-subfile) screen. Key an event number and Enter: the program CHAINs VNEVNT for the header (name, date, status), then reads the first zone on file for that event (SETLL/READE on VNZONE) and shows its price, capacity, sold, and the derived seats available (ZCAP−ZSOLD, floored at 0) — the figure box-office staff actually care about. An unknown event clears the detail and shows "Event not found."; F3 exits.

Event Availability - VENUE/i Event number: EV0001 Event name . . : SUMMER STADIUM TOUR Event date . . : 20260815 Status . . . . : S Zone . . . . . : FLOOR Price . . . . : 120.00 Capacity . . . : 200 Sold . . . . . : 5 Available . . : 195 Event found. F3=Exit Enter=Inquire

Ticket Order Inquiry (VNTKTIQ / VNTKTD)

The app's subfile screen (DDS record TSFL under control record TCTL, SFLPAG(5)/SFLSIZ(20), ROLLUP/ROLLDOWN paging). Key an order number and Enter: it CHAINs VNTKTH for the header (patron, status, order total) and loads every ticket line (SETLL/READE on VNTKTL) into the subfile — sequence, zone, qty, price, net and line status. The subfile is cleared and reloaded on each enquiry (write TCTL with *IN31 on to clear, drive SFLDSP from *IN32 so it shows only once a row is loaded). An unknown order clears the header and shows "Order not found."; F3 exits.

Ticket Order Inquiry - VENUE/i Order number : ORD00001 Patron . . . . : P00001 Status . . . . : P Order total . : 2,205.00 Seq Zone Qty Price Net S 1 FL 5 120.00 600.00 S 2 T1 20 75.00 1,500.00 S Order found. F3=Exit Roll=Page Enter=Inquire

Actions & keys

Honest statement: the online screens are inquiry-only. There is no interactive ticket-capture, sell, settle or payment screen — those are all batch steps (section C). Orders, concessions sales and payments are captured as data (in the tested suites, written directly to VNTKTH/VNTKTL, VNCSAL, VNPAY) and then processed by the cycles. VNEVQIQ/VNTKTIQ let the operator see availability and order state; they do not mutate it.

B.3 Controls & status gating (no maker–checker)

VENUE/i does not model a four-eyes maker–checker workflow. Its control posture is status/state gating + hard inventory limits, enforced in each program:

Accountability is by journal, not by approval gate: every priced/sold ticket line, concessions sale, settlement, AP open item, payment and GL entry is a durable row you can read back and reconcile (the VNAPRPT COBOL control report and the VNSTMT ageing print exist for exactly that).

C. Batch Jobs & the Periodic Cycle ↑ top

VENUE/i's processing runs as three CL-chained cycles rather than one monolithic job: a daily box-office cycle (price → sell → post concessions), a settle cycle (per-event settlement → payout application), and a monthly AP close (age → print → GL post → control report). Each CL program simply ADDLIBLE VENUE and CALLs its steps in order; none of the steps take parameters — they walk their files and process every eligible row.

-- the three cycles, submittable as bare jobs
SBMJOB CMD(CALL PGM(VENUE/VNDAILY))  JOB(VNDAILY)
SBMJOB CMD(CALL PGM(VENUE/VNSETTLE)) JOB(VNSETTLE)
SBMJOB CMD(CALL PGM(VENUE/VNMONTH))  JOB(VNMONTH)

-- first install: build objects, then seed reference data
CALL PGM(VENUE/VNSETUP)
CALL PGM(VENUE/VNREFLD)

C.1 Full batch program set

ProgramCyclePurposeReads / writesResult DSPLY
VNPRICEDAILY Price every open order line at its zone price; stamp header net/tax/total (tax per-event). reads VNZONE/VNEVNT; updates VNTKTL, VNTKTH. VNPRICE PRICED=n SKIP=n
VNSELLDAILY Sell fitting lines (relieve zone inventory), reject oversells whole; set order P/H. reads VNEVNT; updates VNZONE, VNTKTL, VNTKTH. VNSELL SOLD=n REJECTED=n SKIP=n
VNCONCPOSTDAILY Post new concessions sales, relieve on-hand stock, compute tax from item tax code. updates VNCONC, VNCSAL. VNCONCPOST POSTED=n SHORT=n SKIP=n
VNSETTLSETTLE Per-event settlement: sum sold lines, compute payout, raise settlement + AP item, event→S. reads VNTKTLLF/VNPROM; writes VNSETL, VNAPOP; updates VNEVNT. VNSETTL SETTLED=n SKIP=n
VNPAYAPSETTLE Apply unapplied payments against their AP open item; reduce open by exactly the amount taken. updates VNAPOP, VNPAY. VNPAYAP APPLIED=n SKIP=n
VNAGEMONTHLY Age each open AP item into bucket 0/1/2/3 by days overdue at the run date (30/360 serial). reads VNAPDLF (due-date order); updates VNAPOP. VNAGE B0=n B1=n B2=n B3=n
VNSTMTMONTHLY Print the AP settlement ageing report over open items, with page overflow. reads VNAPDLF/VNPROM; writes VNAGEP (PRTF). VNSTMT LINES=n OPEN=nnn
VNGLPSTMONTHLY Post the settlement register as balanced DR/CR GL rows (movement since last close only). reads VNSETL; SQL insert into VNGLDIST. VNGLPST BATCH=202609 ROWS=n
VNAPRPTMONTHLY ILE COBOL control report proving the AP sub-ledger totals reconcile. reads VNAPOP sequentially. VNAPRPT RAISED/OPEN/ITEMS/OVERDUE

C.2 Daily / settle / monthly detail

Daily — VNDAILY (VNPRICE → VNSELL → VNCONCPOST)

VNPRICE walks the order headers; for each order that is not already posted/cancelled it prices every non-cancelled line at its zone's current ZPRICE (TNET = TQTY × ZPRICE), reads the event's ETAXPC, and stamps the header ONETVAL / OTAXVAL (net × tax%) / OTOTVAL. It re-CHAINs the line and header after the zone/event reads because those reads move the file cursor. Idempotent: it recomputes from TQTY and the zone price every time.

VNSELL walks the headers; for each OSTAT='N' order whose event is on sale it reads each open line, CHAINs the zone, computes free = ZCAP−ZSOLD, and — whole-line-or-nothing — if free ≥ qty it raises ZSOLD and marks the line 'S', else marks it 'X' (rejected). An order with any rejected line goes OSTAT='H', else 'P'. An event on hold/cancelled sells nothing.

VNCONCPOST walks new concessions sales; for each it CHAINs the item, refuses the sale whole if on-hand < qty (leaves it 'N'), else relieves CONHAND, computes tax (flat 8% for a 'S'-coded item, none for 'Z'), and stamps the sale 'P'.

Expected DSPLY (hand-derived book: 3 orders, 2 concessions sales):
  VNPRICE PRICED= 3 SKIP= 0
  VNSELL SOLD= 3 REJECTED= 1 SKIP= 0   15xGA vs 10-cap zone rejected whole
  VNCONCPOST POSTED= 1 SHORT= 1        25xWATER vs 20 on-hand refused

Settle — VNSETTLE (VNSETTL → VNPAYAP)

VNSETTL walks the events; for a settleable event (not already 'S'/'X', and no existing settlement row) it sums TNET over every LSTAT='S' ticket line for the event through the event-keyed VNTKTLLF, computes venue fee (gross × EFEEPC/100), facility fee (flat EFACFEE), tax (gross × ETAXPC/100) and payout (gross − vfee − ffee − tax, clamped ≥ 0), writes VNSETL, flips the event to 'S', and raises a VNAPOP open item due settlement-date + PRTERMS.

VNPAYAP walks the payments; for each unapplied (PYSTAT='U') payment it CHAINs the nominated AP item and applies min(tendered, open): APPAID rises, APOPEN falls, the item goes 'P' (paid) at zero open, and the payment is stamped 'A' (fully applied) or 'P' (part).

Expected DSPLY (settle the daily book, then a 2000.00 payment):
  VNSETTL SETTLED= 2 SKIP= 0
  VNPAYAP APPLIED= 1 SKIP= 0
EV0001 gross 4350.00, vfee 435.00, ffee 500.00, tax 217.50 -> payout 3197.50
EV0002 gross 0.00 (only line rejected) -> payout clamped to 0.00
payment 2000.00 vs open 3197.50 -> open falls to 1197.50, item stays open

Monthly — VNMONTH (VNAGE → VNSTMT → VNGLPST → VNAPRPT)

VNAGE reads the open AP items oldest-due-first through VNAPDLF, and for each item with open > 0 stamps APAGE from days overdue at the run date (20260930) using the 30/360 serial ((yyyy×12)+mm)×30+dd: 0 current, 1 = 1–30, 2 = 31–60, 3 = 61+. VNSTMT prints one VNAGEP detail line per open item (skipping zero-open items), joining the promoter name, with page-overflow re-headers, and a total footer. VNGLPST (SQLRPGLE) accumulates the settlement register and posts the movement since the last close as balanced rows into VNGLDIST. VNAPRPT (COBOL) reads the whole AP ledger and reports raised / open / item count / overdue count.

Expected DSPLY (real settled book + 3 seeded ageing items):
  VNAGE B0= 1 B1= 1 B2= 1 B3= 1     one item in each bucket
  VNSTMT LINES= 4 OPEN= 7697.5      4 open items; zero-open EV0002 skipped
  VNGLPST BATCH=202609 ROWS= 3      DR cash / CR AP / CR venue fee
  VNAPRPT ITEMS 5.00  OVERDUE 3.00  5 AP items, 3 aged past due
GL: DR 1000-CASH 4350.00 = CR 2100-AP 3197.50 + CR 4100-VFEE 1152.50 (balances)

C.3 Ordering & dependencies

D. Data Files (data dictionary) ↑ top

All files are in library VENUE, grounded in the DDS/SQL in src/sources.mjs. Dates are stored as signed numeric YYYYMMDD (packed/zoned per DDS); money is packed decimal (nP2); fee and tax percentages are packed 5P2 (e.g. 10.00 = 10%).

VNHALL — Hall master (key HALLID)

FieldTypeMeaning
HALLID4AHall id (key), e.g. H001.
HNAME / HCITY30A / 20AHall name / city.
HCAP7P0Physical seat capacity of the hall.
HSTAT1AHall status (A active).

Seeded: H001 RIVERSIDE ARENA (cap 2000), H002 THE GRANGE THEATRE (cap 600).

VNPROM — Promoter master / AP vendor (key PROMO)

FieldTypeMeaning
PROMO6APromoter id (key), e.g. PM0001.
PRNAME30APromoter name.
PRTERMS3S0Days after settlement the payout is due.
PRSTAT1APromoter status (A active).

Seeded: PM0001 (14-day terms), PM0002 (30-day terms) — different terms so ageing has variety.

VNPATR — Patron master (key PATRID)

FieldTypeMeaning
PATRID6APatron id (key).
PNAME / PEMAIL30A / 30APatron name / email.
PSTAT1APatron status (A active).

VNEVNT — Event / performance header (key EVNTID)

FieldTypeMeaning
EVNTID6AEvent id (key), e.g. EV0001.
HALLID / PROMO4A / 6AHall booked / promoter (FKs in intent).
ENAME30AEvent name.
EDATE8S0Event date (YYYYMMDD).
ESTAT1AN new/on-sale, H on hold (box office closed), S settled, X cancelled.
EFEEPC5P2Venue fee % on gross ticket sales.
EFACFEE11P2Flat facility fee.
ETAXPC5P2Tax % on ticket sales.

Seeded: EV0001 (arena, PM0001) 10% fee / 500.00 facility / 5% tax; EV0002 (theatre, PM0002) 15% fee / 100.00 facility / 0% tax.

VNZONE — Price zones per event (key EVNTID, ZONEID)

FieldTypeMeaning
EVNTID / ZONEID6A / 2AEvent + zone (key).
ZNAME20AZone name (FLOOR, TIER 1, …).
ZPRICE9P2Per-ticket price in this zone.
ZCAP6P0Seat capacity allocated to this zone for this event.
ZSOLD6P0Running count of tickets sold in the zone. Available = ZCAP−ZSOLD.

Seeded EV0001: FL 120.00/cap 200, T1 75.00/cap 500, T2 45.00/cap 300 (sum 1000 ≤ hall 2000, headroom). EV0002: GA 35.00/cap 10 (tiny, so an oversell test bites).

VNTKTH — Ticket order header (key ORDNO)

FieldTypeMeaning
ORDNO8AOrder number (key), e.g. ORD00001.
PATRID / EVNTID6A / 6ABuyer / event.
ODATE8S0Order date.
OSTAT1AN new (not yet sold), P posted (tickets sold), H held (a line rejected), X cancelled.
ONETVAL / OTAXVAL / OTOTVAL11P2Order net / tax / total (stamped by VNPRICE).

VNTKTL — Ticket order lines (key ORDNO, LSEQ)

FieldTypeMeaning
ORDNO / LSEQ8A / 3S0Order + line sequence (key).
EVNTID6AEvent (denormalised onto the line so VNTKTLLF can key on it).
ZONEID2AZone bought into.
TQTY5P0Tickets requested/sold on this line.
TPRICE / TNET9P2 / 11P2Zone price applied / line net (TQTY×TPRICE).
LSTAT1AO open/unpriced-unsold, S sold (inventory relieved), X cancelled/rejected (no inventory taken).

VNTKTLLF — Ticket-line access path (key EVNTID, ZONEID, ORDNO)

Non-unique logical file over VNTKTL: the per-event/per-zone sales enquiry the settlement run and the availability screen both want. The base PF is keyed ORDNO/LSEQ and cannot be walked positioned on an event id, so VNSETTL reads sold lines through this path.

VNCONC — Concessions item master (key ITEMNO)

FieldTypeMeaning
ITEMNO6AItem number (key).
CDESC20ADescription.
CPRICE7P2Unit price.
CONHAND7P0On-hand stock (relieved by a posted sale).
CTAXCD1ATax code: S standard (flat 8% at the till), Z zero-rated.
CSTAT1AItem status (A active).

Seeded: CN0001 lager 6.50/'S'/1000, CN0002 hot dog 5.00/'S'/300, CN0003 water 2.50/'Z'/20 (low stock, oversell test).

VNCSAL — Concessions sales (key SALNO)

FieldTypeMeaning
SALNO8ASale number (key).
EVNTID / ITEMNO6A / 6AEvent / item sold.
CQTY5P0Quantity.
CDATE8S0Sale date.
CNET / CTAX / CTOT11P2Net / tax / total (stamped at post).
CSTAT1AN new (not yet posted), P posted (stock relieved).

VNSETL — Per-event settlement (key EVNTID)

FieldTypeMeaning
EVNTID / PROMO6A / 6AEvent settled / promoter paid.
SGROSS11P2Gross sold-ticket sales (Σ sold-line TNET).
SVFEE11P2Venue fee = SGROSS × EFEEPC/100.
SFFEE11P2Flat facility fee (EFACFEE, copied).
STAX11P2Tax = SGROSS × ETAXPC/100.
SPAYOUT11P2Promoter payout = SGROSS − SVFEE − SFFEE − STAX (clamped ≥ 0).
SSTAT1AO open (AP raised, unpaid), P paid, ' ' unsettled.

VNAPOP — AP open items (key PROMO, EVNTID)

FieldTypeMeaning
PROMO / EVNTID6A / 6APromoter owed + the event (key; a promoter's items sit together).
APINVDT / APDUEDT8S0Settlement (invoice) date / due date = invoice + PRTERMS.
APAMT11P2Payout raised (mirrors SPAYOUT at settlement).
APPAID11P2Amount paid so far.
APOPEN11P2Outstanding = APAMT − APPAID.
APAGE1S0Ageing bucket 0/1/2/3 (stamped by VNAGE).
APSTAT1AO open, P paid (zero open).

VNAPDLF — AP due-date access path (key APDUEDT, PROMO)

Second logical file over VNAPOP, keyed by due date, so the monthly ageing and print walk the ledger oldest-due-first without sorting.

VNPAY — Payout runs (key PAYNO)

FieldTypeMeaning
PAYNO8APayment number (key).
PROMO / PYEVNT6A / 6APromoter + event the payment nominates (its AP-item key).
PYDT8S0Payment date.
PYAMT11P2Amount tendered.
PYAPPL11P2Amount actually applied against the AP item.
PYSTAT1AU unapplied, A fully applied, P part-applied.

VNGLDIST — GL distribution (SQL table, PK GLSEQ)

ColumnTypeMeaning
GLSEQDECIMAL(8,0)Sequence (PK), continued run to run.
GLBATCHDECIMAL(6,0)Posting batch (e.g. 202609).
ACCT / DRCRCHAR(9) / CHAR(1)Account (1000-CASH, 2100-AP, 4100-VFEE) / D or C.
AMTDECIMAL(11,2)Signed posting amount.
GLREF / GLDTCHAR(8) / DECIMAL(8,0)Reference (SETTLE) / GL date.

Index VNGLDACC on (ACCT, DRCR) — the by-account read the re-post guard uses.

Relationships

E. Operations Runbook ↑ top

E.1 Day-in-the-life

  1. First install only: CALL VENUE/VNSETUP (builds every object and compiles every program; ends with a "VENUE setup complete." banner), then CALL VENUE/VNREFLD to seed halls/promoters/patrons/events/zones/concessions.
  2. Capture the day's ticket orders (into VNTKTH/VNTKTL, orders OSTAT='N' with lines LSTAT='O') and concessions sales (into VNCSAL, CSTAT='N').
  3. Submit the daily cycle: SBMJOB CMD(CALL PGM(VENUE/VNDAILY)).
  4. Post-check the daily run (below).
  5. Use the online screens to check availability/order state: CALL VENUE/VNMENU.

Pre-checks: confirm the job's library list includes VENUE; confirm the events you intend to sell are ESTAT='N' (an 'H' event sells nothing).

Post-checks after the daily cycle:

E.2 Settlement & month-end

  1. After an event has played and its daily sells are in, submit the settlement cycle: SBMJOB CMD(CALL PGM(VENUE/VNSETTLE)). Confirm VNSETTL SETTLED= covers the events you expected and VNPAYAP APPLIED= covers the payments you captured in VNPAY.
  2. Reconcile each settlement row and its AP item:
SELECT EVNTID, SGROSS, SVFEE, SFFEE, STAX, SPAYOUT, SSTAT FROM VENUE.VNSETL;
-- and the AP open items it raised
SELECT PROMO, EVNTID, APAMT, APPAID, APOPEN, APDUEDT, APSTAT FROM VENUE.VNAPOP;

Reconciling figures (the same ones the volume suites check against a hand-derived oracle):

Month-end: submit SBMJOB CMD(CALL PGM(VENUE/VNMONTH)). Confirm the four DSPLY lines (VNAGE buckets, VNSTMT LINES=/OPEN=, VNGLPST ROWS=, VNAPRPT ITEMS/OVERDUE). Then reconcile the GL:

SELECT ACCT, DRCR, AMT FROM VENUE.VNGLDIST ORDER BY GLSEQ;
-- DR total must equal CR total: 4350.00 (DR cash) = 3197.50 (CR AP) + 1152.50 (CR VFEE)

E.3 Failure & re-run rules

Each program DSPLYs its result line. Every mutating step gates on a status flag and advances it, so the safe recovery for almost any partial failure is simply to re-submit — already-processed rows are skipped.

SituationBehaviourAction
Daily cycle fails partwayPriced/sold rows carry their new status; unprocessed rows keep the old one.Re-submit VNDAILY: priced orders re-price to the same value (recompute from TQTY×price), sold lines are skipped (LSTAT≠'O'), the rest catch up. Idempotent.
Re-run VNSELLOnly OSTAT='N' orders / 'O' lines are considered.No-op: zone ZSOLD does not double, rejects are not re-rejected.
Re-run VNCONCPOSTOnly CSTAT='N' sales considered.Posts nothing new (POSTED=0); stock not double-relieved.
Re-run VNSETTLEvent already 'S'/'X', or a VNSETL row already exists (CHAIN(EN) guard).Settles nothing (SETTLED=0); no duplicate settlement or AP item.
Re-run VNPAYAPOnly PYSTAT='U' payments considered.Applies nothing (APPLIED=0); open balance does not fall twice.
Over-payment / zero-open itemApplies min(tendered, open); against a zero-open item applies 0.00 and leaves the payment part-applied (PYSTAT='P').Nothing owed is taken; no negative open.
Re-run VNAGE (same run date)Recomputes buckets from due dates; stamps the same values.Idempotent — identical bucket counts.
Re-run VNGLPSTReads already-posted cash-DR / AP-CR and subtracts; a clean second run has zero movement.Posts nothing (ROWS=0); GL row count unchanged. No double-post.
Because every priced/sold line, concessions sale, settlement, AP item, payment and GL entry is a durable keyed row, any cycle's effect is fully reconstructable after the fact — the VNAPRPT COBOL control report reconciles the AP sub-ledger (raised vs open vs overdue) and the GL batch is self-balancing.

F. Developer Reference ↑ top

The complete program surface, from src/sources.mjs. All objects are in library VENUE. The RPG is fixed-form C-specs with /free islands, driving keyed DDS files; the one SQLRPGLE program uses embedded EXEC SQL.

F.1 Programs

VNREFLD (RPGLE)
Seed loader: WRITEs the reference rows (2 halls, 2 promoters, 3 patrons, 2 events, 4 zones, 3 concessions items). DSPLYs the seed counts.
VNPRICE (RPGLE)
Prices open order lines at zone price, stamps header net/tax/total. Uses composite KLISTs LKEY(ORDNO,LSEQ) and ZKEY(EVNTID,ZONEID); re-CHAINs the line and header after zone/event reads move the cursor. Skips OSTAT P/X and LSTAT='X' lines.
VNSELL (RPGLE)
Sells fitting lines (whole-line-or-nothing), relieves ZSOLD, sets line S/X and order P/H. Reads the event first to honour hold/cancel. The seat check is free = ZCAP−ZSOLD (floored 0), sell iff free ≥ TQTY.
VNCONCPOST (RPGLE)
Posts new concessions sales, relieves CONHAND, computes tax (8% for 'S', 0 for 'Z'). Refuses whole if CONHAND < CQTY (leaves sale 'N').
VNSETTL (RPGLE)
Per-event settlement. Sums LSTAT='S' TNET via VNTKTLLF, computes vfee/ffee/tax/payout (payout clamped ≥ 0), WRITEs VNSETL and VNAPOP, flips event to 'S'. Idempotent via CHAIN(EN) on the existing settlement row.
VNPAYAP (RPGLE)
Applies PYSTAT='U' payments against their AP item by APKEY(PROMO,EVNTID): takes min(PYAMT, APOPEN), updates paid/open (item → 'P' at zero open), stamps payment 'A'/'P'.
VNAGE (RPGLE)
Reads open items oldest-first through VNAPDLF; stamps APAGE 0/1/2/3 from days overdue at run date 20260930 using the 30/360 serial. Skips zero-open items.
VNSTMT (RPGLE)
Prints the VNAGEP ageing report over open items (joins VNPROM for the name), with page-overflow re-headers (OFLIND(*IN90)) and a count/total footer.
VNGLPST (SQLRPGLE)
Accumulates the settlement register, reads already-posted DR-cash / CR-AP totals from VNGLDIST, subtracts, and if there is new movement posts DR 1000-CASH (gross), CR 2100-AP (payout), CR 4100-VFEE (the remainder) via EXEC SQL INSERT — balanced by construction. Continues GLSEQ. DSPLYs batch and rows.
VNAPRPT (ILE COBOL)
Sequential read of VNAPOP; totals raised (AP-AMT), open (AP-OPEN), item count, and overdue count (AP-AGE>0). The AP sub-ledger reconciliation.
VNEVQIQ / VNTKTIQ / VNMENU (RPGLE)
The three interactive drivers (section B.2): event-availability inquiry, ticket-order subfile inquiry, and the routing menu.
VNSETUP / VNDAILY / VNSETTLE / VNMONTH (CLP)
Object build+compile, and the three job-cycle CALL chains.

F.2 The seat-conservation invariant

The core data invariant the app is built around, asserted at the zone level by the daily suite:

for every VNZONE row, at all times:
  ZSOLD + (ZCAP - ZSOLD) = ZCAP        sold + available = capacity

VNSELL enforces it by only ever raising ZSOLD when a whole line fits:
  free = ZCAP - ZSOLD          (floored at 0)
  if free >= TQTY:  ZSOLD += TQTY ; line -> 'S'     seats taken
  else:             (zone untouched) ; line -> 'X'  rejected whole

A rejected oversell therefore leaves its zone completely untouched (the GA zone stays ZSOLD=0 after a 15-seat request against 10 seats), and a re-run never double-sells. At the event level, the sum of a hall's zone capacities is kept within HCAP at seed time (EV0001: 200+500+300 = 1000 ≤ 2000).

F.3 The settlement & AP invariants

Settlement (VNSETTL), per event:
  SGROSS  = SUM(TNET) over LSTAT='S' lines for the event   (via VNTKTLLF)
  SVFEE   = SGROSS * EFEEPC / 100
  SFFEE   = EFACFEE                        (flat, always applies)
  STAX    = SGROSS * ETAXPC / 100
  SPAYOUT = max(0, SGROSS - SVFEE - SFFEE - STAX)

AP application (VNPAYAP):
  take   = min(PYAMT, APOPEN)
  APPAID += take ; APOPEN -= take ; APOPEN==0 -> APSTAT='P'

GL post (VNGLPST) — balanced by construction:
  DR 1000-CASH  = SGROSS   (new movement only)
  CR 2100-AP    = SPAYOUT
  CR 4100-VFEE  = SGROSS - SPAYOUT          (= vfee+ffee+tax retained by venue)
  => DR total == CR total

The GL re-post guard reads SUM(AMT) already in VNGLDIST for 1000-CASH/D and 2100-AP/C and subtracts, so only the movement since the last close is posted; a clean second run posts nothing.

F.4 File-access & RPG patterns

F.5 Status-code table

FieldValueMeaning
ESTAT (VNEVNT)N / H / S / XNew/on-sale · on hold (closed) · settled · cancelled.
OSTAT (VNTKTH)N / P / H / XNew · posted (sold) · held (a line rejected) · cancelled.
LSTAT (VNTKTL)O / S / XOpen · sold (inventory relieved) · cancelled/rejected.
CSTAT (VNCSAL)N / PNew · posted (stock relieved).
SSTAT (VNSETL)O / P / ' 'Open (AP raised) · paid · unsettled.
APSTAT (VNAPOP)O / POpen · paid (zero outstanding).
APAGE (VNAPOP)0 / 1 / 2 / 3Current · 1–30 · 31–60 · 61+ days overdue.
PYSTAT (VNPAY)U / A / PUnapplied · fully applied · part-applied.

There are no SQLSTATE application codes: VENUE/i signals outcomes through these status fields and the DSPLY result lines, not through SQL exceptions (the one SQL program, VNGLPST, checks SQLCOD=0 only to count successful inserts).

G. Glossary ↑ top

AP open item (payable)
What the venue owes a promoter after an event settles: a VNAPOP row with amount raised, paid and outstanding, and a due date. The payables mirror of a receivable ledger.
Ageing bucket
A classification of how overdue an open payable is: 0 current, 1 = 1–30 days, 2 = 31–60, 3 = 61+ (VNAGE, via the 30/360 serial). Used by the ageing print and the control report.
Concessions
Food/drink/merchandise sold at a stand during an event (VNCONC items, VNCSAL sales). Posting relieves on-hand stock and taxes 'S'-coded items at a flat 8%.
Facility fee
A flat per-event charge (EFACFEE) the venue deducts from gross at settlement, regardless of ticket volume — it applies even to an unsold event.
GL distribution / balanced batch
The general-ledger journal (VNGLDIST) of DR/CR entries. VENUE/i's posting is balanced by construction: DR cash = CR AP + CR venue-fee remainder.
Idempotent
Safe to run again with the same result. Every VENUE/i step gates on a status flag and advances it, so a re-run is a no-op (a zone is never double-sold, a settlement never doubled, the GL never double-posted).
Payout (promoter payout)
What the venue pays the promoter for an event: gross − venue fee − facility fee − tax, clamped at 0. Raised as an AP open item at settlement.
Price zone / tier
A priced seating band within an event's hall (VNZONE), with its own price and seat capacity. Ticket lines buy into a zone and relieve its inventory.
SBMJOB
Submit Job — the IBM i command that queues a program to run as a batch job (e.g. SBMJOB CMD(CALL PGM(VENUE/VNDAILY))).
Seat conservation
The invariant ZSOLD + (ZCAP−ZSOLD) = ZCAP (sold + available = capacity) that holds for every zone at all times, enforced by whole-line-or-nothing selling.
Settlement
The post-event accounting run (VNSETTL) that turns sold-ticket gross into a promoter payout and an AP open item, and flips the event to settled.
Subfile
A 5250 display construct listing many rows on one screen (DDS SFL/SFLCTL). VNTKTIQ's ticket-line list is a subfile, paged with the Roll keys.
Whole-line-or-nothing
The selling rule: a ticket line (or concessions sale) either fits entirely and is taken, or is rejected entirely — no partial seat booking or partial stock draw.
30/360 serial
The date-difference convention VENUE/i uses for ageing: serial(yyyymmdd) = ((yyyy×12)+mm)×30+dd, days = serial(run) − serial(due). A stamping convention, not a real calendar rollover.