SCHOLARIS/i — K-12 School Business Office

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

SCHOLARIS/i is a K-12 school business-office application: a family/payer master and student master, grade-level tuition schedules, per-year fee items and financial-aid awards, a family accounts-receivable (AR) ledger, installment payment plans and cash receipts, prepaid lunch/POS accounts that are never allowed to go negative, and a balanced general-ledger (GL) feed. The book flows one way — enrollment → tuition and fees net of aid → the family ledger → cash / payment plans / lunch accounts → the GL — and every money movement is journaled to a durable audit trail. The application is deliberately minimal and hand-derivable: every posted figure is stated as exact arithmetic in the tests. This manual is the reference for the operator who runs the online screens and the three job cycles, and for the developer maintaining the application. It is grounded entirely in the committed source (school-app/src/sources.mjs, src/seed.mjs, the test/sc_*.mjs drivers, and school-app/FINDINGS.md). Everything runs in library SCHOLARIS.

Contents

A. Overview & Architecture ↑ top

A.1 What it does

SCHOLARIS/i runs a school's business office across three cycles:

A.2 One-way posting model: the family balance is the spine

SCHOLARIS/i has a single financial invariant that ties the whole application together: the family's running AR balance (SCFAM.FBAL) moves only two waysup when a charge is posted (term assessment, a plan installment, a late fee) and down when cash is applied. It is never edited directly. Every posting program that raises or lowers FBAL also writes the matching ledger line (SCLEDG) and a durable history row (SCHIST), so the book stays reconstructable and the COBOL trial balance SCGLRPT can prove, at any time, that the sum of every open ledger item's LOPEN reconciles to the sum of every family's FBAL (its BALDIFF is zero).

Two design choices keep the arithmetic honest and hand-derivable. First, tuition is charged as an exact one-third of the annual figure per term (the seeded annual tuitions — K5 6000.00, grade 03 7200.00, grade 08 8400.00 — divide cleanly into 2000.00 / 2400.00 / 2800.00, so three terms sum back to the annual figure with no rounding drift). Second, a financial-aid award is posted as a negative ledger line, so the ledger lines for a student sum directly to the net charge and the family balance rises by exactly that net.

A.3 Component & flow

  ONLINE (5250)          TERM              DAILY               MONTHLY
  -------------          ----              -----               -------
  SCMENU                 SCTERM            SCDAILY             SCMONTH
    1 -> SCSTUIQ           SCASSESS          SCLPOS  (lunch)     SCINST   (plan installments)
    2 -> SCLEDIQ            (assess)          SCCASH  (cash)      SCLATE   (aging + late fees)
                          SCGLRPT                                SCLWARN  (lunch low-bal sweep)
                           (trial bal)                           SCGLDST  (GL distribution)
                                                                 SCGLRPT  (trial balance)
       \                        |                    |                    /
        \                       v                    v                   /
         +----------------> SCFAM.FBAL  (family AR balance: up on charge, down on cash) <-+
                                 |
                                 v
         SCLEDG (open-item ledger) --+-- SCHIST (durable audit trail, disjoint key ranges)
         SCLUNCH / SCLTXN (lunch)    +-- SCGLDIST (SQL GL, balanced DR/CR pairs)
         SCPLAN (payment plans)      +-- SCRCPT (cash receipts)

A single event — say, one term charge — flows: SCASSESS reads the active enrollment → looks up the grade tuition schedule and the grade's fee links → caps any aid at the gross → writes the tuition, fee and aid ledger lines into SCLEDG → raises SCFAM.FBAL by the net → writes the SCHIST history rows the monthly GL post later sums.

A.4 Object inventory

ObjectTypeRole
SCFAMPFFamily / payer master; FBAL is the AR spine.
SCSTUPFStudent master (family, grade, status).
SCSTULFLFStudents keyed by FAMNO (a family's roster).
SCGRADEPFGrade-level annual tuition schedule per school year.
SCENRPFEnrollment (student × school year → grade).
SCFEEPFFee-item master (registration / activity / lab …).
SCGFEEPFWhich fee items apply to which grade.
SCAIDPFFinancial-aid / scholarship awards.
SCLEDGPFFamily AR open-item ledger.
SCLEDLFLFThe ledger keyed by due date (oldest-due-first aging).
SCPLANPFInstallment payment plans.
SCRCPTPFCash receipts against the ledger.
SCLUNCHPFPrepaid lunch/POS account (never negative).
SCLTXNPFLunch POS transactions (charge / reload).
SCHISTPFDurable audit trail; disjoint key ranges per program.
SCGLDISTSQL tableGL distribution (DR/CR pairs), + index SCGLDACC.
SCSTUD / SCLEDD / SCMENUDDSPFStudent inquiry / ledger subfile / menu.
SCAGEPPRTFAR ageing / billing statement printer file.
SCREFLDRPGLEReference-data seed loader.
SCASSESSRPGLETerm tuition + fee assessment.
SCCASHRPGLECash-receipt application.
SCLPOSRPGLELunch POS charge/reload run.
SCINSTRPGLEPayment-plan installment due-posting.
SCLATERPGLEAR aging + late-fee assessment.
SCLWARNRPGLELunch low-balance alert sweep (read-only).
SCGLDSTSQLRPGLEGL distribution post (embedded SQL).
SCSTUIQ / SCLEDIQ / SCMENURPGLEInquiry / subfile inquiry / menu drivers.
SCGLRPTCBLLECOBOL AR trial balance.
SCSETUPCLPObject build/compile driver.
SCTERM / SCDAILY / SCMONTHCLPThe three job-cycle drivers.

The catalogue is 13 PFs + 2 LFs, 1 SQL table + 1 index, 3 DSPFs and 1 PRTF, driven by 11 RPGLE programs + 1 SQLRPGLE + 1 COBOL program, wired together by 4 CL programs. Sections D and F expand each.

B. Online Transactions & Screens ↑ top

B.1 The command/entry line

SCHOLARIS/i has no CICS transaction identifiers and no transid switch. On IBM i each program is reached by name from a 5250 command-entry line (or through the menu SCMENU for the two inquiries, or a JOBQ/scheduler for the batch cycles). Before invoking anything, the job's library list must include SCHOLARIS — the tested jobs run with LIBL = QSYS QGPL SCHOLARIS QTEMP and CURLIB = SCHOLARIS.

To do thisType on the command line
Open the main menu (routes to the two inquiries)CALL SCHOLARIS/SCMENU
Student / family inquiry directlyCALL SCHOLARIS/SCSTUIQ
Family ledger (subfile) inquiry directlyCALL SCHOLARIS/SCLEDIQ
Build/compile every object (first-time setup)CALL SCHOLARIS/SCSETUP
Seed reference data (families, students, grades, fees, aid)CALL SCHOLARIS/SCREFLD
Run the term assessment cycleCALL SCHOLARIS/SCTERM (or SBMJOB it)
Run the daily lunch + cash cycleCALL SCHOLARIS/SCDAILY
Run the monthly close cycleCALL SCHOLARIS/SCMONTH

The batch cycles take no CALL parameters. Unlike a control-row-driven design, each SCHOLARIS/i batch program carries its processing dates as literals in the source (the term run posts for period 20260901 / due 20260915; the plan run dates 20261001; the aging run dates 20261025; the GL batch is 202610), so a scheduled submission is a bare CALL. Only SCMENU, SCSTUIQ and SCLEDIQ are interactive; the batch programs run to completion and DSPLY a one-line result per step.

B.2 The menu & inquiry screens

Three interactive programs share the shipped DSPFs. The menu (SCMENU over SCMENUD) simply routes: option 1 CALLs SCSTUIQ, option 2 CALLs SCLEDIQ, any other non-blank option sets 'Invalid option.' and re-displays the menu; F3 ends it. Both inquiries return to the menu on F3.

Student / family inquiry (SCSTUIQ / SCSTUD) — a plain screen

Key a student number and press Enter. SCSTUIQ CHAINs SCSTU for the master, then SCFAM for the billing family (showing the derived family AR balance), then SCLUNCH for that student's prepaid lunch balance. A miss clears the detail and reports 'Student not found.'; a student with no lunch account leaves the lunch field blank rather than showing a stale value.

Student / Family Inquiry - SCHOLARIS/i Student number : S00001 Student name . : MIA ALVAREZ Grade . . . . : K5 Status . . . . : A Family . . . . : ALVAREZ HOUSEHOLD Family balance : 4,350.00 Lunch balance : 42.75 Student and family found. F3=Exit Enter=Inquire

Family ledger inquiry (SCLEDIQ / SCLEDD) — the subfile screen

Key a family number and press Enter. SCLEDIQ CHAINs SCFAM for the header (family name + derived balance), then walks SCLEDG on the family key and loads one subfile row per open ledger item in sequence order. The subfile is SFLPAG(5) per page over SFLSIZ(20) with Roll paging (ROLLUP/ROLLDOWN), so a longer ledger pages.

Family Ledger Inquiry - SCHOLARIS/i Family number: F00002 Family name . : BRENNAN HOUSEHOLD Family balance : 3,075.00 Seq Ty Description Amount Open Age 1 T TUITION - 08 2,800.00 2,800.00 0 2 F REGISTRATION FEE 150.00 150.00 0 3 F ACTIVITY FEE 75.00 75.00 0 4 F SCIENCE LAB FEE 50.00 50.00 0 Family found. F3=Exit Roll=Page Enter=Inquire

Subfile columns (LSFL record)

FieldType (DDS)Shows
SSEQ5S,0 outputLedger sequence number (LSEQ).
STYPE1A outputLine type: T tuition, F fee, A aid credit, L late fee.
SDESC25A outputLine description (e.g. SCIENCE LAB FEE).
SAMT12A outputCharge as raised (LAMT; aid credits are negative).
SOPEN12A outputOutstanding amount (LOPEN).
SAGE1A outputAgeing bucket (LAGE): 0 current, 1 =1-30, 2 =31-60, 3 =61+.
A family that exists but carries no open ledger items (e.g. F00003, whose sole enrollment was withdrawn and never assessed) writes zero subfile rows and reports 'No ledger for this family.' rather than a blanket “found”. This message logic was an app-level fix during development (see FINDINGS.md) so the header and message are always trustworthy — which matters because of the engine subfile-render quirk noted in F.4.

B.3 Controls & audit workflow (no four-eyes maker–checker)

Honest statement: SCHOLARIS/i does not model a true four-eyes maker–checker / separate-authorization workflow. There is no “one clerk posts, a second approves” gate: the term assessment, cash application, plan installments, late fees and lunch POS all post immediately when their cycle runs. The manual documents the control model the application does have:

In sum, the control posture is durable audit + idempotency guards + hard invariants (never-negative lunch, aid cap) + trial-balance reconciliation, all enforced in the posting programs and the data, rather than a segregation-of-duties approval workflow.

C. Batch Jobs & the Periodic Cycle ↑ top

SCHOLARIS/i runs as three periodic cycles rather than one monolithic nightly job: a term cycle (tuition + fee assessment), a daily cycle (lunch POS + cash application), and a monthly cycle (plan installments + aging + late fees + lunch sweep + GL close). Each cycle is a CL driver that ADDLIBLE SCHOLARIS, CALLs its programs in a fixed order, and sends a completion banner. The batch programs take no CALL parameters — their processing dates are literals in the source — so a scheduled/JOBQ submission is a bare CALL.

-- first-time setup (once): build/compile objects, seed reference data
CALL PGM(SCHOLARIS/SCSETUP)
CALL PGM(SCHOLARIS/SCREFLD)

-- then submit a (parameterless) cycle
SBMJOB CMD(CALL PGM(SCHOLARIS/SCTERM)) JOB(SCTERM)

C.1 Full batch program set

ProgramCyclePurposeReads / writesDSPLY result
SCREFLDsetup Seed families, students, grade schedules, enrollments, fee items, grade-fee links, aid. Writes SCFAM/SCSTU/SCGRADE/SCENR/SCFEE/SCGFEE/SCAID. SCREFLD FAM=3 STU=4 GRADE=3 ENR=4 FEE=3 GFEE=7 AID=1
SCASSESSterm Assess tuition + fees net of aid for every active enrollment. Reads SCENR/SCSTU/SCGRADE/SCGFEE/SCFEE/SCAID; writes SCLEDG + SCHIST; updates SCFAM. SCASSESS ASSESSED=3 SKIP=1
SCLPOSdaily Apply pending lunch POS charges/reloads; decline overdrafts. Reads/updates SCLTXN/SCLUNCH; writes SCHIST. SCLPOS APPLIED=3 DECLINED=1 SKIP=0
SCCASHdaily Apply unapplied cash receipts against ledger charges. Reads/updates SCRCPT/SCLEDG/SCFAM; writes SCHIST. SCCASH APPLIED=2 SKIP=0
SCINSTmonthly Post one installment per active plan; advance/complete the plan. Reads/updates SCPLAN/SCFAM; writes SCLEDG + SCHIST. SCINST POSTED=1 SKIP=0
SCLATEmonthly Age every open charge; assess one flat late fee per overdue family. Reads/updates SCLEDG/SCFAM; writes SCHIST. SCLATE B0=0 B1=1 B2=11 B3=0 FEES=2
SCLWARNmonthly Report lunch accounts at/below their own warn line (read-only). Reads SCLUNCH only. SCLWARN LOW=1 OK=3
SCGLDSTmonthly Post balanced GL DR/CR pairs for the movement since the last close. Reads SCHIST; SELECT/INSERT into SCGLDIST (embedded SQL). SCGLDST BATCH=202610 ROWS=n
SCGLRPTterm/monthly COBOL AR trial balance: prove ΣLOPEN = ΣFBAL. Reads SCLEDG + SCFAM. SCGLRPT LEDGOPEN / FAMBAL / BALDIFF / ITEMS / FAMS

C.2 Term / daily / monthly detail

Term — SCTERM (SCASSESS → SCGLRPT)

SCASSESS walks SCENR; for each enrollment it skips a withdrawn enrollment (ESTAT≠'A') or a wrong-year row, confirms the student is still active, then for the active enrollment: (1) charges one term's tuition = grade schedule TUITION / 3 as a 'T' ledger line; (2) writes one 'F' ledger line per active fee item linked to the grade for the year; (3) credits any active aid award, capped at the gross charge, as a negative 'A' line; then (4) raises SCFAM.FBAL by the net (gross − aid). It writes the SCHIST rows the GL post later sums. SCGLRPT then proves the trial balance.

Expected DSPLY (3 active enrollments, S00004 withdrawn):
  SCASSESS ASSESSED=3 SKIP=1

Worked arithmetic (from the test oracle):
  S00001 K5   2000.00 tuition + 150 REG + 75 ACT  = 2225.00 gross
              - 500.00 aid                         = 1725.00 net
  S00002 03   2400.00 + 150 + 75                   = 2625.00 net (no aid)
  F00001 balance = 1725.00 + 2625.00              = 4350.00
  S00003 08   2800.00 + 150 + 75 + 50 (LAB)        = 3075.00 net
  F00002 balance                                   = 3075.00
  F00003 balance (S00004 enrollment withdrawn)     =    0.00
  school-wide: gross 7925.00 - aid 500.00          = 7425.00
The lab fee is a genuine per-grade difference, not a flat rider: only grade 08 carries the SCIENCE LAB FEE grade-fee link, so only S00003's ledger gets the 50.00 'F' line. This is why F00001 has 4 fee lines (REG×2 + ACT×2, no LAB) and F00002 has 3 (REG + ACT + LAB).

Daily — SCDAILY (SCLPOS → SCCASH)

SCLPOS applies each pending ('E') lunch transaction in TSEQ order against the student's SCLUNCH balance: a reload ('R') always applies and raises the balance; a charge ('C') applies only if TAMT ≤ LBAL, otherwise it is declined (TSTAT='D', balance unchanged). Because reloads and charges apply in sequence, a reload posted before a charge tops the balance up first. SCCASH then applies each unapplied receipt (RCSTAT='U') against the ledger charge it names: it takes only what is owed (any excess stays unapplied), never touches a negative-open aid credit, lowers SCFAM.FBAL by exactly what it applied, and stamps the receipt 'A' (fully applied) or 'P' (part-applied).

Expected DSPLY:
  SCLPOS APPLIED=3 DECLINED=1 SKIP=0
  SCCASH APPLIED=2 SKIP=0

Lunch worked example:
  S00001  20.00 - 4.50 charge         = 15.50  (applied)
  S00002   3.00 + 20.00 reload        = 23.00, then - 4.50 = 18.50  (TSEQ order)
  S00003  10.00 - 15.00 charge        = DECLINED, stays 10.00  (never-negative)

Cash worked example (against the term ledger):
  RC000001 2000.00 vs S00001 K5 tuition 2000.00 open -> full: open 0.00, P
           F00001 4350.00 -> 2350.00
  RC000002 1000.00 vs F00002 tuition 2800.00 open   -> part: open 1800.00, O
           F00002 3075.00 -> 2075.00; receipt itself fully applied (A)

Monthly — SCMONTH (SCINST → SCLATE → SCLWARN → SCGLDST → SCGLRPT)

SCINST posts one installment per active plan with installments remaining (PLPAID < PLCNT): a new 'T' ledger charge of PLINST, raising FBAL, advancing PLPAID and flipping the plan to 'C' when the last one posts — a plan smooths when money falls due, it does not discount the total. SCLATE runs two passes on a 30/360 date convention: pass 1 ages every open positive charge into bucket 0/1/2/3 by days overdue; pass 2 assesses one flat 25.00 late fee per active family that has any open charge past the 30-day grace (a negative aid-credit line is never aged and never triggers a fee). SCLWARN reports (read-only) any active lunch account at/below its own LWARN line. SCGLDST sums the SCHIST history by type and posts balanced GL pairs for the movement since the last close. SCGLRPT proves the trial balance.

Expected DSPLY:
  SCINST POSTED=1 SKIP=0
  SCLATE B0=0 B1=1 B2=11 B3=0 FEES=2
  SCLWARN LOW=1 OK=3
  SCGLDST BATCH=202610 ROWS=n

GL balanced pairs (worked, from the test oracle):
  DR 1400-FAR  7975.00   (charges: tuition 7200 + fees 725 + late 50)
  CR 4100-TUIT 7200.00 / CR 4200-FEE 725.00 / CR 4300-LATE 50.00
  DR 5100-AID   500.00 / CR 1400-FAR 500.00   (the aid pair, its own balanced leg)
  => SUM(DR) = SUM(CR) to the cent
The plan installment posts as ledger type 'T' but writes an SCHIST row of type 'I', which is not part of the T/F/A/L taxonomy SCGLDST recognises, so the installment does not double-count into tuition revenue. The GL sums history, not the ledger. Aging is genuinely per-charge: in the test month F00002's original term charges land in bucket 2 (40 days overdue) while its fresh 1-Oct installment lands in bucket 1 (24 days overdue).

C.3 Ordering & dependencies

D. Data Files (data dictionary) ↑ top

All files are in library SCHOLARIS, grounded in the DDS/SQL source in src/sources.mjs. Dates are stored as signed numeric in YYYYMMDD form; money is packed decimal. Field types are given as they appear in DDS (P packed, S zoned, A character).

SCFAM — Family / payer master (K FAMNO)

FieldTypeMeaning
FAMNO6AFamily number (key), e.g. F00001.
FNAME / FADDR / FPHONE30A / 30A / 14AName, address, phone.
FBAL11P 2Running AR balance — the spine; moved only up (charge) and down (cash).
FSTAT1AA active, I inactive (withdrawn, no current enrollments).

SCSTU — Student master (K STUNO)  /  SCSTULF (LF, K FAMNO)

FieldTypeMeaning
STUNO6AStudent number (key), unique school-wide, e.g. S00001.
SNAME30AStudent name.
FAMNO6ABilling family.
GRADE2AGrade (drives which tuition schedule applies), e.g. K5, 08.
SSTAT1AA active, W withdrawn, G graduated.

SCSTULF is a non-unique logical over SCSTU keyed by FAMNO, so a family's whole roster can be walked without scanning the student file.

SCGRADE — Grade-level tuition schedule (K GRADE, SCHYR)

FieldTypeMeaning
GRADE2AGrade.
SCHYR4S 0School year.
TUITION11P 2Standing annual tuition (term charges one-third).
GSTAT1AA active.

Seeded 2026 schedule: K5 6000.00, grade 03 7200.00, grade 08 8400.00.

SCENR — Enrollment (K STUNO, SCHYR)

FieldTypeMeaning
STUNO / SCHYR6A / 4S 0Student + school year (key).
GRADE2AGrade enrolled for the year.
ENRDT8S 0Enrollment date (YYYYMMDD).
ESTAT1AA active, W withdrawn (the term run skips a withdrawn enrollment).

SCFEE — Fee-item master (K FEECD, SCHYR)  /  SCGFEE — grade-fee links (K GRADE, FEECD)

FieldTypeMeaning
FEECD4AFee code, e.g. REG, ACT, LAB.
SCHYR4S 0School year.
FEEDESC20ADescription (e.g. SCIENCE LAB FEE).
FAMT9P 2Flat per-term amount.
FSTAT21AA active (charged), S suspended (waived this year).

SCGFEE maps (GRADE, FEECD, SCHYR): which fee items apply to which grade. Seeded links: REG + ACT for every grade, LAB for grade 08 only.

SCAID — Financial-aid award (K STUNO, SCHYR)

FieldTypeMeaning
STUNO / SCHYR6A / 4S 0Student + school year (key).
AWDAMT11P 2Flat award (SCASSESS caps it at the gross charge).
ASTAT1AA active award, D declined/withdrawn.

SCLEDG — Family AR open-item ledger (K FAMNO, LSEQ)  /  SCLEDLF (LF, K LDUE, FAMNO)

FieldTypeMeaning
FAMNO / LSEQ6A / 5S 0Family + per-family sequence (key).
LTYPE1AT tuition, F fee, A aid credit (negative), L late fee.
LDT / LDUE8S 0Charge date / due date (YYYYMMDD).
LAMT11P 2Charge as raised (never changed after posting; aid credits are negative).
LOPEN11P 2Outstanding amount (LAMT less cash applied; an aid credit's LOPEN is negative).
LAGE1S 0Ageing bucket stamped by SCLATE: 0/1/2/3.
LDESC25ALine description.
LSTAT1AO open, P part/paid (LOPEN reached 0).

SCLEDLF is a logical over SCLEDG keyed by due date, so the aging run can walk oldest-due-first — the access path an ageing report wants and the family-keyed PF cannot give.

SCPLAN — Payment plan (K FAMNO)

FieldTypeMeaning
FAMNO6AFamily (key).
PLTOT11P 2Total enrolled under the plan.
PLINST11P 2Flat installment amount due each month.
PLCNT / PLPAID3S 0Installment count / installments posted so far.
PSTAT1AA active, C completed (all installments posted).

SCRCPT — Cash receipts (K RCPTNO)

FieldTypeMeaning
RCPTNO8AReceipt number (key), e.g. RC000001.
FAMNO / RCLSEQ6A / 5S 0Family and the ledger LSEQ this receipt names.
RCDT8S 0Receipt date.
RCAMT / RCAPPL11P 2Amount tendered / amount actually applied.
RCSTAT1AU unapplied, A fully applied, P part-applied.

SCLUNCH — Prepaid lunch/POS account (K STUNO)  /  SCLTXN — lunch transactions (K STUNO, TSEQ)

FieldTypeMeaning
STUNO6AStudent (key).
LBAL9P 2Prepaid balance — NEVER goes negative.
LWARN9P 2Low-balance threshold the monthly sweep alerts against.
LSTAT1AA active.
SCLTXN fieldTypeMeaning
STUNO / TSEQ6A / 5S 0Student + transaction sequence (key; apply order).
TTYPE1AC charge (reduces balance), R reload (increases balance).
TDT / TAMT8S 0 / 9P 2Date / amount (always positive; sign implied by TTYPE).
TDESC20ADescription.
TSTAT1AE entered/pending, A applied, D declined (insufficient balance).

SCHIST — Durable audit trail (K HSEQ)

FieldTypeMeaning
HSEQ8S 0Stable, business-key-derived sequence (key; disjoint ranges per program — see F.3).
HKEY8AThe business key (student or family) the row was derived from.
HTYPE1AT tuition, F fee, A aid, P cash payment, I plan installment, L late fee.
HDT / HAMT8S 0 / 11P 2Date / amount (cash is negative).
HREF / HMEMO8A / 25AReference and free-text memo.

SCGLDIST — GL distribution (SQL, PK GLSEQ)  /  index SCGLDACC

ColumnTypeMeaning
GLSEQDECIMAL(8,0)Sequence (PK).
GLBATCHDECIMAL(6,0)Batch YYYYMM.
ACCTCHAR(9)Account, e.g. 1400-FAR, 4100-TUIT, 4200-FEE, 4300-LATE, 5100-AID.
DRCRCHAR(1)D debit, C credit.
AMTDECIMAL(11,2)Amount.
GLREF / GLDTCHAR(8) / DECIMAL(8,0)Reference / date.

Index SCGLDACC is on (ACCT, DRCR) — the access path the incremental GL post uses to sum what has already been debited per account.

Relationships

E. Operations Runbook ↑ top

E.1 Term-in-the-life

  1. Once, at first setup: CALL SCHOLARIS/SCSETUP (build/compile every object), then CALL SCHOLARIS/SCREFLD (seed reference data). Confirm the banner SCREFLD FAM=3 STU=4 GRADE=3 ENR=4 FEE=3 GFEE=7 AID=1.
  2. At the start of a term: submit the assessment cycle SBMJOB CMD(CALL PGM(SCHOLARIS/SCTERM)).
  3. Post-check the term run (see below).
  4. Each business day: load the day's lunch POS transactions and cash receipts as pending rows, then submit SCDAILY. Check the SCLPOS/SCCASH lines.
  5. Handle interactive lookups through CALL SCHOLARIS/SCMENU (option 1 student inquiry, option 2 family ledger) as questions arrive.

Pre-checks: confirm the job's library list includes SCHOLARIS; confirm reference data is seeded (a fresh library needs SCREFLD before SCTERM can assess anything).

Post-checks after the term cycle:

E.2 Month-end close

  1. Confirm the term assessment has run and the month's daily cycles (lunch + cash) are all applied.
  2. Load any payment-plan rows (SCPLAN) that should post an installment this month.
  3. Submit SCMONTH. Confirm the completion banner and the four DSPLY lines (SCINST/SCLATE/SCLWARN/SCGLDST).
  4. Reconcile the GL distribution:
SELECT ACCT, DRCR, SUM(AMT) FROM SCHOLARIS.SCGLDIST GROUP BY ACCT, DRCR;
SELECT SUM(CASE WHEN DRCR='D' THEN AMT ELSE -AMT END) AS NET FROM SCHOLARIS.SCGLDIST;

Reconciling figures (the same ones the monthly volume simulation checks against a hand-derived oracle):

Ad-hoc statement: the AR ageing / billing report writes through the SCAGEP printer file (header AGEHDR, one AGEDTL per aged line, an AGETOT footer with item count and total outstanding).

E.3 Failure & re-run rules

Each program DSPLYs a one-line result. A healthy chain also ends with the completion banner its CL driver sends. Because every posting program guards on a stable history key, most cycles are safe to re-run.

SituationBehaviourAction
Re-run the term cycleEvery student already has its tuition history row; all are skipped.Safe: the second run reports ASSESSED=0 SKIP=4 and family balances are unchanged. Idempotent.
Re-run the daily cycleApplied transactions/receipts have left their pending state; nothing new matches.Safe: SCLPOS APPLIED=0 DECLINED=0 SKIP=4, SCCASH APPLIED=0 SKIP=2; balances unchanged.
Re-run SCLATE / SCGLDST in the same periodLate-fee guard key is stable per run date; GL posts only the movement since the last close.Safe: SCLATE FEES=0 on the second call; the GL debit total does not double.
Re-run SCINST across a genuinely new monthThe guard key is derived from PLPAID+1, so a new month posts the NEXT installment.Correct by design: installment #2, then #3, then the plan completes (PSTAT='C'); a further call reports POSTED=0 SKIP=1.
Lunch charge would overdrawSCLPOS declines it (TSTAT='D'), balance unchanged.Reload the account (a 'R' transaction) and re-run; the never-negative invariant is intentional, not an error.
Cash receipt exceeds the open chargeSCCASH applies only what is owed; the excess stays unapplied (receipt 'P').Raise a further receipt against another open charge, or leave the remainder unapplied.
Because every money movement is journaled to SCHIST and every charge to SCLEDG with a live LOPEN, any cycle's effect is fully reconstructable after the fact, and SCGLRPT's BALDIFF is the single number that confirms the book still balances.

F. Developer Reference ↑ top

The full program surface, from src/sources.mjs. Programs are fixed-form RPG IV with embedded /free blocks (built by the C()/D() column-exact helpers), one SQLRPGLE, and one ILE COBOL. All objects are in library SCHOLARIS.

F.1 Batch programs

SCREFLD — reference-data loader
Writes the seeded families, students, grade schedules, enrollments, fee items, grade-fee links and one aid award, then DSPLYs the count banner. Mirrors the sibling apps' RLREFLD/PYREFLD loaders.
SCASSESS — term tuition + fee assessment
Reads SCENR; per active in-year enrollment: CHAINs SCSTU (family + still-active check), CHAINs SCGRADE for TUITION/3, walks the grade's SCGFEE links CHAINing each active SCFEE, caps SCAID at the gross, writes the T/F/A ledger lines and history rows, and raises SCFAM.FBAL by the net. The next LSEQ is found by a SETLL/READE partial-key walk keeping the highest seq seen.
SCCASH — cash-receipt application
Reads SCRCPT; for each unapplied receipt CHAINs the named SCLEDG charge (KLIST FAMNO+LSEQ), takes min(RCAMT, LOPEN) of a POSITIVE open charge (never an aid credit), lowers SCFAM.FBAL, writes a negative-amount 'P' history row, and stamps the receipt A/P.
SCLPOS — lunch POS run
Reads SCLTXN in key (TSEQ) order; a reload always applies, a charge applies only if it fits the balance else it is declined; re-CHAINs the transaction row after each SCLUNCH update (the update moved the file cursor) to stamp A/D. DSPLYs applied/declined/skip counts.
SCINST — plan installment posting
Reads SCPLAN; for an active plan with PLPAID < PLCNT posts one PLINST as a 'T' ledger charge, raises FBAL, advances PLPAID and flips PSTAT to 'C' on the last one.
SCLATE — AR aging + late fees
Pass 1 sequentially ages every open positive charge (30/360 serial, bucket 0/1/2/3, updating LAGE). Pass 2 walks SCFAM, and per family re-walks its own ledger rows to decide if any open charge is past the 30-day grace, assessing at most one flat 25.00 late fee (its own ledger line + history row + FBAL bump). Aid credits are never aged and never trigger a fee.
SCLWARN — lunch low-balance sweep
Read-only over SCLUNCH: counts active accounts at/below their own LWARN line vs OK, DSPLYs the tally. Never mutates a balance.
SCGLDST — GL distribution (SQLRPGLE)
Accumulates SCHIST by type (T/F/A/L), reads what has already been debited to 1400-FAR and 5100-AID via EXEC SQL SELECT, and posts only the movement since the last close as balanced pairs (the glrow subroutine INSERTs and counts only sqlcod=0 rows). The financial-aid pair is posted separately so DR total = CR total.
SCGLRPT — COBOL trial balance
Sequentially sums every SCLEDG.LOPEN and every SCFAM.FBAL, then DISPLAYs LEDGOPEN, FAMBAL, BALDIFF (should be 0.00), ITEMS and FAMS. Proves the AR sub-ledger reconciles to the family master.

F.2 Interactive programs

SCMENU (over SCMENUD)
EXFMTs the menu in a loop; option 1 CALLs SCSTUIQ, 2 CALLs SCLEDIQ, any other non-blank sets 'Invalid option.'; *IN03 (F3) ends.
SCSTUIQ (over SCSTUD)
Plain screen. EXFMT/CHAIN SCSTUSCFAMSCLUNCH, editing FBAL/LBAL with %editc(:'K'). Clears detail and reports the outcome message; a miss says 'Student not found.', a family-less student 'Student found -- no family on file.'
SCLEDIQ (over SCLEDD, subfile)
SFL/SFLCTL subfile. Clears the subfile with *IN31 (SFLCLR) after the EXFMT returns the new key, CHAINs SCFAM for the header, then SETLL/READE SCLEDG on the family key writing one LSFL row per open item. The message is decided AFTER the load from RRN: 'Family found.' if rows loaded, else 'No ledger for this family.'

F.3 The idempotency-key scheme (SCHIST disjoint ranges)

There is no control table and no transaction sequence generator. Instead, every posting program derives its SCHIST.HSEQ from a stable business key in a range disjoint per program, CHAINs SCHIST on it before posting (CHAIN(EN)), and skips if the row already exists. A re-run regenerates the same key and is refused — this is the app's idempotency guard.

ProgramHSEQ formulaBaseStable across
SCASSESS10000000 + student-digits×10 + component#10Msame term (per student, per component)
SCCASH20000000 + receipt-digits20Mthe receipt (applied once)
SCLATE30000000 + family-digits30Mthe run date (one fee per family)
SCINST40000000 + family-digits×100 + installment#40Mone installment number (advances by month)
SCLPOS50000000 + student-digits×1000 + txn-seq50Mthe transaction (applied once)

Because the ranges are disjoint, the five programs never collide, and each is idempotent in exactly the sense its business needs: SCASSESS/SCCASH/SCLPOS/SCLATE are period-stable (a re-run posts nothing), while SCINST's key advances with the installment number so a genuinely new month posts the next installment — and refuses a second post of the same number.

F.4 Engine notes & a subfile quirk

Two implementation details are documented in the source and matter operationally:

Subfile stale-detail-row on re-EXFMT (platform-side, cross-referenced). On a SECOND enquiry in the same SCLEDIQ session, if the new family has FEWER or ZERO ledger rows than the first, the previous enquiry's detail rows can remain visible on the rendered screen alongside the new (correct) header and message, and the SFLEND(*MORE) indicator may still show. This is not an SCLEDIQ logic fault: the program issues SFLCLR (*IN31) before the reload, the header is re-derived correctly, and the row-count (RRN) and SCLEDG reads are correct — proven by the interactive test asserting the header/balance/message change. The discrepancy is in the emulator's render path for SFLCLR/EXFMT re-display. It is the same recurring quirk already logged against the UNMODIFIED sibling apps — payroll (PYSLPIQ) and mrp (FGWOIQ); SCLEDIQ reproducing it on a third, independently written subfile program is what strengthens the case that the fault is platform-side (the estate's NA-07 area). No engine change is made (hard rule); the app's message logic was fixed so the header and message are always trustworthy even if stale rows show. Trust the header, balance and message — not the detail rows — on a repeat enquiry.

G. Glossary ↑ top

AR (accounts receivable)
What families owe the school. The running total per family is SCFAM.FBAL, backed by the open-item ledger SCLEDG.
Ageing bucket
How overdue an open charge is, by days past its due date: 0 current, 1 =1-30, 2 =31-60, 3 =61+ (SCLEDG.LAGE, stamped by SCLATE on a 30/360 convention).
Enrollment
The fact (SCENR) tying a student to a grade for a school year — the thing the term assessment bills. A withdrawn enrollment (ESTAT='W') is skipped even if the student master is active.
Family balance (FBAL)
The spine of the application: a family's running AR balance, moved up only by a charge and down only by cash. Never edited directly.
Financial-aid credit
A scholarship/award (SCAID) posted as a NEGATIVE ledger line, capped at the gross charge, so the family's net charge is gross minus aid.
Gross vs net charge
Gross = one term's tuition + the grade's fees; net = gross minus any aid credit. The family balance rises by the net.
Idempotent
Safe to run again with the same result. Here enforced by a CHAIN(EN) guard on a stable, business-key-derived SCHIST.HSEQ (see F.3). Term/daily/late/GL cycles are idempotent within a period; plan installments advance across months by design.
Lunch / POS account
A student's prepaid meal balance (SCLUNCH). A charge that would overdraw it is declined — the never-negative invariant.
Never-negative invariant
The rule that a prepaid lunch balance is never allowed below zero: SCLPOS declines an overdrawing charge rather than applying it.
Open item / LOPEN
A ledger charge's outstanding amount, reduced as cash is applied; SCGLRPT proves ΣLOPEN = ΣFBAL.
Payment plan
An installment arrangement (SCPLAN) that smooths WHEN a family's charges fall due; SCINST posts one installment per month as a ledger charge. It does not discount the total owed.
SBMJOB
Submit Job — the IBM i command that queues a program as a batch job (e.g. SBMJOB CMD(CALL PGM(SCHOLARIS/SCTERM))).
Subfile
A 5250 display construct listing many rows on one screen (DDS SFL/SFLCTL). SCLEDIQ's family ledger list is a subfile.
Trial balance (SCGLRPT)
The COBOL reconciliation proving the AR sub-ledger ties to the family master; its BALDIFF is the single “does the book balance” number.