Point Currencies and Balances
GadgetSphere’s members collect one currency, GSPTS, worth RM 1.00 per 100 points at the counter.
A second currency is possible — the record allows any number — but every earning rule, every
balance and every redemption is per currency, so add one only when you want a wallet the first
one must not mix with.
The currency record
PTS CCY Module in Membership Admin writes the point currency: a code, a name, a conversion rate, a point-to-point cross-over conversion flag and a status. PTS to CCY Config writes the points-to-money rate: one point currency, one money currency, a rate — the number the till uses when it turns points into ringgit. A PTS to PTS Config route exists for point-currency-to-point-currency rates; its menu entry is commented out, so there is no working conversion between currencies today.
Where points come from
Every earning is a point transaction line with a source. The sources the backend has:
| Source | What creates the line |
|---|---|
| A sales document at the counter or on account | When a document of the company’s configured type reaches the configured posting status and carries a member, each line that carries a point amount and a point currency becomes one REWARD (positive) or REDEEM (negative) line. The defaults are INTERNAL_SALES_ORDER at FINAL; a company overrides them in its MEMBER_POINT configuration (set through the company API — no screen). The point amount on the line comes from a Pricebook Point treatment |
| A storefront order | The CP Commerce points job runs the same document-type and status check on the order, but writes each line as an adjustment (ADJ) valid until 31 December 9999 — the line’s own point dates are not used, so storefront points never expire. It also skips the order when the company’s scheduled point-assignment days is set to 0 |
| A Commission Scheme | The membership-points commission run turns the scheme’s first treatment into REWARD lines, valid from the document date for the treatment’s Validity Period (Days) — which defaults to 0, so points from a scheme left at 0 end on the document’s own date |
| A scanned third-party receipt | OCR Cash Bill evaluates a price book’s Point treatment against the extracted lines and writes lines |
| A person | Add Point Adjustment on the member form (a line of type ADJ, positive or negative, with a company, branch, item, validity window and DISPLAY / HIDDEN flag, and no source) and Upload Member Point Transaction from CSV |
| A birthday | The birthday-gift run (MEMBER_BIRTHDAY_GIFT_PROCESSOR in the Scheduler applet’s processor picker), when scheduled with a gift type of points: an ADJ line of a point amount in a currency, valid for the months set on the schedule (12 if left empty), to the member classes the schedule names |
If the document is later voided, its point lines stay on the member’s record and the balance the till shows does not change. Where the points-void job is set up it removes the lots the document earned, so the Points Expiry tab and the till can then disagree; points the document redeemed are not returned. Points Setup covers how to correct a member.
Line, lot, balance
Three records answer three different questions:
| Question | Record | How it is kept |
|---|---|---|
| What happened? | The transaction line (the member’s Point Transaction tab) | One per earn, redemption, expiry or adjustment: a type of REWARD, REDEEM, EXPIRY, ADJ or ADJ_INSUFFICIENT (and CF / BF, written only by the balance-calibration call), a points value, a valid-from and valid-to date, the document and line it came from, and whether it is displayed or hidden |
| How many are still valid, and until when? | The lot (the member’s Points Expiry tab) | One per earning, with its remaining balance, start and end date and next expiry check; each redemption is recorded against the lots it drew down. The tab’s Balance Amount column shows the points the lot started with, not its remaining balance |
| What is the total? | The running balance | One per member and currency — a stored accumulator, not a live sum, and maintained by two different writers (below) |
A redemption eats the lot that dies soonest. A redemption takes the member’s open lots whose end date has not passed, sorts them by end date, earliest first, and draws down in that order, writing a contra row for each lot it touches and deleting a lot when it reaches zero. That is earliest-expiry-first, not oldest-earned-first: a lot earned later with a shorter validity is spent before an older one that lasts longer.
More than one writer keeps the balance, and which one last ran explains a balance that looks wrong. Almost every line queues a rebuild, which sets the stored balance to the sum of every active transaction line for that member and currency, then makes the lot (for an earning) or draws lots down (for a spending). Two jobs also write the balance directly: the expiry run and the void’s insufficient-balance adjustment — and on those two lines they set the stored balance to zero rather than subtracting. The expiry run then queues its rebuild, so the balance is briefly zero and then right — and stays zero if that queue hop is lost; the void’s adjustment queues none. The birthday run adds its points to the stored balance directly as well. Walking the chain is how you tell these apart.
Read the running total from the current balance query (it is what the till shows) and the lots’ remaining points from the lot query in the membership API; the Points Expiry tab lists the lots and their dates, but its Balance Amount is each lot’s original points. Do not use the older balance call as a second opinion: it returns one lot row’s figure rather than a sum, and can rewrite that row when it is read. When the lines and the lots disagree, the recalculation queue in Membership Admin rebuilds lots and balance from the lines — and the arithmetic that settles which is wrong is that the sum of the active lines must equal the stored balance.
Nothing posts to the ledger
The point reward and point redeem document types carry no amount and no quantity, and journal
posting has no rule for them. Earning 120 points on a RM 1,200 laptop changes three membership tables and
no GL account. Redeeming 2,000 points on the next bill reaches the ledger only as part of that cash
bill — a points settlement line, or a points-discount line using the MEMBER_POINT_DISCOUNT item —
and that posting is POS General’s, not this module’s.
If GadgetSphere’s accountant wants a points liability on the balance sheet, it is a manual journal
from the balance report, not something the module maintains — and
what you owe your members is the procedure
for producing it.
Related
- Points expiry — what happens to a lot on its end date.
- Points setup — the currency and the rate, in order.