Glossary & Data Model
Terms
Treasury — a place collected money sits: a cash drawer, bank account, or card account. A branch has several, each with a type (e.g. a "collection" treasury for a given payment mode). When you collect a diagnostic fee, you attach it to a treasury so reconciliation knows where the cash is. In the mobile form the treasury is chosen via a picker; the fix in this PR makes the picked treasury object land back in the field.
Default treasury — the treasury pre-filled for a given branch + treasury type. TreasuryField looks it up from BRANCH_DETAILS and calls setValue('treasury', defaultTreasury). The bug only affected changing it via the picker, not this default.
Diagnostic fee (Diagnostic Fees) — the examination fee, optionally collected at booking. In New Appointment it has three modes: None, Collected (an invoice is created automatically), or Add to Next Invoice. "Collected" reveals the amount, payment method, and treasury.
Operation — a treatment/procedure record for a patient, with a total, paid, discount, tax, and a status. Can be paid all at once or over sessions.
Step (Operation Step) — one session of a treatment done over multiple visits. Each step has its own total, paid, discount, tax, and a paidInFull flag.
Pulse / Session — the clinic-facing word for the remaining steps of an operation. The patient Operations tab shows a "Remaining Pulses / Sessions" column. "An operation with pulses" (from the PR title) = an operation billed in steps.
Step Payment (stepPayment) — a record that a chunk of a payment settled a particular step. One incoming payment can create several step-payments across several steps. The bug caused a payment to fragment into an extra step-payment record.
Salary Adjustment — the doctor's commission/earnings entry created alongside a step payment (amount: Math.abs(forOperator)), unless it's an unclaimed insurance payment. Because it's created per step-payment, a spurious split meant the commission landed on only one of the two records.
forOperator — the portion of a step/payment that is the operating doctor's commission, net of lab fees and discount. Drives the salary adjustment amount.
Paid in Full (paidInFull) — flag set on an operation (and its steps) once its paid meets its net payable (total − discount + tax). The PR fixes the comparison to use the operation's discount/tax, not a single step's.
Data-model notes (relevant fields)
These are the fields the fixes read/compare (from the Prisma-backed selects in the changed resolvers; not new fields — nothing was added to the schema).
Operation
| Field | Role in these fixes |
|---|---|
total | Gross value of the operation |
paid | Total collected against the operation; source of a new step's inherited paid amount |
discount / tax | Now used to compute the operation's net payable for the paid-in-full check (paymentUtils.js:217) |
remaining | Remaining un-stepped package; part of totalPackage when computing a step's share |
paidInFull / paidAt | Set when paid ≥ total − discount + tax |
Operation Step
| Field | Role in these fixes |
|---|---|
package | The step's share of the treatment; drives percentOfOperation |
paid | Per-step collected amount; summed to find what's already allocated (addOperationStep.js:290) |
total / discount / tax | The step's own payable; caps the new step's inherited paid via stepTotalToPay |
paidInFull / paidAt | Set when the parent operation is settled |
Step Payment
| Field | Role |
|---|---|
amount | The chunk of the payment applied to this step |
forOperator | Doctor commission portion → salary adjustment |
salaryAdjustment | Created per step-payment; the commission-recording symptom lives here |
Code map (where each fix lives)
| Fix | Path & lines |
|---|---|
| Treasury field persists (mobile) | packages/clinic-mobile/src/components/dashboard/calendar/newAppointment/NewAppointmentScreen.js:451-459 |
| Returned-param naming (root cause) | packages/clinic-mobile/src/common/screens/SelectScreen.js:151-160 |
| Treasury rendering (object expected) | packages/clinic-mobile/src/common/controlledFields/TreasuryField.js |
| New step inherits only unpaid remainder | packages/server/src/resolvers/mutations/actions/addOperationStep.js:285-293 |
Operation discount/tax added to select | packages/server/src/resolvers/mutations/mutationUtils/paymentUtils.js:206 |
| Paid-in-full uses operation discount/tax | packages/server/src/resolvers/mutations/mutationUtils/paymentUtils.js:214-224 |
| Salary adjustment per step-payment | packages/server/src/resolvers/mutations/mutationUtils/paymentUtils.js:160-176 |