feat: add aveiro cash units to the devices table

feat: change data fetching to accomodate the new cash units
This commit is contained in:
Sérgio Salgado 2023-04-16 23:42:34 +01:00
parent 06f534fa48
commit 211c4b1ea7
19 changed files with 1011 additions and 155 deletions

View file

@ -20,8 +20,10 @@ function createCashboxBatch (deviceId, cashboxCount) {
} }
function updateMachineWithBatch (machineContext, oldCashboxCount) { function updateMachineWithBatch (machineContext, oldCashboxCount) {
const isValidContext = _.has(['deviceId', 'cashbox', 'cassettes'], machineContext) const cashUnits = machineContext.cashUnits
const isCassetteAmountWithinRange = _.inRange(constants.CASH_OUT_MINIMUM_AMOUNT_OF_CASSETTES, constants.CASH_OUT_MAXIMUM_AMOUNT_OF_CASSETTES + 1, _.size(machineContext.cassettes)) const isValidContext = _.has(['deviceId', 'cashUnits'], machineContext) && _.has(['cashbox', 'cassette1', 'cassette2', 'cassette3', 'cassette4', 'stacker1f', 'stacker1r', 'stacker2f', 'stacker2r', 'stacker3f', 'stacker3r'], cashUnits)
const cassettes = _.filter(it => !_.isNil(it))([cashUnits.cassette1, cashUnits.cassette2, cashUnits.cassette3, cashUnits.cassette4])
const isCassetteAmountWithinRange = _.inRange(constants.CASH_OUT_MINIMUM_AMOUNT_OF_CASSETTES, constants.CASH_OUT_MAXIMUM_AMOUNT_OF_CASSETTES + 1, _.size(cassettes))
if (!isValidContext && !isCassetteAmountWithinRange) if (!isValidContext && !isCassetteAmountWithinRange)
throw new Error('Insufficient info to create a new cashbox batch') throw new Error('Insufficient info to create a new cashbox batch')
if (_.isEqual(0, oldCashboxCount)) throw new Error('Cash box is empty. Cash box batch could not be created.') if (_.isEqual(0, oldCashboxCount)) throw new Error('Cash box is empty. Cash box batch could not be created.')
@ -34,12 +36,18 @@ function updateMachineWithBatch (machineContext, oldCashboxCount) {
WHERE bills.cash_in_txs_id = cash_in_txs.id AND WHERE bills.cash_in_txs_id = cash_in_txs.id AND
cash_in_txs.device_id = $2 AND cash_in_txs.device_id = $2 AND
bills.cashbox_batch_id IS NULL`, [batchId, deviceId]) bills.cashbox_batch_id IS NULL`, [batchId, deviceId])
const q3 = t.none(`UPDATE devices SET cashbox=$1, cassette1=$2, cassette2=$3, cassette3=$4, cassette4=$5 WHERE device_id=$6`, [ const q3 = t.none(`UPDATE devices SET cashbox=$1, cassette1=$2, cassette2=$3, cassette3=$4, cassette4=$5, stacker1f=$6, stacker1r=$7, stacker1f=$8, stacker1r=$9, stacker1f=$10, stacker1r=$11 WHERE device_id=$12`, [
machineContext.cashbox, cashUnits.cashbox,
machineContext.cassettes[0], cashUnits.cassette1,
machineContext.cassettes[1], cashUnits.cassette2,
machineContext.cassettes[2], cashUnits.cassette3,
machineContext.cassettes[3], cashUnits.cassette4,
cashUnits.stacker1f,
cashUnits.stacker1r,
cashUnits.stacker2f,
cashUnits.stacker2r,
cashUnits.stacker3f,
cashUnits.stacker3r,
machineContext.deviceId machineContext.deviceId
]) ])

View file

@ -21,11 +21,19 @@ const stuckStatus = { label: 'Stuck', type: 'error' }
function toMachineObject (r) { function toMachineObject (r) {
return { return {
deviceId: r.device_id, deviceId: r.device_id,
cashbox: r.cashbox, cashUnits: {
cassette1: r.cassette1, cashbox: r.cashbox,
cassette2: r.cassette2, cassette1: r.cassette1,
cassette3: r.cassette3, cassette2: r.cassette2,
cassette4: r.cassette4, cassette3: r.cassette3,
cassette4: r.cassette4,
stacker1f: r.stacker1f,
stacker1r: r.stacker1r,
stacker2f: r.stacker2f,
stacker2r: r.stacker2r,
stacker3f: r.stacker3f,
stacker3r: r.stacker3r
},
numberOfCassettes: r.number_of_cassettes, numberOfCassettes: r.number_of_cassettes,
version: r.version, version: r.version,
model: r.model, model: r.model,
@ -141,8 +149,9 @@ function renameMachine (rec) {
function resetCashOutBills (rec) { function resetCashOutBills (rec) {
const detailB = notifierUtils.buildDetail({ deviceId: rec.deviceId }) const detailB = notifierUtils.buildDetail({ deviceId: rec.deviceId })
const sql = `UPDATE devices SET cassette1=$1, cassette2=$2, cassette3=$3, cassette4=$4 WHERE device_id=$5;` const { cassette1, cassette2, cassette3, cassette4, stacker1f, stacker1r, stacker2f, stacker2r, stacker3f, stacker3r } = rec.cashUnits
return db.none(sql, [rec.cassettes[0], rec.cassettes[1], rec.cassettes[2], rec.cassettes[3], rec.deviceId]).then(() => notifierQueries.invalidateNotification(detailB, 'fiatBalance')) const sql = `UPDATE devices SET cassette1=$1, cassette2=$2, cassette3=$3, cassette4=$4, stacker1f=$5, stacker1r=$6, stacker2f=$7, stacker2r=$8, stacker3f=$9, stacker3r=$10 WHERE device_id=$11;`
return db.none(sql, [cassette1, cassette2, cassette3, cassette4, stacker1f, stacker1r, stacker2f, stacker2r, stacker3f, stacker3r, rec.deviceId]).then(() => notifierQueries.invalidateNotification(detailB, 'fiatBalance'))
} }
function emptyCashInBills (rec) { function emptyCashInBills (rec) {
@ -151,11 +160,12 @@ function emptyCashInBills (rec) {
} }
function setCassetteBills (rec) { function setCassetteBills (rec) {
const { cashbox, cassette1, cassette2, cassette3, cassette4, stacker1f, stacker1r, stacker2f, stacker2r, stacker3f, stacker3r } = rec.cashUnits
return db.oneOrNone(`SELECT cashbox FROM devices WHERE device_id=$1 LIMIT 1`, [rec.deviceId]) return db.oneOrNone(`SELECT cashbox FROM devices WHERE device_id=$1 LIMIT 1`, [rec.deviceId])
.then(oldCashboxValue => { .then(oldCashboxValue => {
if (_.isNil(oldCashboxValue) || rec.cashbox === oldCashboxValue.cashbox) { if (_.isNil(oldCashboxValue) || cashbox === oldCashboxValue.cashbox) {
const sql = 'UPDATE devices SET cashbox=$1, cassette1=$2, cassette2=$3, cassette3=$4, cassette4=$5 WHERE device_id=$6' const sql = 'UPDATE devices SET cashbox=$1, cassette1=$2, cassette2=$3, cassette3=$4, cassette4=$5, stacker1f=$6, stacker1r=$7, stacker2f=$8, stacker2r=$9, stacker3f=$10, stacker3r=$11 WHERE device_id=$12'
return db.none(sql, [rec.cashbox, rec.cassettes[0], rec.cassettes[1], rec.cassettes[2], rec.cassettes[3], rec.deviceId]) return db.none(sql, [cashbox, cassette1, cassette2, cassette3, cassette4, stacker1f, stacker1r, stacker2f, stacker2r, stacker3f, stacker3r, rec.deviceId])
} }
return batching.updateMachineWithBatch({ ...rec, oldCashboxValue }) return batching.updateMachineWithBatch({ ...rec, oldCashboxValue })

View file

@ -19,8 +19,8 @@ const resolvers = {
unpairedMachines: () => machineLoader.getUnpairedMachines() unpairedMachines: () => machineLoader.getUnpairedMachines()
}, },
Mutation: { Mutation: {
machineAction: (...[, { deviceId, action, cashbox, cassette1, cassette2, cassette3, cassette4, newName }, context]) => machineAction: (...[, { deviceId, action, cashUnits, newName }, context]) =>
machineAction({ deviceId, action, cashbox, cassette1, cassette2, cassette3, cassette4, newName }, context) machineAction({ deviceId, action, cashUnits, newName }, context)
} }
} }

View file

@ -14,11 +14,7 @@ const typeDef = gql`
pairedAt: Date pairedAt: Date
version: String version: String
model: String model: String
cashbox: Int cashUnits: CashUnits
cassette1: Int
cassette2: Int
cassette3: Int
cassette4: Int
numberOfCassettes: Int numberOfCassettes: Int
statuses: [MachineStatus] statuses: [MachineStatus]
latestEvent: MachineEvent latestEvent: MachineEvent
@ -27,6 +23,34 @@ const typeDef = gql`
packetLoss: String packetLoss: String
} }
type CashUnits {
cashbox: Int
cassette1: Int
cassette2: Int
cassette3: Int
cassette4: Int
stacker1f: Int
stacker1r: Int
stacker2f: Int
stacker2r: Int
stacker3f: Int
stacker3r: Int
}
input CashUnitsInput {
cashbox: Int
cassette1: Int
cassette2: Int
cassette3: Int
cassette4: Int
stacker1f: Int
stacker1r: Int
stacker2f: Int
stacker2r: Int
stacker3f: Int
stacker3r: Int
}
type UnpairedMachine { type UnpairedMachine {
id: ID! id: ID!
deviceId: ID! deviceId: ID!
@ -64,7 +88,7 @@ const typeDef = gql`
} }
type Mutation { type Mutation {
machineAction(deviceId:ID!, action: MachineAction!, cashbox: Int, cassette1: Int, cassette2: Int, cassette3: Int, cassette4: Int, newName: String): Machine @auth machineAction(deviceId:ID!, action: MachineAction!, cashUnits: CashUnitsInput, newName: String): Machine @auth
} }
` `

View file

@ -6,14 +6,14 @@ function getMachine (machineId) {
.then(machines => machines.find(({ deviceId }) => deviceId === machineId)) .then(machines => machines.find(({ deviceId }) => deviceId === machineId))
} }
function machineAction ({ deviceId, action, cashbox, cassette1, cassette2, cassette3, cassette4, newName }, context) { function machineAction ({ deviceId, action, cashUnits, newName }, context) {
const operatorId = context.res.locals.operatorId const operatorId = context.res.locals.operatorId
return getMachine(deviceId) return getMachine(deviceId)
.then(machine => { .then(machine => {
if (!machine) throw new UserInputError(`machine:${deviceId} not found`, { deviceId }) if (!machine) throw new UserInputError(`machine:${deviceId} not found`, { deviceId })
return machine return machine
}) })
.then(machineLoader.setMachine({ deviceId, action, cashbox, cassettes: [cassette1, cassette2, cassette3, cassette4], newName }, operatorId)) .then(machineLoader.setMachine({ deviceId, action, cashUnits, newName }, operatorId))
.then(getMachine(deviceId)) .then(getMachine(deviceId))
} }

View file

@ -652,58 +652,58 @@ function plugins (settings, deviceId) {
const machineName = device.name const machineName = device.name
const cashInAlert = device.cashbox > notifications.cashInAlertThreshold const cashInAlert = device.cashUnits.cashbox > notifications.cashInAlertThreshold
? { ? {
code: 'CASH_BOX_FULL', code: 'CASH_BOX_FULL',
machineName, machineName,
deviceId: device.deviceId, deviceId: device.deviceId,
notes: device.cashbox notes: device.cashUnits.cashbox
} }
: null : null
const cassette1Alert = device.numberOfCassettes >= 1 && isCassetteLow(device.cassette1, CASSETTE_MAX_CAPACITY, notifications.fillingPercentageCassette1) const cassette1Alert = device.numberOfCassettes >= 1 && isCassetteLow(device.cashUnits.cassette1, CASSETTE_MAX_CAPACITY, notifications.fillingPercentageCassette1)
? { ? {
code: 'LOW_CASH_OUT', code: 'LOW_CASH_OUT',
cassette: 1, cassette: 1,
machineName, machineName,
deviceId: device.deviceId, deviceId: device.deviceId,
notes: device.cassette1, notes: device.cashUnits.cassette1,
denomination: denomination1, denomination: denomination1,
fiatCode fiatCode
} }
: null : null
const cassette2Alert = device.numberOfCassettes >= 2 && isCassetteLow(device.cassette2, CASSETTE_MAX_CAPACITY, notifications.fillingPercentageCassette2) const cassette2Alert = device.numberOfCassettes >= 2 && isCassetteLow(device.cashUnits.cassette2, CASSETTE_MAX_CAPACITY, notifications.fillingPercentageCassette2)
? { ? {
code: 'LOW_CASH_OUT', code: 'LOW_CASH_OUT',
cassette: 2, cassette: 2,
machineName, machineName,
deviceId: device.deviceId, deviceId: device.deviceId,
notes: device.cassette2, notes: device.cashUnits.cassette2,
denomination: denomination2, denomination: denomination2,
fiatCode fiatCode
} }
: null : null
const cassette3Alert = device.numberOfCassettes >= 3 && isCassetteLow(device.cassette3, CASSETTE_MAX_CAPACITY, notifications.fillingPercentageCassette3) const cassette3Alert = device.numberOfCassettes >= 3 && isCassetteLow(device.cashUnits.cassette3, CASSETTE_MAX_CAPACITY, notifications.fillingPercentageCassette3)
? { ? {
code: 'LOW_CASH_OUT', code: 'LOW_CASH_OUT',
cassette: 3, cassette: 3,
machineName, machineName,
deviceId: device.deviceId, deviceId: device.deviceId,
notes: device.cassette3, notes: device.cashUnits.cassette3,
denomination: denomination3, denomination: denomination3,
fiatCode fiatCode
} }
: null : null
const cassette4Alert = device.numberOfCassettes >= 4 && isCassetteLow(device.cassette4, CASSETTE_MAX_CAPACITY, notifications.fillingPercentageCassette4) const cassette4Alert = device.numberOfCassettes >= 4 && isCassetteLow(device.cashUnits.cassette4, CASSETTE_MAX_CAPACITY, notifications.fillingPercentageCassette4)
? { ? {
code: 'LOW_CASH_OUT', code: 'LOW_CASH_OUT',
cassette: 4, cassette: 4,
machineName, machineName,
deviceId: device.deviceId, deviceId: device.deviceId,
notes: device.cassette4, notes: device.cashUnits.cassette4,
denomination: denomination4, denomination: denomination4,
fiatCode fiatCode
} }

View file

@ -26,7 +26,7 @@ function notifyCashboxRemoval (req, res, next) {
} }
logger.info('** DEBUG ** - Cashbox removal - Cashbox reset is set to automatic. A cashbox batch WILL be created') logger.info('** DEBUG ** - Cashbox removal - Cashbox reset is set to automatic. A cashbox batch WILL be created')
logger.info('** DEBUG ** - Cashbox removal - Creating new batch...') logger.info('** DEBUG ** - Cashbox removal - Creating new batch...')
return cashbox.createCashboxBatch(req.deviceId, machine.cashbox) return cashbox.createCashboxBatch(req.deviceId, machine.cashUnits.cashbox)
.then(() => { .then(() => {
logger.info(`** DEBUG ** - Cashbox removal - Finished creating the new cashbox batch`) logger.info(`** DEBUG ** - Cashbox removal - Finished creating the new cashbox batch`)
logger.info(`** DEBUG ** - Cashbox removal - Resetting the cashbox counter on device ${req.deviceId}`) logger.info(`** DEBUG ** - Cashbox removal - Resetting the cashbox counter on device ${req.deviceId}`)

View file

@ -0,0 +1,57 @@
const db = require('./db')
exports.up = function (next) {
var sql = [
`ALTER TABLE cash_out_actions
ADD COLUMN provisioned_1f INTEGER,
ADD COLUMN provisioned_1r INTEGER,
ADD COLUMN provisioned_2f INTEGER,
ADD COLUMN provisioned_2r INTEGER,
ADD COLUMN provisioned_3f INTEGER,
ADD COLUMN provisioned_3r INTEGER,
ADD COLUMN dispensed_1f INTEGER,
ADD COLUMN dispensed_1r INTEGER,
ADD COLUMN dispensed_2f INTEGER,
ADD COLUMN dispensed_2r INTEGER,
ADD COLUMN dispensed_3f INTEGER,
ADD COLUMN dispensed_3r INTEGER,
ADD COLUMN rejected_1f INTEGER,
ADD COLUMN rejected_1r INTEGER,
ADD COLUMN rejected_2f INTEGER,
ADD COLUMN rejected_2r INTEGER,
ADD COLUMN rejected_3f INTEGER,
ADD COLUMN rejected_3r INTEGER,
ADD COLUMN denomination_1f INTEGER,
ADD COLUMN denomination_1r INTEGER,
ADD COLUMN denomination_2f INTEGER,
ADD COLUMN denomination_2r INTEGER,
ADD COLUMN denomination_3f INTEGER,
ADD COLUMN denomination_3r INTEGER`,
`ALTER TABLE devices
ADD COLUMN stacker1f INTEGER NOT NULL DEFAULT 0,
ADD COLUMN stacker1r INTEGER NOT NULL DEFAULT 0,
ADD COLUMN stacker2f INTEGER NOT NULL DEFAULT 0,
ADD COLUMN stacker2r INTEGER NOT NULL DEFAULT 0,
ADD COLUMN stacker3f INTEGER NOT NULL DEFAULT 0,
ADD COLUMN stacker3r INTEGER NOT NULL DEFAULT 0`,
`ALTER TABLE cash_out_txs
ADD COLUMN provisioned_1f INTEGER,
ADD COLUMN provisioned_1r INTEGER,
ADD COLUMN provisioned_2f INTEGER,
ADD COLUMN provisioned_2r INTEGER,
ADD COLUMN provisioned_3f INTEGER,
ADD COLUMN provisioned_3r INTEGER,
ADD COLUMN denomination_1f INTEGER,
ADD COLUMN denomination_1r INTEGER,
ADD COLUMN denomination_2f INTEGER,
ADD COLUMN denomination_2r INTEGER,
ADD COLUMN denomination_3f INTEGER,
ADD COLUMN denomination_3r INTEGER`
]
db.multi(sql, next)
}
exports.down = function (next) {
next()
}

View file

@ -40,11 +40,19 @@ const GET_INFO = gql`
machines { machines {
name name
deviceId deviceId
cashbox cashUnits {
cassette1 cashbox
cassette2 cassette1
cassette3 cassette2
cassette4 cassette3
cassette4
stacker1f
stacker1r
stacker2f
stacker2r
stacker3f
stacker3r
}
numberOfCassettes numberOfCassettes
} }
config config

View file

@ -147,7 +147,10 @@ const MachinesTable = ({ machines = [], numToRender }) => {
it => it =>
machine.numberOfCassettes >= it ? ( machine.numberOfCassettes >= it ? (
<StyledCell align="left"> <StyledCell align="left">
{makePercentageText(it, machine[`cassette${it}`])} {makePercentageText(
it,
machine.cashUnits[`cassette${it}`]
)}
</StyledCell> </StyledCell>
) : ( ) : (
<StyledCell align="left"> <StyledCell align="left">

View file

@ -24,11 +24,19 @@ const GET_DATA = gql`
machines { machines {
name name
deviceId deviceId
cashbox cashUnits {
cassette1 cashbox
cassette2 cassette1
cassette3 cassette2
cassette4 cassette3
cassette4
stacker1f
stacker1r
stacker2f
stacker2r
stacker3f
stacker3r
}
numberOfCassettes numberOfCassettes
statuses { statuses {
label label

View file

@ -57,27 +57,23 @@ const SET_CASSETTE_BILLS = gql`
mutation MachineAction( mutation MachineAction(
$deviceId: ID! $deviceId: ID!
$action: MachineAction! $action: MachineAction!
$cashbox: Int! $cashUnits: CashUnitsInput
$cassette1: Int!
$cassette2: Int!
$cassette3: Int!
$cassette4: Int!
) { ) {
machineAction( machineAction(deviceId: $deviceId, action: $action, cashUnits: $cashUnits) {
deviceId: $deviceId
action: $action
cashbox: $cashbox
cassette1: $cassette1
cassette2: $cassette2
cassette3: $cassette3
cassette4: $cassette4
) {
deviceId deviceId
cashbox cashUnits {
cassette1 cashbox
cassette2 cassette1
cassette3 cassette2
cassette4 cassette3
cassette4
stacker1f
stacker1r
stacker2f
stacker2r
stacker3f
stacker3r
}
} }
} }
` `

View file

@ -29,11 +29,19 @@ const GET_INFO = gql`
pairedAt pairedAt
version version
model model
cashbox cashUnits {
cassette1 cashbox
cassette2 cassette1
cassette3 cassette2
cassette4 cassette3
cassette4
stacker1f
stacker1r
stacker2f
stacker2r
stacker3f
stacker3r
}
numberOfCassettes numberOfCassettes
statuses { statuses {
label label

View file

@ -19,10 +19,11 @@ import { ReactComponent as EditIcon } from 'src/styling/icons/action/edit/enable
import { ReactComponent as ReverseHistoryIcon } from 'src/styling/icons/circle buttons/history/white.svg' import { ReactComponent as ReverseHistoryIcon } from 'src/styling/icons/circle buttons/history/white.svg'
import { ReactComponent as HistoryIcon } from 'src/styling/icons/circle buttons/history/zodiac.svg' import { ReactComponent as HistoryIcon } from 'src/styling/icons/circle buttons/history/zodiac.svg'
import { fromNamespace, toNamespace } from 'src/utils/config' import { fromNamespace, toNamespace } from 'src/utils/config'
import { MANUAL, AUTOMATIC } from 'src/utils/constants.js' import { MANUAL, AUTOMATIC } from 'src/utils/constants'
import { hasRecycler } from 'src/utils/machine'
import { onlyFirstToUpper } from 'src/utils/string' import { onlyFirstToUpper } from 'src/utils/string'
import styles from './CashCassettes.styles.js' import styles from './CashCassettes.styles'
import CashCassettesFooter from './CashCassettesFooter' import CashCassettesFooter from './CashCassettesFooter'
import CashboxHistory from './CashboxHistory' import CashboxHistory from './CashboxHistory'
import Wizard from './Wizard/Wizard' import Wizard from './Wizard/Wizard'
@ -92,11 +93,20 @@ const GET_MACHINES_AND_CONFIG = gql`
machines { machines {
name name
id: deviceId id: deviceId
cashbox model
cassette1 cashUnits {
cassette2 cashbox
cassette3 cassette1
cassette4 cassette2
cassette3
cassette4
stacker1f
stacker1r
stacker2f
stacker2r
stacker3f
stacker3r
}
numberOfCassettes numberOfCassettes
} }
unpairedMachines { unpairedMachines {
@ -123,27 +133,23 @@ const SET_CASSETTE_BILLS = gql`
mutation MachineAction( mutation MachineAction(
$deviceId: ID! $deviceId: ID!
$action: MachineAction! $action: MachineAction!
$cashbox: Int! $cashUnits: CashUnitsInput
$cassette1: Int!
$cassette2: Int!
$cassette3: Int!
$cassette4: Int!
) { ) {
machineAction( machineAction(deviceId: $deviceId, action: $action, cashUnits: $cashUnits) {
deviceId: $deviceId
action: $action
cashbox: $cashbox
cassette1: $cassette1
cassette2: $cassette2
cassette3: $cassette3
cassette4: $cassette4
) {
deviceId deviceId
cashbox cashUnits {
cassette1 cashbox
cassette2 cassette1
cassette3 cassette2
cassette4 cassette3
cassette4
stacker1f
stacker1r
stacker2f
stacker2r
stacker3f
stacker3r
}
} }
} }
` `
@ -171,6 +177,9 @@ const CashCassettes = () => {
const [machineId, setMachineId] = useState('') const [machineId, setMachineId] = useState('')
const machines = R.path(['machines'])(data) ?? [] const machines = R.path(['machines'])(data) ?? []
const [nonRecyclerMachines, recyclerMachines] = R.partition(hasRecycler)(
machines
)
const unpairedMachines = R.path(['unpairedMachines'])(data) ?? [] const unpairedMachines = R.path(['unpairedMachines'])(data) ?? []
const config = R.path(['config'])(data) ?? {} const config = R.path(['config'])(data) ?? {}
const fillingPercentageSettings = fromNamespace('notifications', config) const fillingPercentageSettings = fromNamespace('notifications', config)
@ -192,20 +201,19 @@ const CashCassettes = () => {
const locale = data?.config && fromNamespace('locale')(data.config) const locale = data?.config && fromNamespace('locale')(data.config)
const fiatCurrency = locale?.fiatCurrency const fiatCurrency = locale?.fiatCurrency
const maxNumberOfCassettes = Math.max( const maxNumberOfCassettes = Math.max(
...R.map(it => it.numberOfCassettes, machines), ...R.map(it => it.numberOfCassettes, nonRecyclerMachines),
0 0
) )
const getCashoutSettings = id => fromNamespace(id)(cashout) const getCashoutSettings = id => fromNamespace(id)(cashout)
const isCashOutDisabled = ({ id }) => !getCashoutSettings(id).active const isCashOutDisabled = ({ id }) => !getCashoutSettings(id).active
const onSave = (id, cashbox, cassettes) => { const onSave = (id, cashUnits) => {
return setCassetteBills({ return setCassetteBills({
variables: { variables: {
action: 'setCassetteBills', action: 'setCassetteBills',
deviceId: id, deviceId: id,
cashbox, cashUnits
...cassettes
} }
}) })
} }
@ -247,10 +255,10 @@ const CashCassettes = () => {
name: 'cashbox', name: 'cashbox',
header: 'Cash box', header: 'Cash box',
width: widthsByNumberOfCassettes[maxNumberOfCassettes]?.cashbox, width: widthsByNumberOfCassettes[maxNumberOfCassettes]?.cashbox,
view: (value, { id }) => ( view: (_, { id, cashUnits }) => (
<CashIn <CashIn
currency={{ code: fiatCurrency }} currency={{ code: fiatCurrency }}
notes={value} notes={cashUnits.cashbox}
total={R.sum(R.map(it => it.fiat, bills[id] ?? []))} total={R.sum(R.map(it => it.fiat, bills[id] ?? []))}
/> />
), ),
@ -270,12 +278,12 @@ const CashCassettes = () => {
width: widthsByNumberOfCassettes[maxNumberOfCassettes]?.cassette, width: widthsByNumberOfCassettes[maxNumberOfCassettes]?.cassette,
stripe: true, stripe: true,
doubleHeader: 'Cash-out', doubleHeader: 'Cash-out',
view: (value, { id }) => ( view: (_, { id, cashUnits }) => (
<CashOut <CashOut
className={classes.cashbox} className={classes.cashbox}
denomination={getCashoutSettings(id)?.[`cassette${it}`]} denomination={getCashoutSettings(id)?.[`cassette${it}`]}
currency={{ code: fiatCurrency }} currency={{ code: fiatCurrency }}
notes={value} notes={cashUnits[`cassette${it}`]}
width={ width={
widthsByNumberOfCassettes[maxNumberOfCassettes]?.cassetteGraph widthsByNumberOfCassettes[maxNumberOfCassettes]?.cassetteGraph
} }
@ -302,7 +310,7 @@ const CashCassettes = () => {
header: 'Edit', header: 'Edit',
width: widthsByNumberOfCassettes[maxNumberOfCassettes]?.editWidth, width: widthsByNumberOfCassettes[maxNumberOfCassettes]?.editWidth,
textAlign: 'center', textAlign: 'center',
view: (value, { id }) => { view: (_, { id }) => {
return ( return (
<IconButton <IconButton
onClick={() => { onClick={() => {
@ -374,7 +382,17 @@ const CashCassettes = () => {
name="cashboxes" name="cashboxes"
stripeWhen={isCashOutDisabled} stripeWhen={isCashOutDisabled}
elements={elements} elements={elements}
data={machines} data={nonRecyclerMachines}
validationSchema={ValidationSchema}
tbodyWrapperClass={classes.tBody}
/>
<EditableTable
error={error?.message}
name="cashboxes"
stripeWhen={isCashOutDisabled}
elements={elements}
data={recyclerMachines}
validationSchema={ValidationSchema} validationSchema={ValidationSchema}
tbodyWrapperClass={classes.tBody} tbodyWrapperClass={classes.tBody}
/> />

View file

@ -25,9 +25,19 @@ const GET_MACHINES = gql`
pairedAt pairedAt
version version
paired paired
cashbox cashUnits {
cassette1 cashbox
cassette2 cassette1
cassette2
cassette3
cassette4
stacker1f
stacker1r
stacker2f
stacker2r
stacker3f
stacker3r
}
version version
model model
statuses { statuses {

View file

@ -18,6 +18,15 @@ const CASSETTE_FIELDS = R.map(
R.range(1, MAX_NUMBER_OF_CASSETTES + 1) R.range(1, MAX_NUMBER_OF_CASSETTES + 1)
) )
const STACKER_FIELDS = [
'stacker1f',
'stacker1r',
'stacker2f',
'stacker2r',
'stacker3f',
'stacker3r'
]
const Wizard = ({ machine, cashoutSettings, locale, onClose, save, error }) => { const Wizard = ({ machine, cashoutSettings, locale, onClose, save, error }) => {
const [{ step, config }, setState] = useState({ const [{ step, config }, setState] = useState({
step: 0, step: 0,
@ -45,6 +54,17 @@ const Wizard = ({ machine, cashoutSettings, locale, onClose, save, error }) => {
) )
} }
const buildStackerObj = cassetteInput => {
return R.reduce(
(acc, value) => {
acc[value] = defaultToZero(cassetteInput[value])
return acc
},
{},
STACKER_FIELDS
)
}
const onContinue = it => { const onContinue = it => {
const newConfig = R.merge(config, it) const newConfig = R.merge(config, it)
if (isLastStep) { if (isLastStep) {
@ -53,10 +73,16 @@ const Wizard = ({ machine, cashoutSettings, locale, onClose, save, error }) => {
it?.wasCashboxEmptied it?.wasCashboxEmptied
].includes('YES') ].includes('YES')
const cashbox = wasCashboxEmptied ? 0 : machine?.cashbox
const cassettes = buildCassetteObj(it) const cassettes = buildCassetteObj(it)
const stackers = buildStackerObj(it)
save(machine.id, cashbox, cassettes) const cashUnits = {
cashbox: wasCashboxEmptied ? 0 : machine?.cashUnits.cashbox,
...cassettes,
...stackers
}
save(machine.id, cashUnits)
return onClose() return onClose()
} }

View file

@ -206,7 +206,7 @@ const WizardStep = ({
classes.lineAlignment classes.lineAlignment
)}> )}>
<Info1 noMargin className={classes.cashboxBills}> <Info1 noMargin className={classes.cashboxBills}>
{machine?.cashbox} {machine?.cashUnits.cashbox}
</Info1> </Info1>
<P noMargin>accepted bills</P> <P noMargin>accepted bills</P>
</div> </div>

View file

@ -2,7 +2,24 @@ const modelPrettifier = {
douro1: 'Douro', douro1: 'Douro',
sintra: 'Sintra', sintra: 'Sintra',
gaia: 'Gaia', gaia: 'Gaia',
tejo: 'Tejo' tejo: 'Tejo',
aveiro: 'Aveiro',
grandola: 'Grândola'
} }
export { modelPrettifier } const hasRecycler = machine =>
machine.model === 'aveiro' || machine.model === 'grandola'
const cashUnitCapacity = {
tejo: {
cashbox: 1000,
cassette: 500
},
aveiro: {
cashbox: 500,
cassette: 200,
stacker: 60
}
}
export { modelPrettifier, cashUnitCapacity, hasRecycler }

737
package-lock.json generated

File diff suppressed because it is too large Load diff