ESTATE/i — Fixed Assets & Depreciation

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

ESTATE/i is a fixed-asset accounting application: acquisition and capitalisation, three depreciation methods (straight-line, declining-balance, units-of-production) posted monthly with a GL distribution, asset transfer between cost centres, disposal with gain/loss, weekly maintenance and warranty sweeps, and a year-end register with a fully-depreciated retirement roll. The business logic is classic RPG IV over keyed DDS physical/logical files, with one ILE COBOL summary program and one SQLRPGLE program that posts the GL distribution to a DB2 for i table; the four periodic cycles are driven by CL. This manual is the reference for the operator who runs the periodic cycles and the online inquiry screens, and for the developer maintaining the application. It is grounded entirely in the committed source (assets-app/src/sources.mjs, src/seed.mjs, and the test/fa_*.mjs drivers), which loads library ESTATE.

Contents

A. Overview & Architecture ↑ top

A.1 What it does

ESTATE/i accounts for the full life of a fixed asset:

A.2 Architecture & the ledger discipline

The application is classic IBM i: RPG IV programs orchestrate keyed DDS files, one ILE COBOL program produces an independent depreciation summary, one SQLRPGLE program posts the GL distribution with embedded SQL, and CL ties the objects together into a setup job and four periodic cycles. Everything lives in library ESTATE.

There is no CICS, no transaction-id switch and no single monolithic nightly job: work is organised as a daily, a weekly, a monthly and an annual CL cycle, each calling a small set of RPG/COBOL programs in a fixed order.

A.3 Component & flow

  ONLINE (5250)          DAILY  FADAILY        MONTHLY  FAMONTH
  ------------           --------------        ---------------
  FAMENU                 FAACQ    (capitalise) FADEPRUN (depreciate, 3 methods)
   opt 1 -> FAASTIQ      FAXFRUN  (transfer)   FAGLPST  (GL distribution, SQL)
   opt 2 -> FADEPIQ      FADISPOS (dispose)    FADEPSUM (COBOL proof summary)

  WEEKLY  FAWEEK         ANNUAL  FAYEAR
  -------------          --------------
  FAMTSWP (maint due)    FARETIRE (retire fully-depreciated)
  FAWARN  (warranty)     FANBVRL  (NBV roll, invariant)
  FACCRPT (cctr summary) FAREGEN  (register snapshot) -> FAREGPR (print)

                    +-- reads policy --  FACLASS
                    |
   FAASSET  <--------- every program --  (master; keyed also by cctr via FAASTLF)
     |  \
     |   +--> FADEPH  (per-asset-per-period history; -> FAGLDIST via FAGLPST)
     |   +--> FALEDG  (C capitalise / X transfer / S sale / P depn / F retire)
     +------> FAREG   (year-end register snapshot)   FADEPPER (data area: period)

A depreciation event flows: operator sets the period in data area FADEPPER → submits FAMONTHFADEPRUN reads the period, walks every in-service asset, computes the charge by method, writes a FADEPH row and rolls the master → FAGLPST reads the period through the period-keyed logical and writes balanced DR/CR rows to FAGLDISTFADEPSUM (COBOL) independently totals the period by method as a proof.

A.4 Object inventory

ObjectTypeRole
FAASSETPFAsset master (the spine), keyed by ASTNO.
FAASTLFLFAsset master keyed by cost centre (CCTR, ASTNO).
FACLASSPFAsset-class master: default depreciation policy + GL accounts.
FACCTRPFCost-centre master.
FADEPHPFDepreciation history, composite key (ASTNO, DPER).
FADEPLFLFDepreciation history keyed by period (DPER, ASTNO).
FAXFERPFTransfer request log, keyed by XSEQ.
FADISPPFDisposal request log, keyed by ASTNO.
FAMAINTPFMaintenance schedule, composite key (ASTNO, MSEQ).
FALEDGPFDurable accumulating asset ledger, keyed by LSEQ.
FAREGPFYear-end register snapshot, composite key (RYEAR, ASTNO).
FAGLDISTSQL tableGL distribution rows (DR/CR), keyed by GLSEQ.
FAASTD / FADEPD / FAMENUDDSPFInquiry / subfile / menu display files.
FAREGPPRTFFixed-asset register printer file.
FADEPPER*DTAARACHAR(10) data area carrying the depreciation period.
FAREFLDRPGLEReference-data / seed loader (classes, cost centres, assets, maintenance).
FAACQ / FAXFRUN / FADISPOSRPGLEDaily: capitalise / transfer / dispose.
FADEPRUNRPGLEMonthly depreciation calculation & posting.
FAGLPSTSQLRPGLEMonthly GL distribution (embedded SQL).
FADEPSUMCBLLEILE COBOL depreciation summary (independent proof).
FAMTSWP / FAWARN / FACCRPTRPGLEWeekly: maintenance sweep / warranty report / cost-centre summary.
FARETIRE / FANBVRL / FAREGEN / FAREGPRRPGLEAnnual: retire / NBV roll / register generate / register print.
FAASTIQ / FADEPIQ / FAMENURPGLEOnline: asset inquiry / depreciation-history subfile / menu.
FASETUPCLPCreates every object & compiles every program.
FADAILY / FAWEEK / FAMONTH / FAYEARCLPThe four periodic job cycles.

The catalogue is 11 DDS files (9 PF + 2 LF) + 1 SQL table + 1 data area, 3 display files and 1 printer file, driven by 16 RPG programs, 1 COBOL program and 5 CL programs. Sections D and F expand each.

B. Online Transactions & Screens ↑ top

B.1 The command/entry line

ESTATE/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 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 ESTATE — the tested jobs run with LIBL = QSYS QGPL ESTATE QTEMP and CURLIB = ESTATE.

To do thisType on the command line
Open the operator menu (both inquiries)CALL ESTATE/FAMENU
Open the asset inquiry screen directlyCALL ESTATE/FAASTIQ
Open the depreciation-history subfile directlyCALL ESTATE/FADEPIQ
Build/compile the whole applicationCALL ESTATE/FASETUP
Load reference/seed dataCALL ESTATE/FAREFLD
Run the daily / weekly cycleCALL ESTATE/FADAILY / FAWEEK (or SBMJOB)
Set the depreciation period, then run monthlyCHGDTAARA DTAARA(ESTATE/FADEPPER) VALUE(' 202608') then CALL ESTATE/FAMONTH
Run the annual register rollCALL ESTATE/FAYEAR

The batch programs take no CALL parameters. The daily, weekly and annual programs read the run date they need from constants compiled into the source (see the note in C.2); the monthly depreciation and GL programs read the processing period from the FADEPPER data area (default ' 202608'), so a scheduled submission sets that data area, then simply calls the cycle. Only FAMENU, FAASTIQ and FADEPIQ are interactive.

B.2 The menu & the two inquiry screens

Honest statement: the online surface is read-only inquiry plus a menu. There is no maintenance screen: an operator cannot capitalise, transfer, dispose, depreciate or edit an asset from 5250. Those are all batch actions (section C). The three interactive programs are:

FAMENU / FAMENUD — the operator menu

FAMENU presents a two-option menu and routes to the inquiries by a program-to-program CALL: option 1 calls FAASTIQ, option 2 calls FADEPIQ, any other non-blank option shows Invalid option. on the menu itself. F3 ends the program.

ESTATE/i Main Menu 1. Asset Inquiry 2. Depreciation History Option . . . . : _ F3=Exit Enter=Select

FAASTIQ / FAASTD — asset inquiry (plain screen)

A non-subfile screen: key an asset number in IAST and press Enter; the program CHAINs FAASSET and renders the master record with the net book value derived on screen as COST - ACCDEP (work field WN, edited with %editc(...:'K')). An unknown key shows Asset not found. and blanks every value rather than leaving the previous asset's figures stale.

Asset Inquiry - ESTATE/i Asset number: AS100001 Description . : CNC LATHE CELL 1 Class / Ctr . : PLNT CC10 Method . . . . : S Cost . . . . . : 60,000.00 Salvage . . . : 6,000.00 Accum depn . . : 5,400.00 Net book value : 54,600.00 Status . . . . : A Asset found. F3=Exit Enter=Inquire
FieldDDSShows
IAST8A input/outputAsset number keyed by the operator.
DDESC / DCLS / DCCoutputDescription, class code, cost centre.
DMTH1A outputDepreciation method (S / D / U).
DCOST / DSALV / DACC14A outputCost, salvage, accumulated depreciation (edited).
DNBVF14A outputDerived net book value = cost − accumulated.
DSTS1A outputStatus (P/A/D/F).
DMSG50A outputResult message (found / not found).

FADEPIQ / FADEPD — depreciation-history inquiry (subfile)

A subfile screen (DDS record DSFL under control record DCTL, SFLPAG(0005) per page, SFLSIZ(0020)): key an asset, and the program loads that asset's period charges from FADEPH (via a keyed READE group) into the subfile, showing period, method, charge, running accumulated and running NBV. It uses a classic load-then-display discipline: it writes SFLCLR (indicator 31) to wipe the previous enquiry, resets the relative record number, then re-loads the rows for the asset actually asked for before the next EXFMT. Roll Up/Roll Down page a longer history (an asset with 6 periods shows 5 on page one, the 6th on Roll Up).

Depreciation History - ESTATE/i Asset: AS100001 Description . : CNC LATHE CELL 1 Cost . . . . . : 60,000.00 Accum depn . . : 5,400.00 Period M Charge Accum NBV 202608 S 900.00 900.00 59,100.00 202609 S 900.00 1,800.00 58,200.00 202610 S 900.00 2,700.00 57,300.00 202611 S 900.00 3,600.00 56,400.00 202612 S 900.00 4,500.00 55,500.00 F3=Exit Roll=Page Enter=Inquire
The subfile columns (SPER SMTH SAMT SACC SNBV) are all output; the operator keys only the asset number (IDAST). Re-enquiring on an asset with no history correctly clears the subfile to zero rows and still resolves the header. These are the shipped screens exercised by test/fa_interactive.mjs over the real in-process 5250 session.

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

Honest statement: ESTATE/i does not model a four-eyes maker–checker / separate-authorization workflow, and it has no online data-entry at all. A capitalisation, transfer, disposal or depreciation posting is actioned by its batch program the next time the cycle runs; there is no "one user requests, a second user approves" gate in the code. The control model the application does have is:

In sum the control posture is request/state gating + a durable ledger + idempotency + the depreciable-base invariant, all in the batch/data layer, rather than an online segregation-of-duties workflow.

C. Batch Jobs & the Periodic Cycle ↑ top

ESTATE/i runs as four CL cycles rather than one monolithic nightly job: a daily cycle (acquisition, transfer, disposal), a weekly cycle (maintenance sweep, warranty report, cost-centre summary), a monthly cycle (depreciation, GL distribution, COBOL summary) and an annual cycle (retirement, NBV roll, register generate + print). Each cycle is a CL program that ADDLIBLEs ESTATE, CALLs its programs in a fixed order and sends a completion banner.

-- the monthly cycle takes its period from a data area; set it, then submit
CHGDTAARA DTAARA(ESTATE/FADEPPER) VALUE('    202608')
SBMJOB CMD(CALL PGM(ESTATE/FAMONTH)) JOB(FAMONTH)

-- the other cycles are parameterless
SBMJOB CMD(CALL PGM(ESTATE/FADAILY)) JOB(FADAILY)

C.1 Full batch program set

ProgramCyclePurposeReadsWrites / DSPLY
FAACQDailyCapitalise every pending ('P') asset.FAASSET, FACLASSAsset→'A', INSVDT, NBV; FALEDG 'C'; FAACQ CAPITALISED=n SKIP=n.
FAXFRUNDailyAction 'R' transfer requests to a valid open cost centre.FAXFER, FAASSET, FACCTRAsset CCTR moved; request→'C'; FALEDG 'X'; FAXFRUN TRANSFERRED=n SKIP=n.
FADISPOSDailyAction 'R' disposal requests; compute NBV & gain/loss.FADISP, FAASSETAsset→'D', NBV 0; request→'C'; FALEDG 'S' (signed); FADISPOS DISPOSED=n SKIP=n.
FAMTSWPWeeklyFlag maintenance schedules due on/before the sweep date.FAMAINT, FAASSETSchedule→'D'; FAMTSWP DUE=n SKIP=n COST=n.
FAWARNWeeklyReport schedules whose warranty has expired.FAMAINT, FAASSETPer-asset DSPLY + FAWARN EXPIRED=n INWARR=n.
FACCRPTWeeklyCost-centre asset summary over the CCTR access path.FACCTR, FAASTLFPer-centre DSPLY FACCRPT cc N=n COST=n NBV=n.
FADEPRUNMonthlyDepreciate every in-service asset for the period (3 methods).FAASSET, FADEPH, FADEPPERFADEPH row + master roll; FALEDG basis; FADEPRUN PER=p POSTED=n SKIP=n.
FAGLPSTMonthlyGL distribution: balanced DR/CR by cost centre (embedded SQL).FADEPLF, FAASSET, FACCTR, FADEPPERFAGLDIST rows; FAGLPST PER=p ROWS=n TOTAL=n.
FADEPSUMMonthlyILE COBOL: total the period's history by method (proof).FADEPHDSPLY STRAIGHT / DECLINE / UNITS / TOTAL / ROWS.
FARETIREAnnualRetire fully-depreciated in-service assets.FAASSET, FALEDGAsset→'F'; FALEDG 'F'; FARETIRE RETIRED=n SKIP=n.
FANBVRLAnnualRe-roll NBV = cost−accum, clamping to the invariant.FAASSETMaster NBV; FANBVRL ASSETS=n NBV=n CLAMPED=n.
FAREGENAnnualSnapshot one register row per live asset for the year.FAASSET, FAREGFAREG rows; FAREGEN YEAR=y LINES=n NBV=n SKIP=n.
FAREGPRAnnualPrint the register (PRTF, page overflow).FAREG, FAASSET, FAREGPSpooled register; FAREGPR LINES=n NBV=n.
FAREFLDSetupLoad reference & seed data.FACLASS, FACCTR, FAASSET (pending), FAMAINT; FAREFLD CLASSES=4 CCTR=3 ASSETS=7 MAINT=4.

C.2 Daily / weekly / monthly / annual detail

Daily — FADAILY (FAACQ → FAXFRUN → FADISPOS)

FAACQ reads the master sequentially; each asset at ASTAT='P' is capitalised: derive the stable ledger key 10000000 + %dec(%subst(astno:3:6):8:0), refuse (skip) if that ledger row already exists, otherwise CHAIN the class for policy, write the FALEDG 'C' row, re-CHAIN the asset, stamp INSVDT=ACQDT, set NBV=COST-ACCDEP, move to 'A'. FAXFRUN walks FAXFER; for a 'R' request whose destination cost centre exists and is open (CCSTAT='A'), it moves the asset's CCTR, writes a FALEDG 'X' row keyed 20000000 + XSEQ, and flips the request to 'C' (a transfer carries NBV as information only — cost/accum/NBV do not change). FADISPOS walks FADISP; for a 'R' request it snaps cost and accumulated, computes NBV = cost−accum and gain/loss = proceeds−NBV, zeroes the asset's NBV, moves it to 'D', writes a signed FALEDG 'S' row (memo GAIN or LOSS) keyed 30000000 + asset digits, and closes the request.

Expected DSPLY (7 seeded pending assets, 1 valid + 1 bad transfer, 2 disposals):
  FAACQ CAPITALISED=  7 SKIP=  0        capitalised value totals 247200.00
  FAXFRUN TRANSFERRED=  1 SKIP=  1      CC99 destination refused
  FADISPOS DISPOSED=  2 SKIP=  0        gain +2000.00, loss -3500.00

Weekly — FAWEEK (FAMTSWP → FAWARN → FACCRPT)

FAMTSWP flags every MSTAT='S' schedule whose NEXTDT falls on or before the sweep date (compiled constant WRUNDT = 20260815) whose asset is still in service, setting it 'D' and accumulating its MCOST. FAWARN counts and names schedules whose WARRDT has passed the run date. FACCRPT reads each cost centre's assets through the CCTR-keyed logical FAASTLF (a genuine alternate access path — a keyed READE group, not a full-master scan per centre) and summarises count / cost / NBV.

Expected DSPLY (sweep 20260815, all 7 assets in service):
  FAMTSWP DUE=  2 SKIP=  2 COST=  1070.00   750.00 + 320.00
  FAWARN EXPIRED=  1 INWARR=  3             AS100002 out of warranty
  FACCRPT CC10 N=  4 COST= 123200.00 ...    CC20 N=1, CC30 N=2
  FACCRPT CENTRES DONE ASSETS=  7

Monthly — FAMONTH (FADEPRUN → FAGLPST → FADEPSUM)

FADEPRUN reads the period from data area FADEPPER (falling back to 202608 if the data area is blank/invalid), then for every ASTAT='A' asset with depreciable base remaining computes the charge by method (F.1), clamps it to the remaining base, and — guarded by the composite (ASTNO, DPER) key so a same-period re-run posts nothing — writes a FADEPH row and rolls the master's ACCDEP, NBV and LSTPER. FAGLPST reads the whole period through the period-keyed logical FADEPLF, and for each charge writes a balanced pair to FAGLDIST: DR 7100-DEPN (expense) and CR 1590-ADEP (accumulated depreciation), tagged with the asset's cost centre; it is idempotent — if the period already has distribution rows it reports ALREADY POSTED and adds nothing. FADEPSUM (COBOL) independently totals the period's history by method as a cross-check.

Expected DSPLY (period 202608, 7 in-service assets):
  FADEPRUN PER=202608 POSTED=  7 SKIP=  0   period total 8450.00
  FAGLPST PER=202608 ROWS= 14 TOTAL= 8450.00  2 rows/asset, DR=CR=8450.00
  FADEPSUM STRAIGHT      2250.00   900 + 750 + 600
  FADEPSUM DECLINE       1600.00   1000 + 600
  FADEPSUM UNITS         4600.00   3600 + 1000
  FADEPSUM TOTAL         8450.00
A same-period re-run of depreciation reports POSTED=0 SKIP=7 and leaves accumulated depreciation unchanged (composite (ASTNO, DPER) guard) — the single most important control in the app. The whole FAMONTH chain is re-runnable.

Annual — FAYEAR (FARETIRE → FANBVRL → FAREGEN → FAREGPR)

FARETIRE retires any in-service asset whose ACCDEP has reached its depreciable base (COST-SALVAG) to 'F' and posts a FALEDG 'F' row keyed 60000000 + asset digits. FANBVRL re-computes NBV = COST - ACCDEP for every asset, clamping accumulated to the base and NBV to non-negative (disposed assets carry NBV 0), reporting how many it had to clamp. FAREGEN writes one FAREG snapshot row per non-disposed asset for the register year (compiled constant WYR = 2026), composite-keyed (RYEAR, ASTNO) so a re-run is refused. FAREGPR prints the register through FAREGP with page overflow.

Expected DSPLY (after the three depreciation periods in the cycles suite):
  FARETIRE RETIRED=  1 SKIP=  6        the fully-depreciated jig AS400001
  FANBVRL ASSETS=  7 NBV=... CLAMPED=  0
  FAREGEN YEAR=2026 LINES=  7 NBV=... SKIP=  0
  FAREGPR LINES=  7 NBV=...

C.3 Ordering & dependencies

D. Data Files (data dictionary) ↑ top

All files are in library ESTATE, grounded in src/sources.mjs. Dates are stored as signed numeric in YYYYMMDD form (periods as YYYYMM); money is packed 11P2; rates are packed 7P4 (0.2000 = 20% a year, or a per-unit amount for units-of-production). NBV is always COST - ACCDEP — derived, but also carried on the master so the register prints without recomputation.

FAASSET — Asset master (key ASTNO)

FieldTypeMeaning
ASTNO8AAsset number (key), e.g. AS100001.
ADESC30ADescription.
ACLASS4AAsset class (→ FACLASS).
CCTR4ACost centre (→ FACCTR); transfer target.
ACQDT / INSVDT8S 0Acquisition date / in-service date (stamped at capitalisation).
COST11P 2Original cost.
SALVAG11P 2Salvage / residual value.
LIFEMT4S 0Life in MONTHS (straight-line divisor).
DMETH1AMethod: S straight-line, D declining-balance, U units-of-production.
DRATE7P 4Annual declining-balance rate, or per-unit amount for units-of-production.
TOTUNIT / USEUNIT9P 0Lifetime units / units used this period (set before the monthly run).
ACCDEP11P 2Accumulated depreciation.
NBV11P 2Net book value (cost − accumulated).
ASTAT1AP pending, A in service, D disposed, F fully depreciated / retired.
LSTPER6S 0Last period depreciated (YYYYMM).

Seeded (all pending 'P'): AS100001 PLANT 60000/6000/60m/S; AS100002 VEHICLE 40000/4000/48m/S; AS200001 IT 60000/rate .2000/D; AS200002 SERVER 24000/rate .3000/D; AS300001 PRESS 50000/5000/rate .4500/unit/U; AS300002 MOULD 12000/rate .2000/unit/U; AS400001 FIXTURE 1200/0/2m/S (retires fast).

FAASTLF — Asset master by cost centre (LF over FAASSET; key CCTR, ASTNO)

Non-unique alternate access path so the cost-centre register (FACCRPT) and transfer audit are keyed READE reads rather than a full-master scan. A cost centre holds many assets.

FACLASS — Asset-class master (key CLSCD)

FieldTypeMeaning
CLSCD4AClass code (key), e.g. PLNT / VEHC / ITEQ / TOOL.
CLSDSC25AClass description.
DFMETH / DFLIFE / DFRATE1A / 4S 0 / 7P 4Default method / life / rate (the policy where the asset is silent).
ASSACC / DEPACC / EXPACC9AAsset, accumulated-depreciation and depreciation-expense GL accounts.

Seeded: PLNT (S/60/7100-DEPN), VEHC (S/48/7110-DEPN), ITEQ (D/36/.2000/7120-DEPN), TOOL (U/0/.4500/7130-DEPN).

FACCTR — Cost-centre master (key CCNO)

FieldTypeMeaning
CCNO4ACost-centre number (key).
CCDESC / CCMGR25A / 20ADescription / manager.
CCSTAT1AStatus; a transfer target must be 'A' (open).

Seeded: CC10 MAIN FACTORY, CC20 DISTRIBUTION DEPOT, CC30 HEAD OFFICE (all open).

FADEPH — Depreciation history (composite key ASTNO, DPER)

FieldTypeMeaning
ASTNO / DPER8A / 6S 0Asset + period YYYYMM (key). The composite key accumulates history and guards re-runs.
DMETH1AMethod used for this charge.
DAMT11P 2Period charge.
DACCUM11P 2Running accumulated depreciation AFTER this charge.
DNBV11P 2Net book value after this charge.
DPDT8S 0Posting date.

FADEPLF — Depreciation history by period (LF over FADEPH; key DPER, ASTNO)

Alternate access path so the monthly GL distribution (FAGLPST) reads a whole period with one keyed READE group rather than scanning every asset's whole history.

FAXFER — Transfer request log (key XSEQ)

FieldTypeMeaning
XSEQ8S 0Transfer sequence (key); the disjoint 20000000+XSEQ ledger range.
ASTNO8AAsset moving.
FRMCC / TOCC4AFrom / to cost centre (FRMCC captured by the run).
XDT8S 0Transfer date.
XSTAT1AR requested, C complete.
XREASN25AReason text.

FADISP — Disposal request log (key ASTNO)

FieldTypeMeaning
ASTNO8AAsset disposed (key).
DISPDT8S 0Disposal date.
PROCED11P 2Proceeds (seeded on the request).
DCOST / DACCUM / DSPNBV11P 2Cost / accumulated / NBV snapped by the run.
GAINLS11P 2Gain (+) or loss (−) = proceeds − NBV.
DSTAT1AR requested, C complete.

FAMAINT — Maintenance schedule (composite key ASTNO, MSEQ)

FieldTypeMeaning
ASTNO / MSEQ8A / 3S 0Asset + schedule line (key).
MDESC25AService description.
NEXTDT / INTDAY8S 0 / 4S 0Next-due date / interval in days.
WARRDT8S 0Warranty expiry date.
MSTAT1AS scheduled, D due (flagged by the weekly sweep).
MCOST11P 2Estimated service cost (accumulated by the sweep).

FALEDG — Durable asset ledger (key LSEQ)

FieldTypeMeaning
LSEQ8S 0Ledger sequence (key), derived from a stable business key on a disjoint per-program range.
ASTNO8AAsset affected.
LTYPE1AC capitalise, X transfer, S sale/disposal, P depreciation, F retirement.
LDT8S 0Ledger date.
LAMT11P 2Amount (signed for gain/loss; NBV for a transfer).
LREF / LMEMO8A / 25AReference / memo.

LSEQ ranges: capitalise 10000000+digits, transfer 20000000+XSEQ, disposal 30000000+digits, depreciation 40000000+digits (per-period guard is the FADEPH composite key), retirement 60000000+digits.

FAREG — Year-end register snapshot (composite key RYEAR, ASTNO)

FieldTypeMeaning
RYEAR / ASTNO4S 0 / 8ARegister year + asset (key); successive years accumulate.
RCCTR4ACost centre (for the subtotal).
RCOST / RACCUM / RNBV11P 2Cost / accumulated / NBV snapshot.
RSTAT1AStatus at register time.

FAGLDIST — GL distribution (SQL table, key GLSEQ)

ColumnTypeMeaning
GLSEQDECIMAL(8,0)Distribution sequence (PK), seeded period×100 + n.
GLPERDECIMAL(6,0)Period YYYYMM (indexed with ACCT via FAGLDACC).
ACCT / CCTRCHAR(9) / CHAR(4)GL account / cost centre.
DRCRCHAR(1)D debit (7100-DEPN expense) / C credit (1590-ADEP accumulated).
AMTDECIMAL(11,2)Distribution amount.
GLREF / GLDTCHAR(8) / DECIMAL(8,0)Reference / date.

FADEPPER — Depreciation-period data area (*DTAARA CHAR(10))

Holds the processing period the monthly programs read, created by FASETUP with value ' 202608'. Advance it before each monthly run with CHGDTAARA DTAARA(ESTATE/FADEPPER) VALUE(' YYYYMM'); a blank/invalid value falls back to 202608 in the programs.

Relationships

E. Operations Runbook ↑ top

E.1 Day-in-the-life

  1. One-time / on rebuild: CALL ESTATE/FASETUP (creates objects, compiles programs), then CALL ESTATE/FAREFLD (loads classes, cost centres, pending assets, maintenance).
  2. Submit the daily cycle: SBMJOB CMD(CALL PGM(ESTATE/FADAILY)) — capitalises any new pending asset, actions transfer and disposal requests.
  3. Post-check the daily run (below).
  4. Handle enquiries interactively through CALL ESTATE/FAMENU (option 1 asset inquiry, option 2 depreciation history).
  5. On the weekly day, submit FAWEEK and review the maintenance-due, warranty and cost-centre lines.

Pre-checks: confirm the job's library list includes ESTATE; for transfers/disposals, confirm the request rows are seeded at status 'R'.

Post-checks after the daily cycle:

E.2 Depreciation run & month-end

  1. Set the units used this period on any units-of-production asset (e.g. update USEUNIT on AS300001/AS300002); a unit asset that ran 0 units charges nothing that month.
  2. Set the period: CHGDTAARA DTAARA(ESTATE/FADEPPER) VALUE(' YYYYMM').
  3. Submit FAMONTH. Confirm FADEPRUN PER=YYYYMM POSTED=n, FAGLPST PER=YYYYMM ROWS=2n TOTAL=, and the four FADEPSUM lines.
  4. Reconcile the period (below), then advance to the next month.

Reconciling figures (the same ones the cycles suite checks against a hand-derived oracle, period 202608):

Ad-hoc GL review:

SELECT ACCT, DRCR, SUM(AMT) FROM ESTATE.FAGLDIST
  WHERE GLPER = 202608 GROUP BY ACCT, DRCR ORDER BY ACCT;

E.3 Year-end & reconciling the register

  1. Confirm every month's FAMONTH has run for the year (FADEPH holds each asset's periods).
  2. Submit FAYEAR. Confirm FARETIRE RETIRED=, FANBVRL ... CLAMPED=0, FAREGEN YEAR=y LINES=, FAREGPR LINES=.
  3. Reconcile the register snapshot:
-- one row per live asset for the year; RACCUM/RNBV are the year-end position
SELECT ASTNO, RCCTR, RCOST, RACCUM, RNBV FROM ESTATE.FAREG WHERE RYEAR = 2026;

E.4 Failure & re-run rules

Each program DSPLYs a counted result line. Every posting program is guarded so a re-run posts nothing rather than double-posting.

SituationBehaviourAction
Re-run the daily cycleCapitalise/transfer/dispose all report their count as 0 on the second pass.Safe: stable ledger keys + status guards make the whole daily chain re-runnable. The ledger does not grow.
Re-run depreciation for the same periodPOSTED=0 SKIP=n; accumulated unchanged.Safe no-op — composite (ASTNO, DPER) guard. Advance FADEPPER to post a new month.
Re-run the GL distributionReports ALREADY POSTED, ROWS=0.Safe: FAGLPST checks for existing period rows first.
Depreciation reaches the baseThe final charge is CLAMPED; a fully-depreciated asset is SKIPPED (no row).Expected. NBV can never go below salvage or negative.
Transfer to bad/closed cost centreSKIP incremented; request stays 'R'; asset unmoved.Fix the destination (or open the cost centre) and re-run.
Re-run the annual cycleRetires/registers nothing a second time; FAREG holds the same rows.Safe: 60000000+digits ledger key and (RYEAR, ASTNO) register key are the guards.
Units-of-production asset shows no chargeUSEUNIT was 0 for the period.Set USEUNIT before the monthly run; a unit asset only depreciates on units used.
Because every asset event is journaled to FALEDG with an amount, reference and memo, and every depreciation charge to FADEPH with running accumulated and NBV, any cycle's effect is fully reconstructable after the fact for reconciliation and recovery.

F. Developer Reference ↑ top

The mechanics that matter when maintaining ESTATE/i, from src/sources.mjs. All objects are in library ESTATE.

F.1 Depreciation formulae & the invariant

All three methods are computed per PERIOD (one month) in FADEPRUN, subroutine DEP1, and every method half-adjusts to the cent (eval(h)) rather than truncating — a ledger that truncated every month would drift cents from the base and the final clamp would carry the whole error.

S — straight-line
monthly = (COST - SALVAGE) / LIFEMT (only when LIFEMT > 0). Flat across periods.
D — declining-balance
monthly = (COST - ACCDEP) × DRATE / 12. The rate is applied to net book value, so the charge shrinks each month (classic reducing balance).
U — units-of-production
monthly = USEUNIT × DRATE (units run in the period × per-unit rate). The harness/operator stamps USEUNIT before the run; the program consumes it.

The invariant, enforced for every method: the depreciable base is WBASE = COST - SALVAG and the remaining base is WREM = WBASE - ACCDEP. If the computed charge exceeds WREM it is clamped to WREM; a charge ≤ 0 skips the asset (no history row). So accumulated depreciation can never exceed COST - SALVAGE and NBV can never fall below salvage while the asset is live, nor go negative. The annual FANBVRL re-asserts this by clamping accumulated to the base and NBV to non-negative and counting how many it had to fix.

F.2 Idempotency keys

Every posting program derives its key from a stable business key on a disjoint LSEQ range, then CHAIN(EN)s that key before writing: if the row exists it increments SKIP and leaves; otherwise it writes. A re-run regenerates the identical key and is refused rather than double-posting.

ProgramKeyGuard
FAACQFALEDG 10000000 + %dec(%subst(astno:3:6):8:0)Stable ledger key + ASTAT='P' check.
FAXFRUNFALEDG 20000000 + XSEQStable ledger key + XSTAT='R' + open destination.
FADISPOSFALEDG 30000000 + asset digitsStable ledger key + DSTAT='R' + not already 'D'.
FADEPRUNFADEPH composite (ASTNO, DPER)Per-period guard via a KLIST CHAIN — the app's most important control.
FAGLPSTFAGLDIST COUNT(*) WHERE GLPER = :wperExisting-period check → ALREADY POSTED.
FARETIREFALEDG 60000000 + asset digitsStable ledger key + ASTAT='A' + base reached.
FAREGENFAREG composite (RYEAR, ASTNO)Per-year guard via a KLIST CHAIN.
The depreciation ledger range 40000000+digits is reserved for the depreciation class; the per-period idempotency guard for depreciation is the FADEPH composite key, not this ledger key (a single asset depreciates every month, so its ledger-key form alone could not distinguish periods).

F.3 The re-CHAIN pattern & composite keys

Two RPG idioms recur and are worth understanding before editing:

Embedded SQL (FAGLPST). The one SQLRPGLE program uses free-form exec sql: a SELECT COUNT(*) INTO :wexist idempotency check, then an INSERT INTO ESTATE.FAGLDIST VALUES(...) per DR/CR row inside a begsr glrow subroutine, summing the period read through the period-keyed logical FADEPHR (accessed as FADEPLF).

F.4 Program status codes (result lines)

ESTATE/i signals no application SQLSTATEs; every program reports its outcome as a counted DSPLY line. The completion banners are sent by the CL cycles.

LineProgramMeaning
FAACQ CAPITALISED=n SKIP=nFAACQn assets capitalised; SKIP = already-capitalised or not pending.
FAXFRUN TRANSFERRED=n SKIP=nFAXFRUNn transfers actioned; SKIP = not-'R'/bad destination/already posted.
FADISPOS DISPOSED=n SKIP=nFADISPOSn disposals actioned; SKIP = not-'R'/already 'D'/already posted.
FAMTSWP DUE=n SKIP=n COST=nFAMTSWPn schedules flagged due; total estimated cost.
FAWARN EXPIRED=n INWARR=nFAWARNn warranties expired / still in warranty (expired assets named).
FACCRPT cc N=n COST=n NBV=nFACCRPTPer cost centre + CENTRES DONE ASSETS=n.
FADEPRUN PER=p POSTED=n SKIP=nFADEPRUNn assets depreciated for period p; SKIP = not-'A'/no base/already posted.
FAGLPST PER=p ROWS=n TOTAL=nFAGLPSTn distribution rows / total; or ROWS=0 ALREADY POSTED.
FADEPSUM STRAIGHT/DECLINE/UNITS/TOTAL/ROWSFADEPSUMCOBOL period totals by method (independent proof).
FARETIRE RETIRED=n SKIP=nFARETIREn fully-depreciated assets retired.
FANBVRL ASSETS=n NBV=n CLAMPED=nFANBVRLn assets rolled; CLAMPED = invariant fixes applied.
FAREGEN YEAR=y LINES=n NBV=n SKIP=nFAREGENn register rows written for year y.
FAREGPR LINES=n NBV=nFAREGPRn register lines spooled.

G. Glossary ↑ top

Accumulated depreciation (ACCDEP)
The running total of depreciation charged against an asset since it went into service. NBV is COST - ACCDEP.
Capitalisation
Bringing a pending asset into service: stamping the in-service date, setting NBV = cost, moving ASTAT P→A and posting a FALEDG 'C' row (FAACQ).
Cost centre (FACCTR)
An organisational unit an asset belongs to; transfers move an asset between two, and the register and GL distribution subtotal by them.
Data area (FADEPPER)
A small named object (*DTAARA) holding the depreciation period the parameterless monthly programs read, so a bare CALL can drive them for any month.
Declining-balance (D)
Depreciation applied to net book value at an annual rate (÷12 monthly), so the charge shrinks each period: (COST - ACCDEP) × DRATE / 12.
Depreciable base
COST - SALVAGE — the ceiling accumulated depreciation may never exceed. The invariant clamps every charge to what is left of it.
Depreciation history (FADEPH)
One row per asset per period (composite key ASTNO, DPER) carrying the charge, running accumulated and NBV; the key both accumulates history and guards same-period re-runs.
Disposal
Selling/retiring an asset for proceeds: NBV = cost−accumulated, gain/loss = proceeds−NBV, asset→'D', a signed FALEDG 'S' row (FADISPOS).
GL distribution (FAGLDIST)
Balanced double-entry rows the monthly depreciation feeds to the general ledger: DR depreciation expense (7100-DEPN), CR accumulated depreciation (1590-ADEP), per cost centre (FAGLPST).
Idempotent
Safe to run again with the same result. Every ESTATE/i posting is idempotent via a stable business key on a disjoint range (or a composite period/year key), so a re-run posts nothing.
Ledger (FALEDG)
The single accumulating audit trail every cycle contributes to (LTYPE C/X/S/P/F), with disjoint LSEQ ranges per program.
Net book value (NBV)
An asset's carrying value: COST - ACCDEP. Derived, and also carried on the master and on the inquiry screen; never below salvage while live, never negative.
Re-CHAIN
Re-reading the driver record on its captured key after a side write (to another file) moved the file cursor, so the driver update lands on the right record.
SBMJOB
Submit Job — the IBM i command that queues a program to run as a batch job (e.g. SBMJOB CMD(CALL PGM(ESTATE/FADAILY))).
Straight-line (S)
Equal depreciation each month over the asset's life: (COST - SALVAGE) / LIFEMT.
Subfile
A 5250 display construct listing many rows on one screen (DDS SFL/SFLCTL). FADEPIQ's period-charge list is a subfile with SFLPAG(0005) paging.
Units-of-production (U)
Depreciation by usage: USEUNIT × DRATE (units run this period × per-unit rate); no usage, no charge.