refactor: use recyclers instead of stackers
This commit is contained in:
parent
dc52cf4414
commit
21b88f182e
37 changed files with 2868 additions and 9599 deletions
36
bin/lamassu-update-recyclers
Normal file
36
bin/lamassu-update-recyclers
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
require('../lib/environment-helper')
|
||||||
|
|
||||||
|
const _ = require('lodash')
|
||||||
|
const db = require('../lib/db')
|
||||||
|
|
||||||
|
if (process.argv.length !== 4) {
|
||||||
|
console.log('Usage: lamassu-update-recyclers <device_id> <number_of_recyclers>')
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_.isFinite(parseInt(process.argv[3]))) {
|
||||||
|
console.log('Error: <number_of_recyclers> is not a valid number (%s)', err)
|
||||||
|
process.exit(3)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parseInt(process.argv[3]) > 6 || parseInt(process.argv[3]) < 1) {
|
||||||
|
console.log('Error: <number_of_recyclers> is out of range. Should be a number between 1 and 3')
|
||||||
|
process.exit(3)
|
||||||
|
}
|
||||||
|
|
||||||
|
const deviceId = process.argv[2]
|
||||||
|
const numberOfRecyclers = parseInt(process.argv[3])
|
||||||
|
|
||||||
|
const query = `UPDATE devices SET number_of_recyclers = $1 WHERE device_id = $2`
|
||||||
|
|
||||||
|
db.none(query, [numberOfRecyclers, deviceId])
|
||||||
|
.then(() => {
|
||||||
|
console.log('Success! Device %s updated to %s recyclers', deviceId, numberOfRecyclers)
|
||||||
|
process.exit(0)
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log('Error: %s', err)
|
||||||
|
process.exit(3)
|
||||||
|
})
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
#!/usr/bin/env node
|
|
||||||
|
|
||||||
require('../lib/environment-helper')
|
|
||||||
|
|
||||||
const _ = require('lodash')
|
|
||||||
const db = require('../lib/db')
|
|
||||||
|
|
||||||
if (process.argv.length !== 4) {
|
|
||||||
console.log('Usage: lamassu-update-stackers <device_id> <number_of_stackers>')
|
|
||||||
process.exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_.isFinite(parseInt(process.argv[3]))) {
|
|
||||||
console.log('Error: <number_of_stackers> is not a valid number (%s)', err)
|
|
||||||
process.exit(3)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parseInt(process.argv[3]) > 3 || parseInt(process.argv[3]) < 1) {
|
|
||||||
console.log('Error: <number_of_stackers> is out of range. Should be a number between 1 and 3')
|
|
||||||
process.exit(3)
|
|
||||||
}
|
|
||||||
|
|
||||||
const deviceId = process.argv[2]
|
|
||||||
const numberOfStackers = parseInt(process.argv[3])
|
|
||||||
|
|
||||||
const query = `UPDATE devices SET number_of_stackers = $1 WHERE device_id = $2`
|
|
||||||
|
|
||||||
db.none(query, [numberOfStackers, deviceId])
|
|
||||||
.then(() => {
|
|
||||||
console.log('Success! Device %s updated to %s stackers', deviceId, numberOfStackers)
|
|
||||||
process.exit(0)
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
console.log('Error: %s', err)
|
|
||||||
process.exit(3)
|
|
||||||
})
|
|
||||||
|
|
@ -50,17 +50,17 @@ function insertNewBills (t, billRows, machineTx) {
|
||||||
const columns = ['id', 'fiat', 'fiat_code', 'crypto_code', 'cash_in_fee', 'cash_in_txs_id', 'device_time', 'destination_unit']
|
const columns = ['id', 'fiat', 'fiat_code', 'crypto_code', 'cash_in_fee', 'cash_in_txs_id', 'device_time', 'destination_unit']
|
||||||
const sql = pgp.helpers.insert(dbBills, columns, 'bills')
|
const sql = pgp.helpers.insert(dbBills, columns, 'bills')
|
||||||
const deviceID = machineTx.deviceId
|
const deviceID = machineTx.deviceId
|
||||||
const sql2 = `update devices set stacker1f = stacker1f + $2, stacker1r = stacker1r + $3, stacker2f = stacker2f + $4, stacker2r = stacker2r + $5, stacker3f = stacker3f + $6, stacker3r = stacker3r + $7
|
const sql2 = `update devices set recycler1 = recycler1 + $2, recycler2 = recycler2 + $3, recycler3 = recycler3 + $4, recycler4 = recycler4 + $5, recycler5 = recycler5 + $6, recycler6 = recycler6 + $7
|
||||||
where device_id = $1`
|
where device_id = $1`
|
||||||
|
|
||||||
return t.none(sql2, [
|
return t.none(sql2, [
|
||||||
deviceID,
|
deviceID,
|
||||||
getBillsByDestination('stacker1f').length,
|
getBillsByDestination('recycler1').length,
|
||||||
getBillsByDestination('stacker1r').length,
|
getBillsByDestination('recycler2').length,
|
||||||
getBillsByDestination('stacker2f').length,
|
getBillsByDestination('recycler3').length,
|
||||||
getBillsByDestination('stacker2r').length,
|
getBillsByDestination('recycler4').length,
|
||||||
getBillsByDestination('stacker3f').length,
|
getBillsByDestination('recycler5').length,
|
||||||
getBillsByDestination('stacker3r').length
|
getBillsByDestination('recycler6').length
|
||||||
])
|
])
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return t.none(sql)
|
return t.none(sql)
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ function mapDispense (tx) {
|
||||||
const res = {}
|
const res = {}
|
||||||
|
|
||||||
_.forEach(it => {
|
_.forEach(it => {
|
||||||
const suffix = bills[it].name.replace(/cassette|stacker/gi, '')
|
const suffix = _.snakeCase(bills[it].name.replace(/cassette/gi, ''))
|
||||||
res[`provisioned_${suffix}`] = bills[it].provisioned
|
res[`provisioned_${suffix}`] = bills[it].provisioned
|
||||||
res[`denomination_${suffix}`] = bills[it].denomination
|
res[`denomination_${suffix}`] = bills[it].denomination
|
||||||
res[`dispensed_${suffix}`] = bills[it].dispensed
|
res[`dispensed_${suffix}`] = bills[it].dispensed
|
||||||
|
|
|
||||||
|
|
@ -18,31 +18,33 @@ case
|
||||||
end`
|
end`
|
||||||
|
|
||||||
const MAX_CASSETTES = 4
|
const MAX_CASSETTES = 4
|
||||||
const MAX_STACKERS = 3
|
const MAX_RECYCLERS = 6
|
||||||
|
|
||||||
const BILL_FIELDS = [
|
const SNAKE_CASE_BILL_FIELDS = [
|
||||||
'denomination1',
|
'denomination_1',
|
||||||
'denomination2',
|
'denomination_2',
|
||||||
'denomination3',
|
'denomination_3',
|
||||||
'denomination4',
|
'denomination_4',
|
||||||
'denomination1f',
|
'denomination_recycler_1',
|
||||||
'denomination1r',
|
'denomination_recycler_2',
|
||||||
'denomination2f',
|
'denomination_recycler_3',
|
||||||
'denomination2r',
|
'denomination_recycler_4',
|
||||||
'denomination3f',
|
'denomination_recycler_5',
|
||||||
'denomination3r',
|
'denomination_recycler_6',
|
||||||
'provisioned1',
|
'provisioned_1',
|
||||||
'provisioned2',
|
'provisioned_2',
|
||||||
'provisioned3',
|
'provisioned_3',
|
||||||
'provisioned4',
|
'provisioned_4',
|
||||||
'provisioned1f',
|
'provisioned_recycler_1',
|
||||||
'provisioned1r',
|
'provisioned_recycler_2',
|
||||||
'provisioned2f',
|
'provisioned_recycler_3',
|
||||||
'provisioned2r',
|
'provisioned_recycler_4',
|
||||||
'provisioned3f',
|
'provisioned_recycler_5',
|
||||||
'provisioned3r'
|
'provisioned_recycler_6'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const BILL_FIELDS = _.map(_.camelCase, BILL_FIELDS)
|
||||||
|
|
||||||
module.exports = { redeemableTxs, toObj, toDb, REDEEMABLE_AGE, CASH_OUT_TRANSACTION_STATES }
|
module.exports = { redeemableTxs, toObj, toDb, REDEEMABLE_AGE, CASH_OUT_TRANSACTION_STATES }
|
||||||
|
|
||||||
const mapValuesWithKey = _.mapValues.convert({cap: false})
|
const mapValuesWithKey = _.mapValues.convert({cap: false})
|
||||||
|
|
@ -69,19 +71,17 @@ function convertBigNumFields (obj) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function convertField (key) {
|
function convertField (key) {
|
||||||
return _.includes('denomination', key) || _.includes('provisioned', key) ? key : _.snakeCase(key)
|
return _.snakeCase(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
function addDbBills (tx) {
|
function addDbBills (tx) {
|
||||||
const bills = tx.bills
|
const bills = tx.bills
|
||||||
if (_.isEmpty(bills)) return tx
|
if (_.isEmpty(bills)) return tx
|
||||||
|
|
||||||
const billFields = _.map(it => _.replace(/(denomination|provisioned)/g, '$1_')(it), BILL_FIELDS)
|
|
||||||
|
|
||||||
const billsObj = _.flow(
|
const billsObj = _.flow(
|
||||||
_.reduce(
|
_.reduce(
|
||||||
(acc, value) => {
|
(acc, value) => {
|
||||||
const suffix = value.name.replace(/cassette|stacker/gi, '')
|
const suffix = _.snakeCase(value.name.replace(/cassette/gi, ''))
|
||||||
return {
|
return {
|
||||||
...acc,
|
...acc,
|
||||||
[`provisioned_${suffix}`]: value.provisioned,
|
[`provisioned_${suffix}`]: value.provisioned,
|
||||||
|
|
@ -96,7 +96,7 @@ function addDbBills (tx) {
|
||||||
return _.assign({ [value]: 0 })(acc)
|
return _.assign({ [value]: 0 })(acc)
|
||||||
},
|
},
|
||||||
{}
|
{}
|
||||||
)(_.difference(billFields, _.keys(it)))
|
)(_.difference(SNAKE_CASE_BILL_FIELDS, _.keys(it)))
|
||||||
return _.assign(missingKeys, it)
|
return _.assign(missingKeys, it)
|
||||||
}
|
}
|
||||||
)(bills)
|
)(bills)
|
||||||
|
|
@ -118,7 +118,7 @@ function toObj (row) {
|
||||||
let newObj = {}
|
let newObj = {}
|
||||||
|
|
||||||
keys.forEach(key => {
|
keys.forEach(key => {
|
||||||
const objKey = key.match(/denomination|provisioned/g) ? key.replace(/_/g, '') : _.camelCase(key)
|
const objKey = _.camelCase(key)
|
||||||
if (key === 'received_crypto_atoms' && row[key]) {
|
if (key === 'received_crypto_atoms' && row[key]) {
|
||||||
newObj[objKey] = new BN(row[key])
|
newObj[objKey] = new BN(row[key])
|
||||||
return
|
return
|
||||||
|
|
@ -138,16 +138,7 @@ function toObj (row) {
|
||||||
|
|
||||||
const billFieldsArr = _.concat(
|
const billFieldsArr = _.concat(
|
||||||
_.map(it => ({ name: `cassette${it + 1}`, denomination: newObj[`denomination${it + 1}`], provisioned: newObj[`provisioned${it + 1}`] }))(_.range(0, MAX_CASSETTES)),
|
_.map(it => ({ name: `cassette${it + 1}`, denomination: newObj[`denomination${it + 1}`], provisioned: newObj[`provisioned${it + 1}`] }))(_.range(0, MAX_CASSETTES)),
|
||||||
_.reduce(
|
_.map(it => ({ name: `recycler${it + 1}`, denomination: newObj[`denomination_recycler${it + 1}`], provisioned: newObj[`provisioned_recycler${it + 1}`] }))(_.range(0, MAX_RECYCLERS)),
|
||||||
(acc, value) => {
|
|
||||||
acc.push(
|
|
||||||
{ name: `stacker${value + 1}f`, denomination: newObj[`denomination${value + 1}f`], provisioned: newObj[`provisioned${value + 1}f`] },
|
|
||||||
{ name: `stacker${value + 1}r`, denomination: newObj[`denomination${value + 1}r`], provisioned: newObj[`provisioned${value + 1}r`] }
|
|
||||||
)
|
|
||||||
return acc
|
|
||||||
},
|
|
||||||
[]
|
|
||||||
)(_.range(0, MAX_STACKERS))
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// There can't be bills with denomination === 0.
|
// There can't be bills with denomination === 0.
|
||||||
|
|
@ -164,7 +155,9 @@ function redeemableTxs (deviceId) {
|
||||||
and dispense=$3
|
and dispense=$3
|
||||||
and (
|
and (
|
||||||
provisioned_1 is not null or provisioned_2 is not null or provisioned_3 is not null or provisioned_4 is not null or
|
provisioned_1 is not null or provisioned_2 is not null or provisioned_3 is not null or provisioned_4 is not null or
|
||||||
provisioned_1f is not null or provisioned_1r is not null or provisioned_2f is not null or provisioned_2r is not null or provisioned_3f is not null or provisioned_3r is not null
|
provisioned_recycler_1 is not null or provisioned_recycler_2 is not null or
|
||||||
|
provisioned_recycler_3 is not null or provisioned_recycler_4 is not null or
|
||||||
|
provisioned_recycler_5 is not null or provisioned_recycler_6 is not null
|
||||||
)
|
)
|
||||||
and extract(epoch from (now() - greatest(created, confirmed_at))) < $4`
|
and extract(epoch from (now() - greatest(created, confirmed_at))) < $4`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ function postProcess (txVector, justAuthorized, pi) {
|
||||||
if ((newTx.dispense && !oldTx.dispense) || (newTx.redeem && !oldTx.redeem)) {
|
if ((newTx.dispense && !oldTx.dispense) || (newTx.redeem && !oldTx.redeem)) {
|
||||||
return pi.buildAvailableUnits(newTx.id)
|
return pi.buildAvailableUnits(newTx.id)
|
||||||
.then(_units => {
|
.then(_units => {
|
||||||
const units = _.concat(_units.cassettes, _units.stackers)
|
const units = _.concat(_units.cassettes, _units.recyclers)
|
||||||
logger.silly('Computing bills to dispense:', {
|
logger.silly('Computing bills to dispense:', {
|
||||||
txId: newTx.id,
|
txId: newTx.id,
|
||||||
units: units,
|
units: units,
|
||||||
|
|
@ -74,7 +74,7 @@ function postProcess (txVector, justAuthorized, pi) {
|
||||||
const rec = {}
|
const rec = {}
|
||||||
|
|
||||||
_.forEach(it => {
|
_.forEach(it => {
|
||||||
const suffix = bills[it].name.replace(/cassette|stacker/gi, '')
|
const suffix = _.snakeCase(bills[it].name.replace(/cassette/gi, ''))
|
||||||
rec[`provisioned_${suffix}`] = bills[it].provisioned
|
rec[`provisioned_${suffix}`] = bills[it].provisioned
|
||||||
rec[`denomination_${suffix}`] = bills[it].denomination
|
rec[`denomination_${suffix}`] = bills[it].denomination
|
||||||
}, _.times(_.identity(), _.size(bills)))
|
}, _.times(_.identity(), _.size(bills)))
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,8 @@ function createCashboxBatch (deviceId, cashboxCount) {
|
||||||
|
|
||||||
function updateMachineWithBatch (machineContext, oldCashboxCount) {
|
function updateMachineWithBatch (machineContext, oldCashboxCount) {
|
||||||
const cashUnits = machineContext.cashUnits
|
const cashUnits = machineContext.cashUnits
|
||||||
const isValidContext = _.has(['deviceId', 'cashUnits'], machineContext) && _.has(['cashbox', 'cassette1', 'cassette2', 'cassette3', 'cassette4', 'stacker1f', 'stacker1r', 'stacker2f', 'stacker2r', 'stacker3f', 'stacker3r'], cashUnits)
|
const cashUnitNames = ['cashbox', 'cassette1', 'cassette2', 'cassette3', 'cassette4', 'recycler1', 'recycler2', 'recycler3', 'recycler4', 'recycler5', 'recycler6']
|
||||||
|
const isValidContext = _.has(['deviceId', 'cashUnits'], machineContext) && _.has(cashUnitNames, cashUnits)
|
||||||
const cassettes = _.filter(it => !_.isNil(it))([cashUnits.cassette1, cashUnits.cassette2, cashUnits.cassette3, cashUnits.cassette4])
|
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))
|
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)
|
||||||
|
|
@ -48,17 +49,17 @@ function updateMachineWithBatch (machineContext, oldCashboxCount) {
|
||||||
bills.cashbox_batch_id IS NULL`, [batchId, deviceId])
|
bills.cashbox_batch_id IS NULL`, [batchId, deviceId])
|
||||||
const q3 = t.none(`UPDATE empty_unit_bills SET cashbox_batch_id=$1
|
const q3 = t.none(`UPDATE empty_unit_bills SET cashbox_batch_id=$1
|
||||||
WHERE empty_unit_bills.device_id = $2 AND empty_unit_bills.cashbox_batch_id IS NULL`, [batchId, deviceId])
|
WHERE empty_unit_bills.device_id = $2 AND empty_unit_bills.cashbox_batch_id IS NULL`, [batchId, deviceId])
|
||||||
const q4 = t.none(`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`, [
|
const q4 = t.none(`UPDATE devices SET cassette1=$1, cassette2=$2, cassette3=$3, cassette4=$4, recycler1=$5, recycler2=$6, recycler3=$7, recycler3=$8, recycler4=$9, recycler5=$10 WHERE device_id=$11`, [
|
||||||
cashUnits.cassette1,
|
cashUnits.cassette1,
|
||||||
cashUnits.cassette2,
|
cashUnits.cassette2,
|
||||||
cashUnits.cassette3,
|
cashUnits.cassette3,
|
||||||
cashUnits.cassette4,
|
cashUnits.cassette4,
|
||||||
cashUnits.stacker1f,
|
cashUnits.recycler1,
|
||||||
cashUnits.stacker1r,
|
cashUnits.recycler2,
|
||||||
cashUnits.stacker2f,
|
cashUnits.recycler3,
|
||||||
cashUnits.stacker2r,
|
cashUnits.recycler4,
|
||||||
cashUnits.stacker3f,
|
cashUnits.recycler5,
|
||||||
cashUnits.stacker3r,
|
cashUnits.recycler6,
|
||||||
machineContext.deviceId
|
machineContext.deviceId
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ const CASH_UNIT_CAPACITY = {
|
||||||
},
|
},
|
||||||
aveiro: {
|
aveiro: {
|
||||||
cashbox: 1500,
|
cashbox: 1500,
|
||||||
stacker: 60,
|
recycler: 60,
|
||||||
cassette: 500
|
cassette: 500
|
||||||
},
|
},
|
||||||
tejo: {
|
tejo: {
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,7 @@ const staticConfig = ({ currentConfigVersion, deviceId, deviceName, pq, settings
|
||||||
operatorInfo,
|
operatorInfo,
|
||||||
receiptInfo,
|
receiptInfo,
|
||||||
twoWayMode,
|
twoWayMode,
|
||||||
{ numberOfCassettes, numberOfStackers },
|
{ numberOfCassettes, numberOfRecyclers },
|
||||||
]) =>
|
]) =>
|
||||||
(currentConfigVersion && currentConfigVersion >= staticConf.configVersion) ?
|
(currentConfigVersion && currentConfigVersion >= staticConf.configVersion) ?
|
||||||
null :
|
null :
|
||||||
|
|
@ -142,7 +142,7 @@ const staticConfig = ({ currentConfigVersion, deviceId, deviceName, pq, settings
|
||||||
languages: localeInfo.languages,
|
languages: localeInfo.languages,
|
||||||
fiatCode: localeInfo.fiatCurrency
|
fiatCode: localeInfo.fiatCurrency
|
||||||
},
|
},
|
||||||
machineInfo: { deviceId, deviceName, numberOfCassettes, numberOfStackers },
|
machineInfo: { deviceId, deviceName, numberOfCassettes, numberOfRecyclers },
|
||||||
twoWayMode,
|
twoWayMode,
|
||||||
speedtestFiles,
|
speedtestFiles,
|
||||||
urlsToPing,
|
urlsToPing,
|
||||||
|
|
@ -171,24 +171,24 @@ const dynamicConfig = ({ deviceId, operatorId, pid, pq, settings, }) => {
|
||||||
)(cassettes) :
|
)(cassettes) :
|
||||||
null
|
null
|
||||||
|
|
||||||
const massageStackers = stackers =>
|
const massageRecyclers = recyclers =>
|
||||||
stackers ?
|
recyclers ?
|
||||||
_.flow(
|
_.flow(
|
||||||
stackers => _.set('physical', _.get('stackers', stackers), stackers),
|
recyclers => _.set('physical', _.get('recyclers', recyclers), recyclers),
|
||||||
stackers => _.set('virtual', _.get('virtualStackers', stackers), stackers),
|
recyclers => _.set('virtual', _.get('virtualRecyclers', recyclers), recyclers),
|
||||||
_.unset('stackers'),
|
_.unset('recyclers'),
|
||||||
_.unset('virtualStackers')
|
_.unset('virtualRecyclers')
|
||||||
)(stackers) :
|
)(recyclers) :
|
||||||
null
|
null
|
||||||
|
|
||||||
state.pids = _.update(operatorId, _.set(deviceId, { pid, ts: Date.now() }), state.pids)
|
state.pids = _.update(operatorId, _.set(deviceId, { pid, ts: Date.now() }), state.pids)
|
||||||
|
|
||||||
const res = _.flow(
|
const res = _.flow(
|
||||||
_.pick(['areThereAvailablePromoCodes', 'balances', 'cassettes', 'stackers', 'coins', 'rates']),
|
_.pick(['areThereAvailablePromoCodes', 'balances', 'cassettes', 'recyclers', 'coins', 'rates']),
|
||||||
|
|
||||||
_.update('cassettes', massageCassettes),
|
_.update('cassettes', massageCassettes),
|
||||||
|
|
||||||
_.update('stackers', massageStackers),
|
_.update('recyclers', massageRecyclers),
|
||||||
|
|
||||||
/* [{ cryptoCode, rates }, ...] => [[cryptoCode, rates], ...] */
|
/* [{ cryptoCode, rates }, ...] => [[cryptoCode, rates], ...] */
|
||||||
_.update('coins', _.map(({ cryptoCode, rates }) => [cryptoCode, rates])),
|
_.update('coins', _.map(({ cryptoCode, rates }) => [cryptoCode, rates])),
|
||||||
|
|
@ -201,10 +201,10 @@ const dynamicConfig = ({ deviceId, operatorId, pid, pq, settings, }) => {
|
||||||
|
|
||||||
/* Group the separate objects by cryptoCode */
|
/* Group the separate objects by cryptoCode */
|
||||||
/* { balances, coins, rates } => { cryptoCode: { balance, ask, bid, cashIn, cashOut }, ... } */
|
/* { balances, coins, rates } => { cryptoCode: { balance, ask, bid, cashIn, cashOut }, ... } */
|
||||||
({ areThereAvailablePromoCodes, balances, cassettes, stackers, coins, rates }) => ({
|
({ areThereAvailablePromoCodes, balances, cassettes, recyclers, coins, rates }) => ({
|
||||||
areThereAvailablePromoCodes,
|
areThereAvailablePromoCodes,
|
||||||
cassettes,
|
cassettes,
|
||||||
stackers,
|
recyclers,
|
||||||
coins: _.flow(
|
coins: _.flow(
|
||||||
_.reduce(
|
_.reduce(
|
||||||
(ret, [cryptoCode, obj]) => _.update(cryptoCode, _.assign(obj), ret),
|
(ret, [cryptoCode, obj]) => _.update(cryptoCode, _.assign(obj), ret),
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ type MachineInfo {
|
||||||
deviceId: String!
|
deviceId: String!
|
||||||
deviceName: String
|
deviceName: String
|
||||||
numberOfCassettes: Int
|
numberOfCassettes: Int
|
||||||
numberOfStackers: Int
|
numberOfRecyclers: Int
|
||||||
}
|
}
|
||||||
|
|
||||||
type ReceiptInfo {
|
type ReceiptInfo {
|
||||||
|
|
@ -173,7 +173,7 @@ type PhysicalCassette {
|
||||||
count: Int!
|
count: Int!
|
||||||
}
|
}
|
||||||
|
|
||||||
type PhysicalStacker {
|
type PhysicalRecycler {
|
||||||
name: String!
|
name: String!
|
||||||
number: Int!
|
number: Int!
|
||||||
denomination: Int!
|
denomination: Int!
|
||||||
|
|
@ -185,15 +185,15 @@ type Cassettes {
|
||||||
virtual: [Int!]!
|
virtual: [Int!]!
|
||||||
}
|
}
|
||||||
|
|
||||||
type Stackers {
|
type Recyclers {
|
||||||
physical: [PhysicalStacker!]!
|
physical: [PhysicalRecycler!]!
|
||||||
virtual: [Int!]!
|
virtual: [Int!]!
|
||||||
}
|
}
|
||||||
|
|
||||||
type DynamicConfig {
|
type DynamicConfig {
|
||||||
areThereAvailablePromoCodes: Boolean!
|
areThereAvailablePromoCodes: Boolean!
|
||||||
cassettes: Cassettes
|
cassettes: Cassettes
|
||||||
stackers: Stackers
|
recyclers: Recyclers
|
||||||
coins: [DynamicCoinValues!]!
|
coins: [DynamicCoinValues!]!
|
||||||
reboot: Boolean!
|
reboot: Boolean!
|
||||||
shutdown: Boolean!
|
shutdown: Boolean!
|
||||||
|
|
|
||||||
|
|
@ -42,15 +42,15 @@ function toMachineObject (r) {
|
||||||
cassette2: r.cassette2,
|
cassette2: r.cassette2,
|
||||||
cassette3: r.cassette3,
|
cassette3: r.cassette3,
|
||||||
cassette4: r.cassette4,
|
cassette4: r.cassette4,
|
||||||
stacker1f: r.stacker1f,
|
recycler1: r.recycler1,
|
||||||
stacker1r: r.stacker1r,
|
recycler2: r.recycler2,
|
||||||
stacker2f: r.stacker2f,
|
recycler3: r.recycler3,
|
||||||
stacker2r: r.stacker2r,
|
recycler4: r.recycler4,
|
||||||
stacker3f: r.stacker3f,
|
recycler5: r.recycler5,
|
||||||
stacker3r: r.stacker3r
|
recycler6: r.recycler6
|
||||||
},
|
},
|
||||||
numberOfCassettes: r.number_of_cassettes,
|
numberOfCassettes: r.number_of_cassettes,
|
||||||
numberOfStackers: r.number_of_stackers,
|
numberOfRecyclers: r.number_of_recyclers,
|
||||||
version: r.version,
|
version: r.version,
|
||||||
model: r.model,
|
model: r.model,
|
||||||
pairedAt: new Date(r.created),
|
pairedAt: new Date(r.created),
|
||||||
|
|
@ -172,19 +172,19 @@ function renameMachine (rec) {
|
||||||
|
|
||||||
function resetCashOutBills (rec) {
|
function resetCashOutBills (rec) {
|
||||||
const detailB = notifierUtils.buildDetail({ deviceId: rec.deviceId })
|
const detailB = notifierUtils.buildDetail({ deviceId: rec.deviceId })
|
||||||
const { cassette1, cassette2, cassette3, cassette4, stacker1f, stacker1r, stacker2f, stacker2r, stacker3f, stacker3r } = rec.cashUnits
|
const { cassette1, cassette2, cassette3, cassette4, recycler1, recycler2, recycler3, recycler4, recycler5, recycler6 } = rec.cashUnits
|
||||||
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;`
|
const sql = `UPDATE devices SET cassette1=$1, cassette2=$2, cassette3=$3, cassette4=$4, recycler1=$5, recycler2=$6, recycler3=$7, recycler4=$8, recycler5=$9, recycler6=$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'))
|
return db.none(sql, [cassette1, cassette2, cassette3, cassette4, recycler1, recycler2, recycler3, recycler4, recycler5, recycler6, rec.deviceId]).then(() => notifierQueries.invalidateNotification(detailB, 'fiatBalance'))
|
||||||
}
|
}
|
||||||
|
|
||||||
function setCassetteBills (rec) {
|
function setCassetteBills (rec) {
|
||||||
const { cashbox, cassette1, cassette2, cassette3, cassette4, stacker1f, stacker1r, stacker2f, stacker2r, stacker3f, stacker3r } = rec.cashUnits
|
const { cashbox, cassette1, cassette2, cassette3, cassette4, recycler1, recycler2, recycler3, recycler4, recycler5, recycler6 } = rec.cashUnits
|
||||||
return getMachine(rec.deviceId)
|
return getMachine(rec.deviceId)
|
||||||
.then(machine => {
|
.then(machine => {
|
||||||
const oldCashboxCount = machine?.cashUnits?.cashbox
|
const oldCashboxCount = machine?.cashUnits?.cashbox
|
||||||
if (_.isNil(oldCashboxCount) || cashbox === oldCashboxCount) {
|
if (_.isNil(oldCashboxCount) || cashbox === oldCashboxCount) {
|
||||||
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'
|
const sql = 'UPDATE devices SET cassette1=$1, cassette2=$2, cassette3=$3, cassette4=$4, recycler1=$5, recycler2=$6, recycler3=$7, recycler4=$8, recycler5=$9, recycler6=$10 WHERE device_id=$11'
|
||||||
return db.none(sql, [cassette1, cassette2, cassette3, cassette4, stacker1f, stacker1r, stacker2f, stacker2r, stacker3f, stacker3r, rec.deviceId])
|
return db.none(sql, [cassette1, cassette2, cassette3, cassette4, recycler1, recycler2, recycler3, recycler4, recycler5, recycler6, rec.deviceId])
|
||||||
}
|
}
|
||||||
|
|
||||||
return batching.updateMachineWithBatch({ ...rec, oldCashboxValue: oldCashboxCount })
|
return batching.updateMachineWithBatch({ ...rec, oldCashboxValue: oldCashboxCount })
|
||||||
|
|
@ -199,7 +199,7 @@ function emptyMachineUnits ({ deviceId, newUnits, fiatCode }) {
|
||||||
(acc, value) => ({
|
(acc, value) => ({
|
||||||
...acc,
|
...acc,
|
||||||
[value]: {
|
[value]: {
|
||||||
operationName: `cash-${_.replace(/(cassette|stacker)/g, '$1-')(value)}-empty`,
|
operationName: `cash-${_.replace(/(cassette|recycler)/g, '$1-')(value)}-empty`,
|
||||||
delta: newUnits[value] - machine.cashUnits[value],
|
delta: newUnits[value] - machine.cashUnits[value],
|
||||||
denomination: value !== 'cashbox' ? cashoutSettings[value] : null
|
denomination: value !== 'cashbox' ? cashoutSettings[value] : null
|
||||||
}
|
}
|
||||||
|
|
@ -224,7 +224,7 @@ function emptyMachineUnits ({ deviceId, newUnits, fiatCode }) {
|
||||||
fiat_code: fiatCode,
|
fiat_code: fiatCode,
|
||||||
device_id: deviceId
|
device_id: deviceId
|
||||||
// TODO: Uncomment this if we decide to keep track of bills across multiple operations. For now, we'll just create the emptying operations for each unit affected, but not relate these events with individual bills and just use the field for the cashbox batch event
|
// TODO: Uncomment this if we decide to keep track of bills across multiple operations. For now, we'll just create the emptying operations for each unit affected, but not relate these events with individual bills and just use the field for the cashbox batch event
|
||||||
// cash_unit_operation_id: _.find(it => it.operation_type === `cash-${_.replace(/(cassette|stacker)/g, '$1-')(value)}-empty`, operationsToCreate).id
|
// cash_unit_operation_id: _.find(it => it.operation_type === `cash-${_.replace(/(cassette|recycler)/g, '$1-')(value)}-empty`, operationsToCreate).id
|
||||||
}), Math.abs(unit.delta)))
|
}), Math.abs(unit.delta)))
|
||||||
},
|
},
|
||||||
[],
|
[],
|
||||||
|
|
@ -241,17 +241,17 @@ function emptyMachineUnits ({ deviceId, newUnits, fiatCode }) {
|
||||||
const q1= t.none(pgp.helpers.insert(operationsToCreate, q1Cols, 'cash_unit_operation'))
|
const q1= t.none(pgp.helpers.insert(operationsToCreate, q1Cols, 'cash_unit_operation'))
|
||||||
const q2Cols = ['id', 'fiat', 'fiat_code', 'device_id']
|
const q2Cols = ['id', 'fiat', 'fiat_code', 'device_id']
|
||||||
const q2 = t.none(pgp.helpers.insert(billArr, q2Cols, 'empty_unit_bills'))
|
const q2 = t.none(pgp.helpers.insert(billArr, q2Cols, 'empty_unit_bills'))
|
||||||
const q3 = t.none(`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`, [
|
const q3 = t.none(`UPDATE devices SET cassette1=$1, cassette2=$2, cassette3=$3, cassette4=$4, recycler1=$5, recycler2=$6, recycler3=$7, recycler4=$8, recycler5=$9, recycler6=$10 WHERE device_id=$11`, [
|
||||||
_.defaultTo(machine.cashUnits.cassette1, newUnits.cassette1),
|
_.defaultTo(machine.cashUnits.cassette1, newUnits.cassette1),
|
||||||
_.defaultTo(machine.cashUnits.cassette2, newUnits.cassette2),
|
_.defaultTo(machine.cashUnits.cassette2, newUnits.cassette2),
|
||||||
_.defaultTo(machine.cashUnits.cassette3, newUnits.cassette3),
|
_.defaultTo(machine.cashUnits.cassette3, newUnits.cassette3),
|
||||||
_.defaultTo(machine.cashUnits.cassette4, newUnits.cassette4),
|
_.defaultTo(machine.cashUnits.cassette4, newUnits.cassette4),
|
||||||
_.defaultTo(machine.cashUnits.stacker1f, newUnits.stacker1f),
|
_.defaultTo(machine.cashUnits.recycler1, newUnits.recycler1),
|
||||||
_.defaultTo(machine.cashUnits.stacker1r, newUnits.stacker1r),
|
_.defaultTo(machine.cashUnits.recycler2, newUnits.recycler2),
|
||||||
_.defaultTo(machine.cashUnits.stacker2f, newUnits.stacker2f),
|
_.defaultTo(machine.cashUnits.recycler3, newUnits.recycler3),
|
||||||
_.defaultTo(machine.cashUnits.stacker2r, newUnits.stacker2r),
|
_.defaultTo(machine.cashUnits.recycler4, newUnits.recycler4),
|
||||||
_.defaultTo(machine.cashUnits.stacker3f, newUnits.stacker3f),
|
_.defaultTo(machine.cashUnits.recycler5, newUnits.recycler5),
|
||||||
_.defaultTo(machine.cashUnits.stacker3r, newUnits.stacker3r),
|
_.defaultTo(machine.cashUnits.recycler6, newUnits.recycler6),
|
||||||
deviceId
|
deviceId
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
@ -267,7 +267,7 @@ function refillMachineUnits ({ deviceId, newUnits }) {
|
||||||
(acc, value) => ({
|
(acc, value) => ({
|
||||||
...acc,
|
...acc,
|
||||||
[value]: {
|
[value]: {
|
||||||
operationName: `cash-${_.replace(/(stacker)/g, '$1-')(value)}-refill`,
|
operationName: `cash-${_.replace(/(recycler)/g, '$1-')(value)}-refill`,
|
||||||
delta: newUnits[value] - machine.cashUnits[value]
|
delta: newUnits[value] - machine.cashUnits[value]
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
@ -290,17 +290,17 @@ function refillMachineUnits ({ deviceId, newUnits }) {
|
||||||
return db.tx(t => {
|
return db.tx(t => {
|
||||||
const q1Cols = ['id', 'device_id', 'operation_type']
|
const q1Cols = ['id', 'device_id', 'operation_type']
|
||||||
const q1= t.none(pgp.helpers.insert(operationsToCreate, q1Cols, 'cash_unit_operation'))
|
const q1= t.none(pgp.helpers.insert(operationsToCreate, q1Cols, 'cash_unit_operation'))
|
||||||
const q2 = t.none(`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`, [
|
const q2 = t.none(`UPDATE devices SET cassette1=$1, cassette2=$2, cassette3=$3, cassette4=$4, recycler1=$5, recycler2=$6, recycler3=$7, recycler4=$8, recycler5=$9, recycler6=$10 WHERE device_id=$11`, [
|
||||||
_.defaultTo(machine.cashUnits.cassette1, newUnits.cassette1),
|
_.defaultTo(machine.cashUnits.cassette1, newUnits.cassette1),
|
||||||
_.defaultTo(machine.cashUnits.cassette2, newUnits.cassette2),
|
_.defaultTo(machine.cashUnits.cassette2, newUnits.cassette2),
|
||||||
_.defaultTo(machine.cashUnits.cassette3, newUnits.cassette3),
|
_.defaultTo(machine.cashUnits.cassette3, newUnits.cassette3),
|
||||||
_.defaultTo(machine.cashUnits.cassette4, newUnits.cassette4),
|
_.defaultTo(machine.cashUnits.cassette4, newUnits.cassette4),
|
||||||
_.defaultTo(machine.cashUnits.stacker1f, newUnits.stacker1f),
|
_.defaultTo(machine.cashUnits.recycler1, newUnits.recycler1),
|
||||||
_.defaultTo(machine.cashUnits.stacker1r, newUnits.stacker1r),
|
_.defaultTo(machine.cashUnits.recycler2, newUnits.recycler2),
|
||||||
_.defaultTo(machine.cashUnits.stacker2f, newUnits.stacker2f),
|
_.defaultTo(machine.cashUnits.recycler3, newUnits.recycler3),
|
||||||
_.defaultTo(machine.cashUnits.stacker2r, newUnits.stacker2r),
|
_.defaultTo(machine.cashUnits.recycler4, newUnits.recycler4),
|
||||||
_.defaultTo(machine.cashUnits.stacker3f, newUnits.stacker3f),
|
_.defaultTo(machine.cashUnits.recycler5, newUnits.recycler5),
|
||||||
_.defaultTo(machine.cashUnits.stacker3r, newUnits.stacker3r),
|
_.defaultTo(machine.cashUnits.recycler6, newUnits.recycler6),
|
||||||
deviceId
|
deviceId
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ function machineAction (type, value) {
|
||||||
state.emptyUnit[operatorId] = { [deviceId]: pid }
|
state.emptyUnit[operatorId] = { [deviceId]: pid }
|
||||||
break
|
break
|
||||||
case 'refillUnit':
|
case 'refillUnit':
|
||||||
logger.debug(`Refilling stackers from machine '${deviceId}' from operator ${operatorId}`)
|
logger.debug(`Refilling recyclers from machine '${deviceId}' from operator ${operatorId}`)
|
||||||
state.refillUnit[operatorId] = { [deviceId]: pid }
|
state.refillUnit[operatorId] = { [deviceId]: pid }
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ const typeDef = gql`
|
||||||
model: String
|
model: String
|
||||||
cashUnits: CashUnits
|
cashUnits: CashUnits
|
||||||
numberOfCassettes: Int
|
numberOfCassettes: Int
|
||||||
numberOfStackers: Int
|
numberOfRecyclers: Int
|
||||||
statuses: [MachineStatus]
|
statuses: [MachineStatus]
|
||||||
latestEvent: MachineEvent
|
latestEvent: MachineEvent
|
||||||
downloadSpeed: String
|
downloadSpeed: String
|
||||||
|
|
@ -30,12 +30,12 @@ const typeDef = gql`
|
||||||
cassette2: Int
|
cassette2: Int
|
||||||
cassette3: Int
|
cassette3: Int
|
||||||
cassette4: Int
|
cassette4: Int
|
||||||
stacker1f: Int
|
recycler1: Int
|
||||||
stacker1r: Int
|
recycler2: Int
|
||||||
stacker2f: Int
|
recycler3: Int
|
||||||
stacker2r: Int
|
recycler4: Int
|
||||||
stacker3f: Int
|
recycler5: Int
|
||||||
stacker3r: Int
|
recycler6: Int
|
||||||
}
|
}
|
||||||
|
|
||||||
input CashUnitsInput {
|
input CashUnitsInput {
|
||||||
|
|
@ -44,12 +44,12 @@ const typeDef = gql`
|
||||||
cassette2: Int
|
cassette2: Int
|
||||||
cassette3: Int
|
cassette3: Int
|
||||||
cassette4: Int
|
cassette4: Int
|
||||||
stacker1f: Int
|
recycler1: Int
|
||||||
stacker1r: Int
|
recycler2: Int
|
||||||
stacker2f: Int
|
recycler3: Int
|
||||||
stacker2r: Int
|
recycler4: Int
|
||||||
stacker3f: Int
|
recycler5: Int
|
||||||
stacker3r: Int
|
recycler6: Int
|
||||||
}
|
}
|
||||||
|
|
||||||
type UnpairedMachine {
|
type UnpairedMachine {
|
||||||
|
|
|
||||||
|
|
@ -154,9 +154,9 @@ function advancedBatch (data) {
|
||||||
'dispense', 'notified', 'redeem', 'phone', 'error',
|
'dispense', 'notified', 'redeem', 'phone', 'error',
|
||||||
'created', 'confirmedAt', 'hdIndex', 'swept', 'timedout',
|
'created', 'confirmedAt', 'hdIndex', 'swept', 'timedout',
|
||||||
'dispenseConfirmed', 'provisioned1', 'provisioned2', 'provisioned3', 'provisioned4',
|
'dispenseConfirmed', 'provisioned1', 'provisioned2', 'provisioned3', 'provisioned4',
|
||||||
'provisioned1f', 'provisioned1r', 'provisioned2f', 'provisioned2r', 'provisioned3f', 'provisioned3r',
|
'provisionedRecycler1', 'provisionedRecycler2', 'provisionedRecycler3', 'provisionedRecycler4', 'provisionedRecycler5', 'provisionedRecycler6',
|
||||||
'denomination1', 'denomination2', 'denomination3', 'denomination4',
|
'denomination1', 'denomination2', 'denomination3', 'denomination4',
|
||||||
'denomination1f', 'denomination1r', 'denomination2f', 'denomination2r', 'denomination3f', 'denomination3r',
|
'denominationRecycler1', 'denominationRecycler2', 'denominationRecycler3', 'denominationRecycler4', 'denominationRecycler5', 'denominationRecycler6',
|
||||||
'errorCode', 'customerId', 'txVersion', 'publishedAt', 'termsAccepted', 'layer2Address',
|
'errorCode', 'customerId', 'txVersion', 'publishedAt', 'termsAccepted', 'layer2Address',
|
||||||
'commissionPercentage', 'rawTickerPrice', 'receivedCryptoAtoms',
|
'commissionPercentage', 'rawTickerPrice', 'receivedCryptoAtoms',
|
||||||
'discount', 'txHash', 'customerPhone', 'customerIdCardDataNumber',
|
'discount', 'txHash', 'customerPhone', 'customerIdCardDataNumber',
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ const CA_PATH = process.env.CA_PATH
|
||||||
// A machine on an older version (no multicassette code) could be paired with a server with multicassette code.
|
// A machine on an older version (no multicassette code) could be paired with a server with multicassette code.
|
||||||
// This makes sure that the server stores a default value
|
// This makes sure that the server stores a default value
|
||||||
const DEFAULT_NUMBER_OF_CASSETTES = 2
|
const DEFAULT_NUMBER_OF_CASSETTES = 2
|
||||||
const DEFAULT_NUMBER_OF_STACKERS = 0
|
const DEFAULT_NUMBER_OF_RECYCLERS = 0
|
||||||
|
|
||||||
function pullToken (token) {
|
function pullToken (token) {
|
||||||
const sql = `delete from pairing_tokens
|
const sql = `delete from pairing_tokens
|
||||||
|
|
@ -37,16 +37,16 @@ function unpair (deviceId) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function pair (token, deviceId, machineModel, numOfCassettes = DEFAULT_NUMBER_OF_CASSETTES, numOfStackers = DEFAULT_NUMBER_OF_STACKERS) {
|
function pair (token, deviceId, machineModel, numOfCassettes = DEFAULT_NUMBER_OF_CASSETTES, numOfRecyclers = DEFAULT_NUMBER_OF_RECYCLERS) {
|
||||||
return pullToken(token)
|
return pullToken(token)
|
||||||
.then(r => {
|
.then(r => {
|
||||||
if (r.expired) return false
|
if (r.expired) return false
|
||||||
|
|
||||||
const insertSql = `insert into devices (device_id, name, number_of_cassettes, number_of_stackers) values ($1, $2, $3, $4)
|
const insertSql = `insert into devices (device_id, name, number_of_cassettes, number_of_recyclers) values ($1, $2, $3, $4)
|
||||||
on conflict (device_id)
|
on conflict (device_id)
|
||||||
do update set paired=TRUE, display=TRUE`
|
do update set paired=TRUE, display=TRUE`
|
||||||
|
|
||||||
return db.none(insertSql, [deviceId, r.name, numOfCassettes, numOfStackers])
|
return db.none(insertSql, [deviceId, r.name, numOfCassettes, numOfRecyclers])
|
||||||
.then(() => true)
|
.then(() => true)
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
|
|
|
||||||
145
lib/plugins.js
145
lib/plugins.js
|
|
@ -147,42 +147,42 @@ function plugins (settings, deviceId) {
|
||||||
return computedCassettes
|
return computedCassettes
|
||||||
}
|
}
|
||||||
|
|
||||||
function computeAvailableStackers (stackers, redeemableTxs) {
|
function computeAvailableRecyclers (recyclers, redeemableTxs) {
|
||||||
if (_.isEmpty(redeemableTxs)) return stackers
|
if (_.isEmpty(redeemableTxs)) return recyclers
|
||||||
|
|
||||||
const sumTxs = (sum, tx) => {
|
const sumTxs = (sum, tx) => {
|
||||||
// cash-out-helper sends 0 as fallback value, need to filter it out as there are no '0' denominations
|
// cash-out-helper sends 0 as fallback value, need to filter it out as there are no '0' denominations
|
||||||
const bills = _.filter(it => _.includes('stacker', it.name) && it.denomination > 0, tx.bills)
|
const bills = _.filter(it => _.includes('recycler', it.name) && it.denomination > 0, tx.bills)
|
||||||
const sameDenominations = a => a[0]?.denomination === a[1]?.denomination
|
const sameDenominations = a => a[0]?.denomination === a[1]?.denomination
|
||||||
|
|
||||||
const doDenominationsMatch = _.every(sameDenominations, _.zip(stackers, bills))
|
const doDenominationsMatch = _.every(sameDenominations, _.zip(recyclers, bills))
|
||||||
|
|
||||||
if (!doDenominationsMatch) {
|
if (!doDenominationsMatch) {
|
||||||
throw new Error('Denominations don\'t add up, stackers were changed.')
|
throw new Error('Denominations don\'t add up, recyclers were changed.')
|
||||||
}
|
}
|
||||||
|
|
||||||
return _.map(r => r[0] + r[1].provisioned, _.zip(sum, tx.bills))
|
return _.map(r => r[0] + r[1].provisioned, _.zip(sum, tx.bills))
|
||||||
}
|
}
|
||||||
|
|
||||||
const provisioned = _.reduce(sumTxs, _.times(_.constant(0), _.size(stackers)), redeemableTxs)
|
const provisioned = _.reduce(sumTxs, _.times(_.constant(0), _.size(recyclers)), redeemableTxs)
|
||||||
const zipped = _.zip(_.map('count', stackers), provisioned)
|
const zipped = _.zip(_.map('count', recyclers), provisioned)
|
||||||
const counts = _.map(r => r[0] - r[1], zipped)
|
const counts = _.map(r => r[0] - r[1], zipped)
|
||||||
|
|
||||||
if (_.some(_.lt(_, 0), counts)) {
|
if (_.some(_.lt(_, 0), counts)) {
|
||||||
throw new Error('Negative note count: %j', counts)
|
throw new Error('Negative note count: %j', counts)
|
||||||
}
|
}
|
||||||
|
|
||||||
const computedStackers = []
|
const computedRecyclers = []
|
||||||
_.forEach(it => {
|
_.forEach(it => {
|
||||||
computedStackers.push({
|
computedRecyclers.push({
|
||||||
number: stackers[it].number,
|
number: recyclers[it].number,
|
||||||
name: stackers[it].name,
|
name: recyclers[it].name,
|
||||||
denomination: stackers[it].denomination,
|
denomination: recyclers[it].denomination,
|
||||||
count: counts[it]
|
count: counts[it]
|
||||||
})
|
})
|
||||||
}, _.times(_.identity(), _.size(stackers)))
|
}, _.times(_.identity(), _.size(recyclers)))
|
||||||
|
|
||||||
return computedStackers
|
return computedRecyclers
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildAvailableCassettes (excludeTxId) {
|
function buildAvailableCassettes (excludeTxId) {
|
||||||
|
|
@ -231,62 +231,57 @@ function plugins (settings, deviceId) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildAvailableStackers (excludeTxId) {
|
function buildAvailableRecyclers (excludeTxId) {
|
||||||
const cashOutConfig = configManager.getCashOut(deviceId, settings.config)
|
const cashOutConfig = configManager.getCashOut(deviceId, settings.config)
|
||||||
|
|
||||||
if (!cashOutConfig.active) return Promise.resolve()
|
if (!cashOutConfig.active) return Promise.resolve()
|
||||||
|
|
||||||
return Promise.all([dbm.stackerCounts(deviceId), cashOutHelper.redeemableTxs(deviceId, excludeTxId)])
|
return Promise.all([dbm.recyclerCounts(deviceId), cashOutHelper.redeemableTxs(deviceId, excludeTxId)])
|
||||||
.then(([_stackers, _redeemableTxs]) => {
|
.then(([_recyclers, _redeemableTxs]) => {
|
||||||
const redeemableTxs = _.reject(_.matchesProperty('id', excludeTxId), _redeemableTxs)
|
const redeemableTxs = _.reject(_.matchesProperty('id', excludeTxId), _redeemableTxs)
|
||||||
|
|
||||||
const denominations = []
|
const denominations = []
|
||||||
_.forEach(it => {
|
|
||||||
denominations.push([cashOutConfig[`stacker${it + 1}f`], cashOutConfig[`stacker${it + 1}r`]])
|
|
||||||
}, _.times(_.identity(), _stackers.numberOfStackers))
|
|
||||||
|
|
||||||
const virtualStackers = denominations.length ? [Math.max(..._.flatten(denominations)) * 2] : []
|
|
||||||
|
|
||||||
const counts = _stackers.counts
|
_.forEach(it => {
|
||||||
|
denominations.push(cashOutConfig[`recycler${it + 1}`])
|
||||||
|
}, _.times(_.identity(), _recyclers.numberOfRecyclers))
|
||||||
|
|
||||||
|
const virtualRecyclers = denominations.length ? [Math.max(..._.flatten(denominations)) * 2] : []
|
||||||
|
|
||||||
|
const counts = _recyclers.counts
|
||||||
|
|
||||||
if (counts.length !== denominations.length) {
|
if (counts.length !== denominations.length) {
|
||||||
throw new Error('Denominations and respective counts do not match!')
|
throw new Error('Denominations and respective counts do not match!')
|
||||||
}
|
}
|
||||||
|
|
||||||
const stackers = []
|
const recyclers = []
|
||||||
_.forEach(it => {
|
_.forEach(it => {
|
||||||
stackers.push({
|
recyclers.push({
|
||||||
number: 1 + it * 2,
|
number: it + 1,
|
||||||
name: `stacker${it + 1}f`,
|
name: `recycler${it + 1}`,
|
||||||
denomination: parseInt(denominations[it][0], 10),
|
denomination: parseInt(denominations[it], 10),
|
||||||
count: parseInt(counts[it][0], 10)
|
count: parseInt(counts[it], 10)
|
||||||
})
|
})
|
||||||
stackers.push({
|
}, _.times(_.identity(), _recyclers.numberOfRecyclers))
|
||||||
number: 2 + it * 2,
|
|
||||||
name: `stacker${it + 1}r`,
|
|
||||||
denomination: parseInt(denominations[it][1], 10),
|
|
||||||
count: parseInt(counts[it][1], 10)
|
|
||||||
})
|
|
||||||
}, _.times(_.identity(), _stackers.numberOfStackers))
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return {
|
return {
|
||||||
stackers: computeAvailableStackers(stackers, redeemableTxs),
|
recyclers: computeAvailableRecyclers(recyclers, redeemableTxs),
|
||||||
virtualStackers
|
virtualRecyclers
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error(err)
|
logger.error(err)
|
||||||
return {
|
return {
|
||||||
stackers,
|
recyclers,
|
||||||
virtualStackers
|
virtualRecyclers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildAvailableUnits (excludeTxId) {
|
function buildAvailableUnits (excludeTxId) {
|
||||||
return Promise.all([buildAvailableCassettes(excludeTxId), buildAvailableStackers(excludeTxId)])
|
return Promise.all([buildAvailableCassettes(excludeTxId), buildAvailableRecyclers(excludeTxId)])
|
||||||
.then(([cassettes, stackers]) => ({ cassettes: cassettes.cassettes, stackers: stackers.stackers }))
|
.then(([cassettes, recyclers]) => ({ cassettes: cassettes.cassettes, recyclers: recyclers.recyclers }))
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchCurrentConfigVersion () {
|
function fetchCurrentConfigVersion () {
|
||||||
|
|
@ -336,7 +331,7 @@ function plugins (settings, deviceId) {
|
||||||
|
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
buildAvailableCassettes(),
|
buildAvailableCassettes(),
|
||||||
buildAvailableStackers(),
|
buildAvailableRecyclers(),
|
||||||
fetchCurrentConfigVersion(),
|
fetchCurrentConfigVersion(),
|
||||||
millisecondsToMinutes(getTimezoneOffset(localeConfig.timezone)),
|
millisecondsToMinutes(getTimezoneOffset(localeConfig.timezone)),
|
||||||
loyalty.getNumberOfAvailablePromoCodes(),
|
loyalty.getNumberOfAvailablePromoCodes(),
|
||||||
|
|
@ -347,7 +342,7 @@ function plugins (settings, deviceId) {
|
||||||
])
|
])
|
||||||
.then(([
|
.then(([
|
||||||
cassettes,
|
cassettes,
|
||||||
stackers,
|
recyclers,
|
||||||
configVersion,
|
configVersion,
|
||||||
timezone,
|
timezone,
|
||||||
numberOfAvailablePromoCodes,
|
numberOfAvailablePromoCodes,
|
||||||
|
|
@ -371,7 +366,7 @@ function plugins (settings, deviceId) {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
cassettes,
|
cassettes,
|
||||||
stackers,
|
recyclers: recyclers,
|
||||||
rates: buildRates(tickers),
|
rates: buildRates(tickers),
|
||||||
balances: buildBalances(balances),
|
balances: buildBalances(balances),
|
||||||
coins,
|
coins,
|
||||||
|
|
@ -744,12 +739,12 @@ function plugins (settings, deviceId) {
|
||||||
const denomination2 = cashOutConfig.cassette2
|
const denomination2 = cashOutConfig.cassette2
|
||||||
const denomination3 = cashOutConfig.cassette3
|
const denomination3 = cashOutConfig.cassette3
|
||||||
const denomination4 = cashOutConfig.cassette4
|
const denomination4 = cashOutConfig.cassette4
|
||||||
const denomination1f = cashOutConfig.stacker1f
|
const denominationRecycler1 = cashOutConfig.recycler1
|
||||||
const denomination1r = cashOutConfig.stacker1r
|
const denominationRecycler2 = cashOutConfig.recycler2
|
||||||
const denomination2f = cashOutConfig.stacker2f
|
const denominationRecycler3 = cashOutConfig.recycler3
|
||||||
const denomination2r = cashOutConfig.stacker2r
|
const denominationRecycler4 = cashOutConfig.recycler4
|
||||||
const denomination3f = cashOutConfig.stacker3f
|
const denominationRecycler5 = cashOutConfig.recycler5
|
||||||
const denomination3r = cashOutConfig.stacker3r
|
const denominationRecycler6 = cashOutConfig.recycler6
|
||||||
const cashOutEnabled = cashOutConfig.active
|
const cashOutEnabled = cashOutConfig.active
|
||||||
const isUnitLow = (have, max, limit) => cashOutEnabled && ((have / max) * 100) < limit
|
const isUnitLow = (have, max, limit) => cashOutEnabled && ((have / max) * 100) < limit
|
||||||
// const isUnitHigh = (have, max, limit) => cashOutEnabled && ((have / max) * 100) > limit
|
// const isUnitHigh = (have, max, limit) => cashOutEnabled && ((have / max) * 100) > limit
|
||||||
|
|
@ -817,74 +812,74 @@ function plugins (settings, deviceId) {
|
||||||
}
|
}
|
||||||
: null
|
: null
|
||||||
|
|
||||||
const stacker1fAlert = device.numberOfStackers >= 1 && isUnitLow(device.cashUnits.stacker1f, getCashUnitCapacity(device.model, 'stacker'), notifications.fillingPercentageStacker1f)
|
const recycler1Alert = device.numberOfRecyclers >= 1 && isUnitLow(device.cashUnits.recycler1, getCashUnitCapacity(device.model, 'recycler'), notifications.fillingPercentageRecycler1)
|
||||||
? {
|
? {
|
||||||
code: 'LOW_RECYCLER_STACKER',
|
code: 'LOW_RECYCLER_STACKER',
|
||||||
cassette: 4,
|
cassette: 4,
|
||||||
machineName,
|
machineName,
|
||||||
deviceId: device.deviceId,
|
deviceId: device.deviceId,
|
||||||
notes: device.cashUnits.stacker1f,
|
notes: device.cashUnits.recycler1,
|
||||||
denomination: denomination1f,
|
denomination: denominationRecycler1,
|
||||||
fiatCode
|
fiatCode
|
||||||
}
|
}
|
||||||
: null
|
: null
|
||||||
|
|
||||||
const stacker1rAlert = device.numberOfStackers >= 1 && isUnitLow(device.cashUnits.stacker1r, getCashUnitCapacity(device.model, 'stacker'), notifications.fillingPercentageStacker1r)
|
const recycler2Alert = device.numberOfRecyclers >= 2 && isUnitLow(device.cashUnits.recycler2, getCashUnitCapacity(device.model, 'recycler'), notifications.fillingPercentageRecycler2)
|
||||||
? {
|
? {
|
||||||
code: 'LOW_RECYCLER_STACKER',
|
code: 'LOW_RECYCLER_STACKER',
|
||||||
cassette: 4,
|
cassette: 4,
|
||||||
machineName,
|
machineName,
|
||||||
deviceId: device.deviceId,
|
deviceId: device.deviceId,
|
||||||
notes: device.cashUnits.stacker1r,
|
notes: device.cashUnits.recycler2,
|
||||||
denomination: denomination1r,
|
denomination: denominationRecycler2,
|
||||||
fiatCode
|
fiatCode
|
||||||
}
|
}
|
||||||
: null
|
: null
|
||||||
|
|
||||||
const stacker2fAlert = device.numberOfStackers >= 2 && isUnitLow(device.cashUnits.stacker2f, getCashUnitCapacity(device.model, 'stacker'), notifications.fillingPercentageStacker2f)
|
const recycler3Alert = device.numberOfRecyclers >= 3 && isUnitLow(device.cashUnits.recycler3, getCashUnitCapacity(device.model, 'recycler'), notifications.fillingPercentageRecycler3)
|
||||||
? {
|
? {
|
||||||
code: 'LOW_RECYCLER_STACKER',
|
code: 'LOW_RECYCLER_STACKER',
|
||||||
cassette: 4,
|
cassette: 4,
|
||||||
machineName,
|
machineName,
|
||||||
deviceId: device.deviceId,
|
deviceId: device.deviceId,
|
||||||
notes: device.cashUnits.stacker2f,
|
notes: device.cashUnits.recycler3,
|
||||||
denomination: denomination2f,
|
denomination: denominatinoRecycler3,
|
||||||
fiatCode
|
fiatCode
|
||||||
}
|
}
|
||||||
: null
|
: null
|
||||||
|
|
||||||
const stacker2rAlert = device.numberOfStackers >= 2 && isUnitLow(device.cashUnits.stacker2r, getCashUnitCapacity(device.model, 'stacker'), notifications.fillingPercentageStacker2r)
|
const recycler4Alert = device.numberOfRecyclers >= 4 && isUnitLow(device.cashUnits.recycler4, getCashUnitCapacity(device.model, 'recycler'), notifications.fillingPercentageRecycler4)
|
||||||
? {
|
? {
|
||||||
code: 'LOW_RECYCLER_STACKER',
|
code: 'LOW_RECYCLER_STACKER',
|
||||||
cassette: 4,
|
cassette: 4,
|
||||||
machineName,
|
machineName,
|
||||||
deviceId: device.deviceId,
|
deviceId: device.deviceId,
|
||||||
notes: device.cashUnits.stacker2r,
|
notes: device.cashUnits.recycler4,
|
||||||
denomination: denomination2r,
|
denomination: denominationRecycler4,
|
||||||
fiatCode
|
fiatCode
|
||||||
}
|
}
|
||||||
: null
|
: null
|
||||||
|
|
||||||
const stacker3fAlert = device.numberOfStackers >= 3 && isUnitLow(device.cashUnits.stacker3f, getCashUnitCapacity(device.model, 'stacker'), notifications.fillingPercentageStacker3f)
|
const recycler5Alert = device.numberOfRecyclers >= 5 && isUnitLow(device.cashUnits.recycler5, getCashUnitCapacity(device.model, 'recycler'), notifications.fillingPercentageRecycler5)
|
||||||
? {
|
? {
|
||||||
code: 'LOW_RECYCLER_STACKER',
|
code: 'LOW_RECYCLER_STACKER',
|
||||||
cassette: 4,
|
cassette: 4,
|
||||||
machineName,
|
machineName,
|
||||||
deviceId: device.deviceId,
|
deviceId: device.deviceId,
|
||||||
notes: device.cashUnits.stacker3f,
|
notes: device.cashUnits.recycler5,
|
||||||
denomination: denomination3f,
|
denomination: denominationRecycler5,
|
||||||
fiatCode
|
fiatCode
|
||||||
}
|
}
|
||||||
: null
|
: null
|
||||||
|
|
||||||
const stacker3rAlert = device.numberOfStackers >= 3 && isUnitLow(device.cashUnits.stacker3r, getCashUnitCapacity(device.model, 'stacker'), notifications.fillingPercentageStacker3r)
|
const recycler6Alert = device.numberOfRecyclers >= 6 && isUnitLow(device.cashUnits.recycler6, getCashUnitCapacity(device.model, 'recycler'), notifications.fillingPercentageRecycler6)
|
||||||
? {
|
? {
|
||||||
code: 'LOW_RECYCLER_STACKER',
|
code: 'LOW_RECYCLER_STACKER',
|
||||||
cassette: 4,
|
cassette: 4,
|
||||||
machineName,
|
machineName,
|
||||||
deviceId: device.deviceId,
|
deviceId: device.deviceId,
|
||||||
notes: device.cashUnits.stacker3r,
|
notes: device.cashUnits.recycler6,
|
||||||
denomination: denomination3r,
|
denomination: denominationRecycler6,
|
||||||
fiatCode
|
fiatCode
|
||||||
}
|
}
|
||||||
: null
|
: null
|
||||||
|
|
@ -895,12 +890,12 @@ function plugins (settings, deviceId) {
|
||||||
cassette2Alert,
|
cassette2Alert,
|
||||||
cassette3Alert,
|
cassette3Alert,
|
||||||
cassette4Alert,
|
cassette4Alert,
|
||||||
stacker1fAlert,
|
recycler1Alert,
|
||||||
stacker1rAlert,
|
recycler2Alert,
|
||||||
stacker2fAlert,
|
recycler3Alert,
|
||||||
stacker2rAlert,
|
recycler4Alert,
|
||||||
stacker3fAlert,
|
recycler5Alert,
|
||||||
stacker3rAlert
|
recycler6Alert
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,18 +40,18 @@ exports.cassetteCounts = function cassetteCounts (deviceId) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.stackerCounts = function stackerCounts (deviceId) {
|
exports.recyclerCounts = function recyclerCounts (deviceId) {
|
||||||
const sql = 'SELECT stacker1f, stacker1r, stacker2f, stacker2r, stacker3f, stacker3r, number_of_stackers FROM devices ' +
|
const sql = 'SELECT recycler1, recycler2, recycler3, recycler4, recycler5, recycler6, number_of_recyclers FROM devices ' +
|
||||||
'WHERE device_id=$1'
|
'WHERE device_id=$1'
|
||||||
|
|
||||||
return db.one(sql, [deviceId])
|
return db.one(sql, [deviceId])
|
||||||
.then(row => {
|
.then(row => {
|
||||||
const counts = []
|
const counts = []
|
||||||
_.forEach(it => {
|
_.forEach(it => {
|
||||||
counts.push([row[`stacker${it + 1}f`], row[`stacker${it + 1}r`]])
|
counts.push(row[`recycler${it + 1}`])
|
||||||
}, _.times(_.identity(), row.number_of_stackers))
|
}, _.times(_.identity(), row.number_of_recyclers))
|
||||||
|
|
||||||
return { numberOfStackers: row.number_of_stackers, counts }
|
return { numberOfRecyclers: row.number_of_recyclers, counts }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,9 @@ function pair (req, res, next) {
|
||||||
const deviceId = req.deviceId
|
const deviceId = req.deviceId
|
||||||
const model = req.query.model
|
const model = req.query.model
|
||||||
const numOfCassettes = req.query.numOfCassettes
|
const numOfCassettes = req.query.numOfCassettes
|
||||||
const numOfStackers = req.query.numOfStackers
|
const numOfRecyclers = req.query.numOfRecyclers
|
||||||
|
|
||||||
return pairing.pair(token, deviceId, model, numOfCassettes, numOfStackers)
|
return pairing.pair(token, deviceId, model, numOfCassettes, numOfRecyclers)
|
||||||
.then(isValid => {
|
.then(isValid => {
|
||||||
if (isValid) return res.json({ status: 'paired' })
|
if (isValid) return res.json({ status: 'paired' })
|
||||||
throw httpError('Pairing failed')
|
throw httpError('Pairing failed')
|
||||||
|
|
|
||||||
86
migrations/1696845395350-recycler-rename-settings.js
Normal file
86
migrations/1696845395350-recycler-rename-settings.js
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
const db = require('./db')
|
||||||
|
|
||||||
|
exports.up = function (next) {
|
||||||
|
var sql = [
|
||||||
|
`ALTER TABLE cash_out_actions
|
||||||
|
RENAME COLUMN provisioned_1f TO provisioned_recycler_1,
|
||||||
|
RENAME COLUMN provisioned_1r TO provisioned_recycler_2,
|
||||||
|
RENAME COLUMN provisioned_2f TO provisioned_recycler_3,
|
||||||
|
RENAME COLUMN provisioned_2r TO provisioned_recycler_4,
|
||||||
|
RENAME COLUMN provisioned_3f TO provisioned_recycler_5,
|
||||||
|
RENAME COLUMN provisioned_3r TO provisioned_recycler_6,
|
||||||
|
RENAME COLUMN dispensed_1f TO dispensed_recycler_1,
|
||||||
|
RENAME COLUMN dispensed_1r TO dispensed_recycler_2,
|
||||||
|
RENAME COLUMN dispensed_2f TO dispensed_recycler_3,
|
||||||
|
RENAME COLUMN dispensed_2r TO dispensed_recycler_4,
|
||||||
|
RENAME COLUMN dispensed_3f TO dispensed_recycler_5,
|
||||||
|
RENAME COLUMN dispensed_3r TO dispensed_recycler_6,
|
||||||
|
RENAME COLUMN rejected_1f TO rejected_recycler_1,
|
||||||
|
RENAME COLUMN rejected_1r TO rejected_recycler_2,
|
||||||
|
RENAME COLUMN rejected_2f TO rejected_recycler_3,
|
||||||
|
RENAME COLUMN rejected_2r TO rejected_recycler_4,
|
||||||
|
RENAME COLUMN rejected_3f TO rejected_recycler_5,
|
||||||
|
RENAME COLUMN rejected_3r TO rejected_recycler_6,
|
||||||
|
RENAME COLUMN denomination_1f TO denomination_recycler_1,
|
||||||
|
RENAME COLUMN denomination_1r TO denomination_recycler_2,
|
||||||
|
RENAME COLUMN denomination_2f TO denomination_recycler_3,
|
||||||
|
RENAME COLUMN denomination_2r TO denomination_recycler_4,
|
||||||
|
RENAME COLUMN denomination_3f TO denomination_recycler_5,
|
||||||
|
RENAME COLUMN denomination_3r TO denomination_recycler_6`,
|
||||||
|
`ALTER TABLE devices
|
||||||
|
RENAME COLUMN stacker1f TO recycler1,
|
||||||
|
RENAME COLUMN stacker1r TO recycler2,
|
||||||
|
RENAME COLUMN stacker2f TO recycler3,
|
||||||
|
RENAME COLUMN stacker2r TO recycler4,
|
||||||
|
RENAME COLUMN stacker3f TO recycler5,
|
||||||
|
RENAME COLUMN stacker3r TO recycler6,
|
||||||
|
RENAME COLUMN number_of_stackers TO number_of_recyclers`,
|
||||||
|
`ALTER TABLE cash_out_txs
|
||||||
|
RENAME COLUMN provisioned_1f TO provisioned_recycler_1,
|
||||||
|
RENAME COLUMN provisioned_1r TO provisioned_recycler_2,
|
||||||
|
RENAME COLUMN provisioned_2f TO provisioned_recycler_3,
|
||||||
|
RENAME COLUMN provisioned_2r TO provisioned_recycler_4,
|
||||||
|
RENAME COLUMN provisioned_3f TO provisioned_recycler_5,
|
||||||
|
RENAME COLUMN provisioned_3r TO provisioned_recycler_6,
|
||||||
|
RENAME COLUMN denomination_1f TO denomination_recycler_1,
|
||||||
|
RENAME COLUMN denomination_1r TO denomination_recycler_2,
|
||||||
|
RENAME COLUMN denomination_2f TO denomination_recycler_3,
|
||||||
|
RENAME COLUMN denomination_2r TO denomination_recycler_4,
|
||||||
|
RENAME COLUMN denomination_3f TO denomination_recycler_5,
|
||||||
|
RENAME COLUMN denomination_3r TO denomination_recycler_6`,
|
||||||
|
`ALTER TYPE cash_unit
|
||||||
|
RENAME VALUE 'stacker1f' TO 'recycler1',
|
||||||
|
RENAME VALUE 'stacker1r' TO 'recycler2',
|
||||||
|
RENAME VALUE 'stacker2f' TO 'recycler3',
|
||||||
|
RENAME VALUE 'stacker2r' TO 'recycler4',
|
||||||
|
RENAME VALUE 'stacker3f' TO 'recycler5',
|
||||||
|
RENAME VALUE 'stacker3r' TO 'recycler6',
|
||||||
|
`,
|
||||||
|
`ALTER TYPE cash_unit_operation_type
|
||||||
|
RENAME VALUE 'cash-stacker-1f-refill' TO 'cash-recycler-1-refill',
|
||||||
|
RENAME VALUE 'cash-stacker-1f-empty' TO 'cash-recycler-1-empty',
|
||||||
|
RENAME VALUE 'cash-stacker-1f-count-change' TO 'cash-recycler-1-count-change',
|
||||||
|
RENAME VALUE 'cash-stacker-1r-refill' TO 'cash-recycler-2-refill',
|
||||||
|
RENAME VALUE 'cash-stacker-1r-empty' TO 'cash-recycler-2-empty',
|
||||||
|
RENAME VALUE 'cash-stacker-1r-count-change' TO 'cash-recycler-2-count-change',
|
||||||
|
RENAME VALUE 'cash-stacker-2f-refill' TO 'cash-recycler-3-refill',
|
||||||
|
RENAME VALUE 'cash-stacker-2f-empty' TO 'cash-recycler-3-empty',
|
||||||
|
RENAME VALUE 'cash-stacker-2f-count-change' TO 'cash-recycler-3-count-change',
|
||||||
|
RENAME VALUE 'cash-stacker-2r-refill' TO 'cash-recycler-4-refill',
|
||||||
|
RENAME VALUE 'cash-stacker-2r-empty' TO 'cash-recycler-4-empty',
|
||||||
|
RENAME VALUE 'cash-stacker-2r-count-change' TO 'cash-recycler-4-count-change',
|
||||||
|
RENAME VALUE 'cash-stacker-3f-refill' TO 'cash-recycler-5-refill',
|
||||||
|
RENAME VALUE 'cash-stacker-3f-empty' TO 'cash-recycler-5-empty',
|
||||||
|
RENAME VALUE 'cash-stacker-3f-count-change' TO 'cash-recycler-5-count-change',
|
||||||
|
RENAME VALUE 'cash-stacker-3r-refill' TO 'cash-recycler-6-refill',
|
||||||
|
RENAME VALUE 'cash-stacker-3r-empty' TO 'cash-recycler-6-empty',
|
||||||
|
RENAME VALUE 'cash-stacker-3r-count-change' TO 'cash-recycler-6-count-change',
|
||||||
|
`
|
||||||
|
]
|
||||||
|
|
||||||
|
db.multi(sql, next)
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.down = function (next) {
|
||||||
|
next()
|
||||||
|
}
|
||||||
|
|
@ -215,7 +215,7 @@ const MachineActions = memo(({ machine, onActionSuccess }) => {
|
||||||
command: 'refillUnit',
|
command: 'refillUnit',
|
||||||
display: 'Refill',
|
display: 'Refill',
|
||||||
message:
|
message:
|
||||||
'Triggering this action will refill the stackers in this machine, by using bills present in its cassettes. This action may require manual operation of the cassettes and close attention to make sure that the denominations in the cassettes match the denominations in the stackers.'
|
'Triggering this action will refill the recyclers in this machine, by using bills present in its cassettes. This action may require manual operation of the cassettes and close attention to make sure that the denominations in the cassettes match the denominations in the recyclers.'
|
||||||
})
|
})
|
||||||
}}>
|
}}>
|
||||||
Refill Unit
|
Refill Unit
|
||||||
|
|
|
||||||
|
|
@ -46,15 +46,15 @@ const GET_INFO = gql`
|
||||||
cassette2
|
cassette2
|
||||||
cassette3
|
cassette3
|
||||||
cassette4
|
cassette4
|
||||||
stacker1f
|
recycler1
|
||||||
stacker1r
|
recycler2
|
||||||
stacker2f
|
recycler3
|
||||||
stacker2r
|
recycler4
|
||||||
stacker3f
|
recycler5
|
||||||
stacker3r
|
recycler6
|
||||||
}
|
}
|
||||||
numberOfCassettes
|
numberOfCassettes
|
||||||
numberOfStackers
|
numberOfRecyclers
|
||||||
}
|
}
|
||||||
config
|
config
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,8 @@ const MODAL_HEIGHT = 520
|
||||||
|
|
||||||
const Wizard = ({ machine, locale, onClose, save, error }) => {
|
const Wizard = ({ machine, locale, onClose, save, error }) => {
|
||||||
// Each stacker counts as two steps, one for front and another for rear
|
// Each stacker counts as two steps, one for front and another for rear
|
||||||
const LAST_STEP = machine.numberOfCassettes + machine.numberOfStackers * 2 + 1
|
const LAST_STEP =
|
||||||
|
machine.numberOfCassettes + machine.numberOfRecyclers * 2 + 1
|
||||||
const [{ step, config }, setState] = useState({
|
const [{ step, config }, setState] = useState({
|
||||||
step: 0,
|
step: 0,
|
||||||
config: { active: true }
|
config: { active: true }
|
||||||
|
|
@ -65,9 +66,9 @@ const Wizard = ({ machine, locale, onClose, save, error }) => {
|
||||||
R.chain(
|
R.chain(
|
||||||
it => [
|
it => [
|
||||||
{
|
{
|
||||||
type: `stacker${it}f`,
|
type: `recycler${it * 2 - 1}`,
|
||||||
model: 'stacker',
|
model: 'recycler',
|
||||||
display: `Stacker ${it}F`,
|
display: `Recycler ${it}`,
|
||||||
component: Autocomplete,
|
component: Autocomplete,
|
||||||
inputProps: {
|
inputProps: {
|
||||||
options: options,
|
options: options,
|
||||||
|
|
@ -76,9 +77,9 @@ const Wizard = ({ machine, locale, onClose, save, error }) => {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: `stacker${it}r`,
|
type: `recycler${it * 2}`,
|
||||||
model: 'stacker',
|
model: 'recycler',
|
||||||
display: `Stacker ${it}R`,
|
display: `Recycler ${it}`,
|
||||||
component: Autocomplete,
|
component: Autocomplete,
|
||||||
inputProps: {
|
inputProps: {
|
||||||
options: options,
|
options: options,
|
||||||
|
|
@ -87,7 +88,7 @@ const Wizard = ({ machine, locale, onClose, save, error }) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
R.range(1, machine.numberOfStackers + 1)
|
R.range(1, machine.numberOfRecyclers + 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -117,38 +118,38 @@ const Wizard = ({ machine, locale, onClose, save, error }) => {
|
||||||
: Yup.number()
|
: Yup.number()
|
||||||
.transform(transformNumber)
|
.transform(transformNumber)
|
||||||
.nullable(),
|
.nullable(),
|
||||||
stacker1f:
|
recycler1:
|
||||||
machine.numberOfStackers >= 1 && step >= machine.numberOfCassettes + 1
|
machine.numberOfRecyclers >= 1 && step >= machine.numberOfCassettes + 1
|
||||||
? Yup.number().required()
|
? Yup.number().required()
|
||||||
: Yup.number()
|
: Yup.number()
|
||||||
.transform(transformNumber)
|
.transform(transformNumber)
|
||||||
.nullable(),
|
.nullable(),
|
||||||
stacker1r:
|
recycler2:
|
||||||
machine.numberOfStackers >= 1 && step >= machine.numberOfCassettes + 2
|
machine.numberOfRecyclers >= 2 && step >= machine.numberOfCassettes + 2
|
||||||
? Yup.number().required()
|
? Yup.number().required()
|
||||||
: Yup.number()
|
: Yup.number()
|
||||||
.transform(transformNumber)
|
.transform(transformNumber)
|
||||||
.nullable(),
|
.nullable(),
|
||||||
stacker2f:
|
recycler3:
|
||||||
machine.numberOfStackers >= 2 && step >= machine.numberOfCassettes + 3
|
machine.numberOfRecyclers >= 3 && step >= machine.numberOfCassettes + 3
|
||||||
? Yup.number().required()
|
? Yup.number().required()
|
||||||
: Yup.number()
|
: Yup.number()
|
||||||
.transform(transformNumber)
|
.transform(transformNumber)
|
||||||
.nullable(),
|
.nullable(),
|
||||||
stacker2r:
|
recycler4:
|
||||||
machine.numberOfStackers >= 2 && step >= machine.numberOfCassettes + 4
|
machine.numberOfRecyclers >= 4 && step >= machine.numberOfCassettes + 4
|
||||||
? Yup.number().required()
|
? Yup.number().required()
|
||||||
: Yup.number()
|
: Yup.number()
|
||||||
.transform(transformNumber)
|
.transform(transformNumber)
|
||||||
.nullable(),
|
.nullable(),
|
||||||
stacker3f:
|
recycler5:
|
||||||
machine.numberOfStackers >= 3 && step >= machine.numberOfCassettes + 5
|
machine.numberOfRecyclers >= 5 && step >= machine.numberOfCassettes + 5
|
||||||
? Yup.number().required()
|
? Yup.number().required()
|
||||||
: Yup.number()
|
: Yup.number()
|
||||||
.transform(transformNumber)
|
.transform(transformNumber)
|
||||||
.nullable(),
|
.nullable(),
|
||||||
stacker3r:
|
recycler6:
|
||||||
machine.numberOfStackers >= 3 && step >= machine.numberOfCassettes + 6
|
machine.numberOfRecyclers >= 6 && step >= machine.numberOfCassettes + 6
|
||||||
? Yup.number().required()
|
? Yup.number().required()
|
||||||
: Yup.number()
|
: Yup.number()
|
||||||
.transform(transformNumber)
|
.transform(transformNumber)
|
||||||
|
|
|
||||||
|
|
@ -41,38 +41,38 @@ const DenominationsSchema = Yup.object().shape({
|
||||||
.max(CURRENCY_MAX)
|
.max(CURRENCY_MAX)
|
||||||
.nullable()
|
.nullable()
|
||||||
.transform(transformNumber),
|
.transform(transformNumber),
|
||||||
stacker1f: Yup.number()
|
recycler1: Yup.number()
|
||||||
.label('Stacker 1')
|
.label('Recycler 1')
|
||||||
.min(1)
|
.min(1)
|
||||||
.max(CURRENCY_MAX)
|
.max(CURRENCY_MAX)
|
||||||
.nullable()
|
.nullable()
|
||||||
.transform(transformNumber),
|
.transform(transformNumber),
|
||||||
stacker1r: Yup.number()
|
recycler2: Yup.number()
|
||||||
.label('Stacker 1')
|
.label('Recycler 2')
|
||||||
.min(1)
|
.min(1)
|
||||||
.max(CURRENCY_MAX)
|
.max(CURRENCY_MAX)
|
||||||
.nullable()
|
.nullable()
|
||||||
.transform(transformNumber),
|
.transform(transformNumber),
|
||||||
stacker2f: Yup.number()
|
recycler3: Yup.number()
|
||||||
.label('Stacker 2')
|
.label('Recycler 3')
|
||||||
.min(1)
|
.min(1)
|
||||||
.max(CURRENCY_MAX)
|
.max(CURRENCY_MAX)
|
||||||
.nullable()
|
.nullable()
|
||||||
.transform(transformNumber),
|
.transform(transformNumber),
|
||||||
stacker2r: Yup.number()
|
recycler4: Yup.number()
|
||||||
.label('Stacker 2')
|
.label('Recycler 4')
|
||||||
.min(1)
|
.min(1)
|
||||||
.max(CURRENCY_MAX)
|
.max(CURRENCY_MAX)
|
||||||
.nullable()
|
.nullable()
|
||||||
.transform(transformNumber),
|
.transform(transformNumber),
|
||||||
stacker3f: Yup.number()
|
recycler5: Yup.number()
|
||||||
.label('Stacker 3')
|
.label('Recycler 5')
|
||||||
.min(1)
|
.min(1)
|
||||||
.max(CURRENCY_MAX)
|
.max(CURRENCY_MAX)
|
||||||
.nullable()
|
.nullable()
|
||||||
.transform(transformNumber),
|
.transform(transformNumber),
|
||||||
stacker3r: Yup.number()
|
recycler6: Yup.number()
|
||||||
.label('Stacker 3')
|
.label('Recycler 6')
|
||||||
.min(1)
|
.min(1)
|
||||||
.max(CURRENCY_MAX)
|
.max(CURRENCY_MAX)
|
||||||
.nullable()
|
.nullable()
|
||||||
|
|
@ -85,11 +85,12 @@ const getElements = (machines, locale = {}, classes) => {
|
||||||
...R.map(it => it.numberOfCassettes, machines),
|
...R.map(it => it.numberOfCassettes, machines),
|
||||||
0
|
0
|
||||||
)
|
)
|
||||||
const maxNumberOfStackers = Math.max(
|
const maxNumberOfRecyclers = Math.max(
|
||||||
...R.map(it => it.numberOfStackers, machines),
|
...R.map(it => it.numberOfRecyclers, machines),
|
||||||
0
|
0
|
||||||
)
|
)
|
||||||
const numberOfCashUnits = maxNumberOfCassettes + maxNumberOfStackers
|
const numberOfCashUnits =
|
||||||
|
maxNumberOfCassettes + Math.ceil(maxNumberOfRecyclers / 2)
|
||||||
|
|
||||||
const options = getBillOptions(locale, denominations)
|
const options = getBillOptions(locale, denominations)
|
||||||
const cassetteProps =
|
const cassetteProps =
|
||||||
|
|
@ -140,29 +141,31 @@ const getElements = (machines, locale = {}, classes) => {
|
||||||
)
|
)
|
||||||
|
|
||||||
R.until(
|
R.until(
|
||||||
R.gt(R.__, maxNumberOfStackers),
|
R.gt(
|
||||||
it => {
|
R.__,
|
||||||
elements.push({
|
Math.ceil(maxNumberOfRecyclers),
|
||||||
names: [`stacker${it}f`, `stacker${it}r`],
|
it => {
|
||||||
header: `Stacker ${it}`,
|
elements.push({
|
||||||
size: 'sm',
|
names: [`recycler${it * 2 - 1}`, `recycler${it * 2}`],
|
||||||
stripe: true,
|
header: `Recyclers ${it * 2 - 1} ${it * 2}`,
|
||||||
textAlign: 'right',
|
size: 'sm',
|
||||||
width: widthsByNumberOfUnits[numberOfCashUnits]?.cassette,
|
stripe: true,
|
||||||
prefix: it => (R.last(it) === 'f' ? 'F' : 'R'),
|
textAlign: 'right',
|
||||||
suffix: fiatCurrency,
|
width: widthsByNumberOfUnits[numberOfCashUnits]?.cassette,
|
||||||
bold: bold,
|
suffix: fiatCurrency,
|
||||||
input: options?.length > 0 ? Autocomplete : NumberInput,
|
bold: bold,
|
||||||
inputProps: cassetteProps,
|
input: options?.length > 0 ? Autocomplete : NumberInput,
|
||||||
doubleHeader: 'Denominations of Cassettes & Recyclers',
|
inputProps: cassetteProps,
|
||||||
isHidden: machine =>
|
doubleHeader: 'Denominations of Cassettes & Recyclers',
|
||||||
it >
|
isHidden: machine =>
|
||||||
machines.find(({ deviceId }) => deviceId === machine.id)
|
it >
|
||||||
.numberOfStackers
|
machines.find(({ deviceId }) => deviceId === machine.id)
|
||||||
})
|
.numberOfRecyclers
|
||||||
return R.add(1, it)
|
})
|
||||||
},
|
return R.add(1, it)
|
||||||
1
|
},
|
||||||
|
1
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
return elements
|
return elements
|
||||||
|
|
|
||||||
|
|
@ -30,15 +30,15 @@ const GET_DATA = gql`
|
||||||
cassette2
|
cassette2
|
||||||
cassette3
|
cassette3
|
||||||
cassette4
|
cassette4
|
||||||
stacker1f
|
recycler1
|
||||||
stacker1r
|
recycler2
|
||||||
stacker2f
|
recycler3
|
||||||
stacker2r
|
recycler4
|
||||||
stacker3f
|
recycler5
|
||||||
stacker3r
|
recycler6
|
||||||
}
|
}
|
||||||
numberOfCassettes
|
numberOfCassettes
|
||||||
numberOfStackers
|
numberOfRecyclers
|
||||||
statuses {
|
statuses {
|
||||||
label
|
label
|
||||||
type
|
type
|
||||||
|
|
|
||||||
|
|
@ -28,12 +28,12 @@ const SET_CASSETTE_BILLS = gql`
|
||||||
cassette2
|
cassette2
|
||||||
cassette3
|
cassette3
|
||||||
cassette4
|
cassette4
|
||||||
stacker1f
|
recycler1
|
||||||
stacker1r
|
recycler2
|
||||||
stacker2f
|
recycler3
|
||||||
stacker2r
|
recycler4
|
||||||
stacker3f
|
recycler5
|
||||||
stacker3r
|
recycler6
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,15 +35,15 @@ const GET_INFO = gql`
|
||||||
cassette2
|
cassette2
|
||||||
cassette3
|
cassette3
|
||||||
cassette4
|
cassette4
|
||||||
stacker1f
|
recycler1
|
||||||
stacker1r
|
recycler2
|
||||||
stacker2f
|
recycler3
|
||||||
stacker2r
|
recycler4
|
||||||
stacker3f
|
recycler5
|
||||||
stacker3r
|
recycler6
|
||||||
}
|
}
|
||||||
numberOfCassettes
|
numberOfCassettes
|
||||||
numberOfStackers
|
numberOfRecyclers
|
||||||
statuses {
|
statuses {
|
||||||
label
|
label
|
||||||
type
|
type
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@ const CashUnitDetails = ({
|
||||||
))(R.keys(billCount))}
|
))(R.keys(billCount))}
|
||||||
</div>
|
</div>
|
||||||
<div className={classes.unitList}>
|
<div className={classes.unitList}>
|
||||||
{machine.numberOfStackers === 0 &&
|
{machine.numberOfRecyclers === 0 &&
|
||||||
R.map(it => (
|
R.map(it => (
|
||||||
<>
|
<>
|
||||||
<div className={classes.col}>
|
<div className={classes.col}>
|
||||||
|
|
@ -142,7 +142,7 @@ const CashUnitDetails = ({
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
))(R.range(1, machine.numberOfCassettes + 1))}
|
))(R.range(1, machine.numberOfCassettes + 1))}
|
||||||
{machine.numberOfStackers > 0 && (
|
{machine.numberOfRecyclers > 0 && (
|
||||||
<>
|
<>
|
||||||
<div className={classes.col}>
|
<div className={classes.col}>
|
||||||
<Label1
|
<Label1
|
||||||
|
|
@ -174,51 +174,51 @@ const CashUnitDetails = ({
|
||||||
{R.map(it => (
|
{R.map(it => (
|
||||||
<>
|
<>
|
||||||
<div className={classes.col}>
|
<div className={classes.col}>
|
||||||
<Label1
|
<Label1 noMargin className={classes.label}>{`Recycler ${it *
|
||||||
noMargin
|
2 -
|
||||||
className={classes.label}>{`Stacker ${it}`}</Label1>
|
1}`}</Label1>
|
||||||
<div className={classes.loadingBoxes}>
|
<div className={classes.loadingBoxes}>
|
||||||
<CashOut
|
<CashOut
|
||||||
width={60}
|
width={60}
|
||||||
height={40}
|
height={40}
|
||||||
currency={{ code: currency }}
|
currency={{ code: currency }}
|
||||||
notes={machine.cashUnits[`stacker${it}f`]}
|
notes={machine.cashUnits[`recycler${it * 2 - 1}`]}
|
||||||
denomination={
|
denomination={
|
||||||
getCashoutSettings(machine.id ?? machine.deviceId)[
|
getCashoutSettings(machine.id ?? machine.deviceId)[
|
||||||
`stacker${it}f`
|
`recycler${it}`
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
threshold={
|
threshold={
|
||||||
fillingPercentageSettings[
|
fillingPercentageSettings[
|
||||||
`fillingPercentageStacker${it}f`
|
`fillingPercentageRecycler${it * 2 - 1}`
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
capacity={getCashUnitCapacity(machine.model, 'stacker')}
|
capacity={getCashUnitCapacity(machine.model, 'recycler')}
|
||||||
/>
|
/>
|
||||||
<CashOut
|
<CashOut
|
||||||
width={60}
|
width={60}
|
||||||
height={40}
|
height={40}
|
||||||
currency={{ code: currency }}
|
currency={{ code: currency }}
|
||||||
notes={machine.cashUnits[`stacker${it}r`]}
|
notes={machine.cashUnits[`recycler${it * 2}`]}
|
||||||
denomination={
|
denomination={
|
||||||
getCashoutSettings(machine.id ?? machine.deviceId)[
|
getCashoutSettings(machine.id ?? machine.deviceId)[
|
||||||
`stacker${it}r`
|
`recycler${it * 2}`
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
threshold={
|
threshold={
|
||||||
fillingPercentageSettings[
|
fillingPercentageSettings[
|
||||||
`fillingPercentageStacker${it}r`
|
`fillingPercentageRecycler${it * 2}`
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
capacity={getCashUnitCapacity(machine.model, 'stacker')}
|
capacity={getCashUnitCapacity(machine.model, 'recycler')}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{it !== machine.numberOfStackers && (
|
{it !== machine.numberOfRecyclers && (
|
||||||
<span className={classes.verticalLine} />
|
<span className={classes.verticalLine} />
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
))(R.range(1, machine.numberOfStackers + 1))}
|
))(R.range(1, machine.numberOfRecyclers / 2 + 1))}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -40,15 +40,15 @@ const GET_MACHINES_AND_CONFIG = gql`
|
||||||
cassette2
|
cassette2
|
||||||
cassette3
|
cassette3
|
||||||
cassette4
|
cassette4
|
||||||
stacker1f
|
recycler1
|
||||||
stacker1r
|
recycler2
|
||||||
stacker2f
|
recycler3
|
||||||
stacker2r
|
recycler4
|
||||||
stacker3f
|
recycler5
|
||||||
stacker3r
|
recycler6
|
||||||
}
|
}
|
||||||
numberOfCassettes
|
numberOfCassettes
|
||||||
numberOfStackers
|
numberOfRecyclers
|
||||||
}
|
}
|
||||||
unpairedMachines {
|
unpairedMachines {
|
||||||
id: deviceId
|
id: deviceId
|
||||||
|
|
@ -84,12 +84,12 @@ const SET_CASSETTE_BILLS = gql`
|
||||||
cassette2
|
cassette2
|
||||||
cassette3
|
cassette3
|
||||||
cassette4
|
cassette4
|
||||||
stacker1f
|
recycler1
|
||||||
stacker1r
|
recycler2
|
||||||
stacker2f
|
recycler3
|
||||||
stacker2r
|
recycler4
|
||||||
stacker3f
|
recycler5
|
||||||
stacker3r
|
recycler6
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,29 +43,29 @@ const CashCassettesFooter = ({
|
||||||
acc,
|
acc,
|
||||||
{
|
{
|
||||||
cashUnits: {
|
cashUnits: {
|
||||||
stacker1f,
|
recycler1,
|
||||||
stacker1r,
|
recycler2,
|
||||||
stacker2f,
|
recycler3,
|
||||||
stacker2r,
|
recycler4,
|
||||||
stacker3f,
|
recycler5,
|
||||||
stacker3r
|
recycler6
|
||||||
},
|
},
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
) => {
|
) => {
|
||||||
const stacker1fDenomination = getCashoutSettings(id).stacker1f ?? 0
|
const recycler1Denomination = getCashoutSettings(id).recycler1 ?? 0
|
||||||
const stacker1rDenomination = getCashoutSettings(id).stacker1r ?? 0
|
const recycler2Denomination = getCashoutSettings(id).recycler2 ?? 0
|
||||||
const stacker2fDenomination = getCashoutSettings(id).stacker2f ?? 0
|
const recycler3Denomination = getCashoutSettings(id).recycler3 ?? 0
|
||||||
const stacker2rDenomination = getCashoutSettings(id).stacker2r ?? 0
|
const recycler4Denomination = getCashoutSettings(id).recycler4 ?? 0
|
||||||
const stacker3fDenomination = getCashoutSettings(id).stacker3f ?? 0
|
const recycler5Denomination = getCashoutSettings(id).recycler5 ?? 0
|
||||||
const stacker3rDenomination = getCashoutSettings(id).stacker3r ?? 0
|
const recycler6Denomination = getCashoutSettings(id).recycler6 ?? 0
|
||||||
return [
|
return [
|
||||||
(acc[0] += stacker1f * stacker1fDenomination),
|
(acc[0] += recycler1 * recycler1Denomination),
|
||||||
(acc[1] += stacker1r * stacker1rDenomination),
|
(acc[1] += recycler2 * recycler2Denomination),
|
||||||
(acc[0] += stacker2f * stacker2fDenomination),
|
(acc[0] += recycler3 * recycler3Denomination),
|
||||||
(acc[1] += stacker2r * stacker2rDenomination),
|
(acc[1] += recycler4 * recycler4Denomination),
|
||||||
(acc[0] += stacker3f * stacker3fDenomination),
|
(acc[0] += recycler5 * recycler5Denomination),
|
||||||
(acc[1] += stacker3r * stacker3rDenomination)
|
(acc[1] += recycler6 * recycler6Denomination)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,12 +31,12 @@ const GET_MACHINES = gql`
|
||||||
cassette2
|
cassette2
|
||||||
cassette3
|
cassette3
|
||||||
cassette4
|
cassette4
|
||||||
stacker1f
|
recycler1
|
||||||
stacker1r
|
recycler2
|
||||||
stacker2f
|
recycler3
|
||||||
stacker2r
|
recycler4
|
||||||
stacker3f
|
recycler5
|
||||||
stacker3r
|
recycler6
|
||||||
}
|
}
|
||||||
version
|
version
|
||||||
model
|
model
|
||||||
|
|
|
||||||
|
|
@ -18,13 +18,13 @@ const CASSETTE_FIELDS = R.map(
|
||||||
R.range(1, MAX_NUMBER_OF_CASSETTES + 1)
|
R.range(1, MAX_NUMBER_OF_CASSETTES + 1)
|
||||||
)
|
)
|
||||||
|
|
||||||
const STACKER_FIELDS = [
|
const RECYCLER_FIELDS = [
|
||||||
'stacker1f',
|
'recycler1',
|
||||||
'stacker1r',
|
'recycler2',
|
||||||
'stacker2f',
|
'recycler3',
|
||||||
'stacker2r',
|
'recycler4',
|
||||||
'stacker3f',
|
'recycler5',
|
||||||
'stacker3r'
|
'recycler6'
|
||||||
]
|
]
|
||||||
|
|
||||||
const Wizard = ({ machine, cashoutSettings, locale, onClose, save, error }) => {
|
const Wizard = ({ machine, cashoutSettings, locale, onClose, save, error }) => {
|
||||||
|
|
@ -37,9 +37,9 @@ const Wizard = ({ machine, cashoutSettings, locale, onClose, save, error }) => {
|
||||||
R.isEmpty(cashoutSettings) || !cashoutSettings?.active
|
R.isEmpty(cashoutSettings) || !cashoutSettings?.active
|
||||||
|
|
||||||
const numberOfCassettes = isCashOutDisabled ? 0 : machine.numberOfCassettes
|
const numberOfCassettes = isCashOutDisabled ? 0 : machine.numberOfCassettes
|
||||||
const numberOfStackers = machine.numberOfStackers
|
const numberOfRecyclers = machine.numberOfRecyclers
|
||||||
|
|
||||||
// const LAST_STEP = numberOfCassettes + numberOfStackers * 2 + 1
|
// const LAST_STEP = numberOfCassettes + numberOfRecyclers * 2 + 1
|
||||||
const LAST_STEP = numberOfCassettes + 1
|
const LAST_STEP = numberOfCassettes + 1
|
||||||
|
|
||||||
const title = `Update counts`
|
const title = `Update counts`
|
||||||
|
|
@ -56,7 +56,7 @@ const Wizard = ({ machine, cashoutSettings, locale, onClose, save, error }) => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const buildStackerObj = cassetteInput => {
|
const buildRecyclerObj = cassetteInput => {
|
||||||
return R.reduce(
|
return R.reduce(
|
||||||
(acc, value) => {
|
(acc, value) => {
|
||||||
acc[value] = machine.cashUnits[value]
|
acc[value] = machine.cashUnits[value]
|
||||||
|
|
@ -64,7 +64,7 @@ const Wizard = ({ machine, cashoutSettings, locale, onClose, save, error }) => {
|
||||||
return acc
|
return acc
|
||||||
},
|
},
|
||||||
{},
|
{},
|
||||||
STACKER_FIELDS
|
RECYCLER_FIELDS
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -77,12 +77,12 @@ const Wizard = ({ machine, cashoutSettings, locale, onClose, save, error }) => {
|
||||||
].includes('YES')
|
].includes('YES')
|
||||||
|
|
||||||
const cassettes = buildCassetteObj(it)
|
const cassettes = buildCassetteObj(it)
|
||||||
const stackers = buildStackerObj(it)
|
const recyclers = buildRecyclerObj(it)
|
||||||
|
|
||||||
const cashUnits = {
|
const cashUnits = {
|
||||||
cashbox: wasCashboxEmptied ? 0 : machine?.cashUnits.cashbox,
|
cashbox: wasCashboxEmptied ? 0 : machine?.cashUnits.cashbox,
|
||||||
...cassettes,
|
...cassettes,
|
||||||
...stackers
|
...recyclers
|
||||||
}
|
}
|
||||||
|
|
||||||
save(machine.id, cashUnits)
|
save(machine.id, cashUnits)
|
||||||
|
|
@ -184,21 +184,21 @@ const Wizard = ({ machine, cashoutSettings, locale, onClose, save, error }) => {
|
||||||
)
|
)
|
||||||
: {}
|
: {}
|
||||||
|
|
||||||
const makeStackersInitialValues = () =>
|
const makeRecyclersInitialValues = () =>
|
||||||
!R.isEmpty(cashoutSettings)
|
!R.isEmpty(cashoutSettings)
|
||||||
? R.reduce(
|
? R.reduce(
|
||||||
(acc, value) => {
|
(acc, value) => {
|
||||||
acc[`stacker${value}f`] = ''
|
acc[`recycler${value * 2 - 1}`] = ''
|
||||||
acc[`stacker${value}r`] = ''
|
acc[`recycler${value * 2}`] = ''
|
||||||
return acc
|
return acc
|
||||||
},
|
},
|
||||||
{},
|
{},
|
||||||
R.range(1, numberOfStackers + 1)
|
R.range(1, numberOfRecyclers + 1)
|
||||||
)
|
)
|
||||||
: {}
|
: {}
|
||||||
|
|
||||||
const makeInitialValues = () =>
|
const makeInitialValues = () =>
|
||||||
R.merge(makeCassettesInitialValues(), makeStackersInitialValues())
|
R.merge(makeCassettesInitialValues(), makeRecyclersInitialValues())
|
||||||
|
|
||||||
const steps = R.pipe(
|
const steps = R.pipe(
|
||||||
// R.concat(makeStackerSteps(numberOfStackers)),
|
// R.concat(makeStackerSteps(numberOfStackers)),
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,7 @@ const useStyles = makeStyles(styles)
|
||||||
|
|
||||||
const CASHBOX_STEP = 1
|
const CASHBOX_STEP = 1
|
||||||
|
|
||||||
const cassetesArtworks = (step, numberOfCassettes, numberOfStackers) => {
|
const cassetesArtworks = (step, numberOfCassettes, numberOfRecyclers) => {
|
||||||
const cassetteStepsStart = CASHBOX_STEP + 1
|
const cassetteStepsStart = CASHBOX_STEP + 1
|
||||||
return [
|
return [
|
||||||
[cassetteOne],
|
[cassetteOne],
|
||||||
|
|
@ -118,7 +118,7 @@ const cassetesArtworks = (step, numberOfCassettes, numberOfStackers) => {
|
||||||
][numberOfCassettes - cassetteStepsStart + 1][step - cassetteStepsStart]
|
][numberOfCassettes - cassetteStepsStart + 1][step - cassetteStepsStart]
|
||||||
}
|
}
|
||||||
|
|
||||||
const getCashUnitFieldName = (step, numberOfCassettes, numberOfStackers) => {
|
const getCashUnitFieldName = (step, numberOfCassettes, numberOfRecyclers) => {
|
||||||
if (step === CASHBOX_STEP) return { name: 'cashbox', category: 'cashbox' }
|
if (step === CASHBOX_STEP) return { name: 'cashbox', category: 'cashbox' }
|
||||||
const cassetteStepsStart = CASHBOX_STEP + 1
|
const cassetteStepsStart = CASHBOX_STEP + 1
|
||||||
if (step < cassetteStepsStart + numberOfCassettes)
|
if (step < cassetteStepsStart + numberOfCassettes)
|
||||||
|
|
@ -126,13 +126,11 @@ const getCashUnitFieldName = (step, numberOfCassettes, numberOfStackers) => {
|
||||||
name: `cassette${step - cassetteStepsStart + 1}`,
|
name: `cassette${step - cassetteStepsStart + 1}`,
|
||||||
category: 'cassette'
|
category: 'cassette'
|
||||||
}
|
}
|
||||||
const stackerStepsStart = CASHBOX_STEP + numberOfCassettes + 1
|
const recyclerStepsStart = CASHBOX_STEP + numberOfCassettes + 1
|
||||||
if (step < stackerStepsStart + numberOfStackers * 2)
|
if (step < recyclerStepsStart + numberOfRecyclers * 2)
|
||||||
return {
|
return {
|
||||||
name: `stacker${Math.ceil((step - stackerStepsStart + 1) / 2)}${
|
name: `recycler${Math.ceil(step - recyclerStepsStart + 1)}`,
|
||||||
(step - stackerStepsStart) % 2 === 0 ? 'f' : 'r'
|
category: 'recycler'
|
||||||
}`,
|
|
||||||
category: 'stacker'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -158,11 +156,11 @@ const WizardStep = ({
|
||||||
]
|
]
|
||||||
|
|
||||||
const numberOfCassettes = machine.numberOfCassettes
|
const numberOfCassettes = machine.numberOfCassettes
|
||||||
const numberOfStackers = machine.numberOfStackers
|
const numberOfRecyclers = machine.numberOfRecyclers
|
||||||
const {
|
const {
|
||||||
name: cashUnitField,
|
name: cashUnitField,
|
||||||
category: cashUnitCategory
|
category: cashUnitCategory
|
||||||
} = getCashUnitFieldName(step, numberOfCassettes, numberOfStackers)
|
} = getCashUnitFieldName(step, numberOfCassettes, numberOfRecyclers)
|
||||||
const originalCashUnitCount = machine?.cashUnits?.[cashUnitField]
|
const originalCashUnitCount = machine?.cashUnits?.[cashUnitField]
|
||||||
const cashUnitDenomination = cashoutSettings?.[cashUnitField]
|
const cashUnitDenomination = cashoutSettings?.[cashUnitField]
|
||||||
|
|
||||||
|
|
@ -268,7 +266,7 @@ const WizardStep = ({
|
||||||
src={cassetesArtworks(
|
src={cassetesArtworks(
|
||||||
step,
|
step,
|
||||||
numberOfCassettes,
|
numberOfCassettes,
|
||||||
numberOfStackers
|
numberOfRecyclers
|
||||||
)}></img>
|
)}></img>
|
||||||
<div className={classes.formWrapper}>
|
<div className={classes.formWrapper}>
|
||||||
<div
|
<div
|
||||||
|
|
@ -293,7 +291,7 @@ const WizardStep = ({
|
||||||
{startCase(cashUnitField)} (
|
{startCase(cashUnitField)} (
|
||||||
{R.includes('cassette', cashUnitField)
|
{R.includes('cassette', cashUnitField)
|
||||||
? `dispenser`
|
? `dispenser`
|
||||||
: R.includes('stacker', cashUnitField)
|
: R.includes('recycler', cashUnitField)
|
||||||
? `recycler`
|
? `recycler`
|
||||||
: ``}
|
: ``}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -78,36 +78,40 @@ const getElements = (
|
||||||
<CashOutLite
|
<CashOutLite
|
||||||
width={'100%'}
|
width={'100%'}
|
||||||
currency={{ code: fiatCurrency }}
|
currency={{ code: fiatCurrency }}
|
||||||
notes={m.cashUnits[`stacker${it}f`]}
|
notes={m.cashUnits[`recycler${it * 2 - 1}`]}
|
||||||
denomination={
|
denomination={
|
||||||
getCashoutSettings(m.id ?? m.deviceId)[`stacker${it}f`]
|
getCashoutSettings(m.id ?? m.deviceId)[
|
||||||
|
`recycler${it * 2 - 1}`
|
||||||
|
]
|
||||||
}
|
}
|
||||||
threshold={
|
threshold={
|
||||||
fillingPercentageSettings[
|
fillingPercentageSettings[
|
||||||
`fillingPercentageStacker${it}f`
|
`fillingPercentageRecycler${it * 2 - 1}`
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
capacity={getCashUnitCapacity(m.model, 'stacker')}
|
capacity={getCashUnitCapacity(m.model, 'recycler')}
|
||||||
/>
|
/>
|
||||||
<CashOutLite
|
<CashOutLite
|
||||||
width={'100%'}
|
width={'100%'}
|
||||||
currency={{ code: fiatCurrency }}
|
currency={{ code: fiatCurrency }}
|
||||||
notes={m.cashUnits[`stacker${it}r`]}
|
notes={m.cashUnits[`recycler${it * 2}`]}
|
||||||
denomination={
|
denomination={
|
||||||
getCashoutSettings(m.id ?? m.deviceId)[`stacker${it}r`]
|
getCashoutSettings(m.id ?? m.deviceId)[
|
||||||
|
`recycler${it * 2}`
|
||||||
|
]
|
||||||
}
|
}
|
||||||
threshold={
|
threshold={
|
||||||
fillingPercentageSettings[
|
fillingPercentageSettings[
|
||||||
`fillingPercentageStacker${it}r`
|
`fillingPercentageRecycler${it * 2}`
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
capacity={getCashUnitCapacity(m.model, 'stacker')}
|
capacity={getCashUnitCapacity(m.model, 'recycler')}
|
||||||
/>
|
/>
|
||||||
{it !== m.numberOfStackers && (
|
{it !== m.numberOfRecyclers && (
|
||||||
<span className={classes.verticalLine} />
|
<span className={classes.verticalLine} />
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
))(R.range(1, m.numberOfStackers + 1))}
|
))(R.range(1, m.numberOfRecyclers / 2 + 1))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ const GET_INFO = gql`
|
||||||
name
|
name
|
||||||
deviceId
|
deviceId
|
||||||
numberOfCassettes
|
numberOfCassettes
|
||||||
numberOfStackers
|
numberOfRecyclers
|
||||||
}
|
}
|
||||||
cryptoCurrencies {
|
cryptoCurrencies {
|
||||||
code
|
code
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ const CASH_IN_KEY = 'fiatBalanceAlertsCashIn'
|
||||||
const CASH_OUT_KEY = 'fiatBalanceAlertsCashOut'
|
const CASH_OUT_KEY = 'fiatBalanceAlertsCashOut'
|
||||||
const RECYCLER_STACKER_KEY = 'fiatBalanceAlertsRecyclerStacker'
|
const RECYCLER_STACKER_KEY = 'fiatBalanceAlertsRecyclerStacker'
|
||||||
const DEFAULT_NUMBER_OF_CASSETTES = 2
|
const DEFAULT_NUMBER_OF_CASSETTES = 2
|
||||||
const DEFAULT_NUMBER_OF_STACKERS = 0
|
const DEFAULT_NUMBER_OF_RECYCLERS = 0
|
||||||
const notesMin = 0
|
const notesMin = 0
|
||||||
const notesMax = 9999999
|
const notesMax = 9999999
|
||||||
|
|
||||||
|
|
@ -41,9 +41,9 @@ const FiatBalance = ({ section, min = 0, max = 100, fieldWidth = 80 }) => {
|
||||||
DEFAULT_NUMBER_OF_CASSETTES
|
DEFAULT_NUMBER_OF_CASSETTES
|
||||||
)
|
)
|
||||||
|
|
||||||
const maxNumberOfStackers = Math.max(
|
const maxNumberOfRecyclers = Math.max(
|
||||||
...R.map(it => it.numberOfStackers, machines),
|
...R.map(it => it.numberOfRecyclers, machines),
|
||||||
DEFAULT_NUMBER_OF_STACKERS
|
DEFAULT_NUMBER_OF_RECYCLERS
|
||||||
)
|
)
|
||||||
|
|
||||||
const percentValidation = Yup.number()
|
const percentValidation = Yup.number()
|
||||||
|
|
@ -64,12 +64,12 @@ const FiatBalance = ({ section, min = 0, max = 100, fieldWidth = 80 }) => {
|
||||||
fillingPercentageCassette2: percentValidation,
|
fillingPercentageCassette2: percentValidation,
|
||||||
fillingPercentageCassette3: percentValidation,
|
fillingPercentageCassette3: percentValidation,
|
||||||
fillingPercentageCassette4: percentValidation,
|
fillingPercentageCassette4: percentValidation,
|
||||||
fillingPercentageStacker1f: percentValidation,
|
fillingPercentageRecycler1: percentValidation,
|
||||||
fillingPercentageStacker1r: percentValidation,
|
fillingPercentageRecycler2: percentValidation,
|
||||||
fillingPercentageStacker2f: percentValidation,
|
fillingPercentageRecycler3: percentValidation,
|
||||||
fillingPercentageStacker2r: percentValidation,
|
fillingPercentageRecycler4: percentValidation,
|
||||||
fillingPercentageStacker3f: percentValidation,
|
fillingPercentageRecycler5: percentValidation,
|
||||||
fillingPercentageStacker3r: percentValidation
|
fillingPercentageRecycler6: percentValidation
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -83,12 +83,12 @@ const FiatBalance = ({ section, min = 0, max = 100, fieldWidth = 80 }) => {
|
||||||
fillingPercentageCassette2: data?.fillingPercentageCassette2 ?? '',
|
fillingPercentageCassette2: data?.fillingPercentageCassette2 ?? '',
|
||||||
fillingPercentageCassette3: data?.fillingPercentageCassette3 ?? '',
|
fillingPercentageCassette3: data?.fillingPercentageCassette3 ?? '',
|
||||||
fillingPercentageCassette4: data?.fillingPercentageCassette4 ?? '',
|
fillingPercentageCassette4: data?.fillingPercentageCassette4 ?? '',
|
||||||
fillingPercentageStacker1f: data?.fillingPercentageStacker1f ?? '',
|
fillingPercentageRecycler1: data?.fillingPercentageRecycler1 ?? '',
|
||||||
fillingPercentageStacker1r: data?.fillingPercentageStacker1r ?? '',
|
fillingPercentageRecycler2: data?.fillingPercentageRecycler2 ?? '',
|
||||||
fillingPercentageStacker2f: data?.fillingPercentageStacker2f ?? '',
|
fillingPercentageRecycler3: data?.fillingPercentageRecycler3 ?? '',
|
||||||
fillingPercentageStacker2r: data?.fillingPercentageStacker2r ?? '',
|
fillingPercentageRecycler4: data?.fillingPercentageRecycler4 ?? '',
|
||||||
fillingPercentageStacker3f: data?.fillingPercentageStacker3f ?? '',
|
fillingPercentageRecycler5: data?.fillingPercentageRecycler5 ?? '',
|
||||||
fillingPercentageStacker3r: data?.fillingPercentageStacker3r ?? ''
|
fillingPercentageRecycler6: data?.fillingPercentageRecycler6 ?? ''
|
||||||
}}
|
}}
|
||||||
validationSchema={schema}
|
validationSchema={schema}
|
||||||
onSubmit={it => save(section, schema.cast(it))}
|
onSubmit={it => save(section, schema.cast(it))}
|
||||||
|
|
@ -169,7 +169,7 @@ const FiatBalance = ({ section, min = 0, max = 100, fieldWidth = 80 }) => {
|
||||||
<Form className={classes.form}>
|
<Form className={classes.form}>
|
||||||
<PromptWhenDirty />
|
<PromptWhenDirty />
|
||||||
<Header
|
<Header
|
||||||
title="Cash recycling (stackers)"
|
title="Cash recycling"
|
||||||
editing={isEditing(RECYCLER_STACKER_KEY)}
|
editing={isEditing(RECYCLER_STACKER_KEY)}
|
||||||
disabled={isDisabled(RECYCLER_STACKER_KEY)}
|
disabled={isDisabled(RECYCLER_STACKER_KEY)}
|
||||||
setEditing={it => setEditing(RECYCLER_STACKER_KEY, it)}
|
setEditing={it => setEditing(RECYCLER_STACKER_KEY, it)}
|
||||||
|
|
@ -183,8 +183,9 @@ const FiatBalance = ({ section, min = 0, max = 100, fieldWidth = 80 }) => {
|
||||||
labelClassName={classes.cashboxLabel}
|
labelClassName={classes.cashboxLabel}
|
||||||
emptyPartClassName={classes.cashboxEmptyPart}
|
emptyPartClassName={classes.cashboxEmptyPart}
|
||||||
percent={
|
percent={
|
||||||
values[`fillingPercentageStacker${it + 1}f`] ??
|
values[
|
||||||
data[`stacker${it + 1}f`]
|
`fillingPercentageRecycler${(it + 1) * 2 - 1}`
|
||||||
|
] ?? data[`recycler${(it + 1) * 2 - 1}f`]
|
||||||
}
|
}
|
||||||
applyColorVariant
|
applyColorVariant
|
||||||
applyFiatBalanceAlertsStyling
|
applyFiatBalanceAlertsStyling
|
||||||
|
|
@ -192,10 +193,12 @@ const FiatBalance = ({ section, min = 0, max = 100, fieldWidth = 80 }) => {
|
||||||
cashOut
|
cashOut
|
||||||
/>
|
/>
|
||||||
<div className={classes.col2}>
|
<div className={classes.col2}>
|
||||||
<TL2 className={classes.title}>Stacker {it + 1}F</TL2>
|
<TL2 className={classes.title}>
|
||||||
|
Recycler {(it + 1) * 2 - 1}
|
||||||
|
</TL2>
|
||||||
<EditableNumber
|
<EditableNumber
|
||||||
label="Alert me under"
|
label="Alert me under"
|
||||||
name={`fillingPercentageStacker${it + 1}f`}
|
name={`fillingPercentageRecycler${(it + 1) * 2 - 1}`}
|
||||||
editing={isEditing(RECYCLER_STACKER_KEY)}
|
editing={isEditing(RECYCLER_STACKER_KEY)}
|
||||||
displayValue={x => (x === '' ? '-' : x)}
|
displayValue={x => (x === '' ? '-' : x)}
|
||||||
decoration="%"
|
decoration="%"
|
||||||
|
|
@ -210,8 +213,8 @@ const FiatBalance = ({ section, min = 0, max = 100, fieldWidth = 80 }) => {
|
||||||
labelClassName={classes.cashboxLabel}
|
labelClassName={classes.cashboxLabel}
|
||||||
emptyPartClassName={classes.cashboxEmptyPart}
|
emptyPartClassName={classes.cashboxEmptyPart}
|
||||||
percent={
|
percent={
|
||||||
values[`fillingPercentageStacker${it + 1}r`] ??
|
values[`fillingPercentageRecycler${(it + 1) * 2}`] ??
|
||||||
data[`stacker${it + 1}r`]
|
data[`recycler${(it + 1) * 2}`]
|
||||||
}
|
}
|
||||||
applyColorVariant
|
applyColorVariant
|
||||||
applyFiatBalanceAlertsStyling
|
applyFiatBalanceAlertsStyling
|
||||||
|
|
@ -219,10 +222,12 @@ const FiatBalance = ({ section, min = 0, max = 100, fieldWidth = 80 }) => {
|
||||||
cashOut
|
cashOut
|
||||||
/>
|
/>
|
||||||
<div className={classes.col2}>
|
<div className={classes.col2}>
|
||||||
<TL2 className={classes.title}>Stacker {it + 1}R</TL2>
|
<TL2 className={classes.title}>
|
||||||
|
Recycler {(it + 1) * 2}
|
||||||
|
</TL2>
|
||||||
<EditableNumber
|
<EditableNumber
|
||||||
label="Alert me under"
|
label="Alert me under"
|
||||||
name={`fillingPercentageStacker${it + 1}r`}
|
name={`fillingPercentageRecycler${(it + 1) * 2}`}
|
||||||
editing={isEditing(RECYCLER_STACKER_KEY)}
|
editing={isEditing(RECYCLER_STACKER_KEY)}
|
||||||
displayValue={x => (x === '' ? '-' : x)}
|
displayValue={x => (x === '' ? '-' : x)}
|
||||||
decoration="%"
|
decoration="%"
|
||||||
|
|
@ -232,7 +237,7 @@ const FiatBalance = ({ section, min = 0, max = 100, fieldWidth = 80 }) => {
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
],
|
],
|
||||||
R.times(R.identity, maxNumberOfStackers)
|
R.times(R.identity, maxNumberOfRecyclers)
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ const cashUnitCapacity = {
|
||||||
},
|
},
|
||||||
aveiro: {
|
aveiro: {
|
||||||
cashbox: 1500,
|
cashbox: 1500,
|
||||||
stacker: 60,
|
recycler: 60,
|
||||||
escrow: 20,
|
escrow: 20,
|
||||||
cassette: 500
|
cassette: 500
|
||||||
},
|
},
|
||||||
|
|
|
||||||
11481
package-lock.json
generated
11481
package-lock.json
generated
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue