← All docs
Workflows
PMS — WORKFLOWS
===============
Updated: 2026-07-19
Finance detail: docs/workflows-finance.txt
1. ONBOARDING ENTITIES
----------------------
[o] Owner → [p] Property → [u] Unit → [t] Tenant → [l] Lease
Check [v] vacant units before leasing.
Ownership model (operator guidance)
-----------------------------------
· One owner_id per property. That owner is the bill-to for rent fees and
work orders under that property (including property-level yard work).
· The unit is the managed door. The property row is the economic control
unit you manage for that owner — not necessarily a unique street parcel.
Same street address, different owners (condo / multi-owner complex)
· Allowed and preferred: N separate properties may share the same address.
· Differentiate in the address or description with the apartment/unit
number, e.g.:
55 Lucky Valley #11
55 Lucky Valley #12
or address = "55 Lucky Valley" + unit_number = "11" on a property that
has only that one managed unit.
· Put a short note on each property, e.g.:
"Parcel shared building; managed door #11 only — Owner Rosina"
· Do NOT put two owners' doors under one property — bill-to would be wrong.
· Common-area work you do not manage is not a billed PMS WO (or is
non-billable). Work one owner pays for stays on that owner's property.
Same owner, many doors at one building
· One property + many units (normal multi_family / apartment_complex).
True co-ownership of the same door's cash (50/50 siblings, trust splits)
· Prefer one bill-to (LLC or primary) and split outside the system, OR a future
ownership-share model — not duplicate address rows for the same cash flow.
See portfolio map: [d] → [4] (directory + property job sheet).
Find an owner's property / add a unit to a shell
-----------------------------------------------
1. [p] Properties — list shows Owner + Units (0 = shell, no units yet)
· Type / then owner name (or address) to filter
· Or sort 4=Owner / 5=Units
2. Select the row → detail shows Owner Name + Units on property
3. Note the PID, then [u] Units → A Add unit
· Picker lists PID · Address · Owner · Units (shells show 0)
· Enter that PID only (blank or q cancels)
4. Confirm under [p] that Units went from 0 → 1, or [d]→[4] directory
Tenant + lease (vacant unit) — operator path
--------------------------------------------
1. [v] Confirm unit is vacant (no current active lease)
2. [t] → A Add tenant
· First + last name required
· Email or phone required (at least one)
· Then open Leases to place them
3. [l] → A Add lease
· Pick tenant from list
· Pick available unit (same current-window rule as [v])
· Defaults: start = 1st of month · end ≈ +12 months
rent = unit base_monthly_rent · deposit = rent
· Status default active
4. Side effects (automatic)
· Unit status → occupied when lease is active and started
· Second active lease on same unit is refused
· Future-start lease: unit stays vacant until start_date
5. [r] → monthly invoicing once the start month is due
Turnover
--------
· Edit lease status to terminated (or delete with YES)
· Unit status → vacant when no current active lease remains
· Make-ready if needed ([u] unit status not-ready → vacant)
· New tenant [t] → new lease [l] on the free unit
2. MONTHLY RENT
---------------
[r] → [2] Monthly rent invoicing
Calendar month · INV-YYYYMM-#####
Issue/due days from PMO settings (default 1 / 5)
Preview count → type YES → safe re-run
[r] → [3] Collect rent
Records payment; posts rent_collected (+) and management_fee (−)
Warns if invoice already paid — do not double-enter
[r] → [4] AR exceptions / reverse pay
Lists OVERPAID / PAID_NO_PAYMENT / BALANCE_DRIFT invoices
[R] soft-void a payment (reason + YES) → clear owner ledger for that
payment_id → recompute invoice balance
[F] fix invoice status from posted payments only
Never hard-delete payment rows; regenerate owner statements after reverse
Needs migration 1.20 (payments.status / reverse columns)
[r] → [6] AR aging detail (also [s]→[6])
Overdue rent only · buckets 0-30/31-60/61-90/90+ · property subtotals
Late fee % from settings when payment after due date.
Collect prompts: [A]pply / [W]aive (default) / custom amount.
Cold-start: waive late (or set pay date = due) so go-live is not auto-punished.
Collected late fee → owner other_income (+); mgmt % on rent only.
3. WORK ORDER MONEY CYCLE
-------------------------
Critical: bill-to-owner charges SUM(expenses linked to WO#),
NOT work_orders.actual_cost alone. Enter expense lines first.
Money recovery = bill owner (ledger expense −), which nets against rent
on the owner package. There is NO separate “collect expense from owner”
cash step. Paid status flips **automatically on successful bill**.
[w] → [1] Manage work orders
Columns show #Exp and Exp$ (linked lines)
X = list expenses on selected WO
N = add expense for this WO (returns to WO list)
K = cancel empty WO only (zero expense rows — T070)
A = add WO (property + unit pickers; category ENUM)
[w] → [2] Manage expenses (or N from WO list)
List default = pending on open jobs (hides pure status echo lag)
Filter: pending · processed · all recent
Expense status = line lock after bill — not a second owner settlement
Edit category/amount only while status = pending
Soft-cancel pending OK; paid locked
[w] → [6] WOs missing expenses (focus list)
[w] → [3] Complete WO (status = completed)
[w] → [4] Bill owner
Posts expense (−) to owner ledger
Auto: WO → paid and pending expenses → paid
Requires YES; fails if zero linked expenses
This IS the recovery step (deducted on owner statement vs rent)
[w] → [7] Reverse WO bill (T070 double-entry)
Reason + YES → clear owner ledger for WO
Soft-void invoiced|paid expenses → cancelled
WO → completed (re-add pending lines then re-bill if needed)
Never hard-delete billed expenses or WOs that have expenses
[w] → [e] View status exceptions (only if integrity errors)
Logged + dashboard + Mark ticket on crit — not a flip-status menu
Do not use a separate “mark paid” operator step.
4. OWNER STATEMENTS
-------------------
[s] → [o] Owner statements hub
Default period = current month
Generate → browse → export PDF
Letterhead: [y] → [L]
Regenerate anytime (idempotent).
5. SYSTEM / PMO
---------------
[y] → [5] Business parameters (fee %, invoice days)
[y] → [L] Letterhead
[y] → [4] Admin (inventory, telemetry, drift, SQL audit)
[y] → [6] Ledger backfill (historical payments / expense signs)
[y] → [Q] QA Lab (sandbox pmdb_qa only)
Seed [4] once · re-fight battles without wipe
Lease onboard [l]/[m] · AR reverse [v] · statement recon [t]
Rent [5–9 a c d] · WO [w] · season [s g]
Wipe [7] only when corrupt / DEFEAT will not clear
6. AUTHORIZED CODE
------------------
New script: add to manifest/scripts.tsv then bin/run <id>
New SQL: add to manifest/sql.tsv then bin/runsql / pms_runsql
bin/audit-sql shows remaining inline SQL.