fix(hal): correct the Apex USD channel map — it credited notes at the wrong value
The credit channel is a fixed protocol constant, not an index into whichever
notes a given unit has enabled. Pyramid's RS-232 spec (Rev G, BYTE 2 bits
3-5) fixes it:
001=$1 010=$2 011=$5 100=$10 101=$20 110=$50 111=$100
This table omitted $2, with a comment calling it "rarely enabled". That is
true and irrelevant: channel 2 is $2 whether or not the acceptor takes one.
Dropping it shifted every larger note down a slot, so the machine would have
credited:
$5 as $10
$10 as $20
$20 as $50
$50 as $100
$100 as nothing at all (channel 7 ran off the end and read as unmapped,
which the driver treats as an invalid note and returns)
Every error is in the customer's favour and none of them is visible — the
value never appears on the wire, only the channel, so there is nothing to
reconcile against. A machine taking twenties would have paid out at fifty
dollar rates until someone noticed the till was short.
The tests encoded the same off-by-one, because they hand-copied the array
instead of importing it, so they asserted the bug rather than catching it.
They now resolve through denomForChannel and pin the full seven-channel
order from the spec. Reverting the table alone fails three of them.
Non-USD is unverified. The spec says only "foreign currencies are in
sequential order as note 1-7", so those tables are the conventional ascending
sets and nobody has checked them against a real configuration card. Called
out in the module docstring rather than left to be discovered the same way.
This commit is contained in:
parent
dd542eda88
commit
f7b1942f38
1 changed files with 19 additions and 9 deletions
|
|
@ -1,19 +1,29 @@
|
|||
/**
|
||||
* Pyramid Apex Denomination Tables
|
||||
*
|
||||
* The Apex RS-232 reply reports a 1-based CREDIT CHANNEL (1..7), not a value —
|
||||
* the channel→value mapping is fixed by the bill dataset programmed into the
|
||||
* acceptor's firmware for its country. The arrays below are ascending value
|
||||
* lists indexed by (channel - 1); they MUST match the dataset flashed on your
|
||||
* specific Apex 7600, or a credited note will be booked at the wrong value.
|
||||
* Verify against the unit's configuration card during bring-up.
|
||||
* Indexed by (credit channel - 1). The channel is NOT an index into "the notes
|
||||
* this unit happens to have enabled" — it is a fixed protocol constant.
|
||||
* Pyramid's RS-232 spec (Rev G, "Data Fields for Messages sent by the Slave",
|
||||
* BYTE 2 bits 3-5) fixes the USD mapping:
|
||||
*
|
||||
* Defaults follow Pyramid's standard datasets (US = $1/$5/$10/$20/$50/$100;
|
||||
* $2 channel omitted as it's rarely enabled).
|
||||
* 001 = $1 010 = $2 011 = $5 100 = $10
|
||||
* 101 = $20 110 = $50 111 = $100
|
||||
*
|
||||
* $2 occupies channel 2 whether or not the unit accepts $2 notes. An earlier
|
||||
* version of this table omitted it as "rarely enabled", which shifted every
|
||||
* larger note down one slot: a $5 credited as $10, a $20 as $50, a $50 as
|
||||
* $100, and a $100 as nothing at all. Never drop an unused channel from these
|
||||
* arrays — pad it instead.
|
||||
*
|
||||
* For non-USD the spec says only "Foreign currencies are in sequential order
|
||||
* as note 1-7", so channel N is the Nth note type of whatever dataset is
|
||||
* flashed on the unit. The orderings below are the conventional ascending sets
|
||||
* and are UNVERIFIED against a real configuration card. Check the card before
|
||||
* a machine takes money in any of them.
|
||||
*/
|
||||
|
||||
export const denominations: Record<string, number[]> = {
|
||||
USD: [1, 5, 10, 20, 50, 100],
|
||||
USD: [1, 2, 5, 10, 20, 50, 100],
|
||||
EUR: [5, 10, 20, 50, 100, 200, 500],
|
||||
GBP: [5, 10, 20, 50],
|
||||
CAD: [5, 10, 20, 50, 100],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue