improve cash-in error handling

This commit is contained in:
Josh Harvey 2017-04-23 16:37:25 +03:00
parent 86adfd0a63
commit 84a93599f5
9 changed files with 263 additions and 47 deletions

View file

@ -49,9 +49,62 @@ function post (tx, pi) {
const [, newTx] = txVector
return postProcess(txVector, pi)
.then(changes => update(newTx, changes))
.then(savedTx => {
return logAction(tx, savedTx)
.then(_.constant(savedTx))
})
})
}
function logError (action, err) {
return logAction({
action,
error: err.message,
error_code: err.name
})
}
function mapDispense (tx) {
const bills = tx.bills
if (_.isEmpty(bills)) return {}
const dispense = {
provisioned_1: bills[0].provisioned,
provisioned_2: bills[1].provisioned,
dispensed_1: bills[0].actualDispense,
dispensed_2: bills[1].actualDispense,
rejected_1: bills[0].rejected,
rejected_2: bills[1].rejected,
denomination_1: bills[0].denomination,
denomination_2: bills[1].denomination
}
return dispense
}
function logDispense (tx) {
const baseRec = {error: tx.error, errorCode: tx.errorCode}
const rec = _.merge(mapDispense(tx), baseRec)
return logAction('dispense', rec, tx)
}
function logActionById (action, _rec, txId) {
const rec = _.assign(_rec, {action, tx_id: txId, redeem: false})
const sql = pgp.helpers.insert(rec, null, 'cash_out_actions')
return db.none(sql)
}
function logAction (action, _rec, tx) {
const rec = _.assign(_rec, {action, tx_id: tx.id, redeem: tx.redeem})
const sql = pgp.helpers.insert(rec, null, 'cash_out_actions')
return db.none(sql)
.then(_.constant(tx))
}
function nilEqual (a, b) {
if (_.isNil(a) && _.isNil(b)) return true
@ -95,8 +148,6 @@ function toObj (row) {
}
function upsert (oldTx, tx) {
// insert bills
if (!oldTx) {
return insert(tx)
.then(newTx => [oldTx, newTx])
@ -106,24 +157,6 @@ function upsert (oldTx, tx) {
.then(newTx => [oldTx, newTx])
}
function mapDispense (tx) {
const bills = tx.bills
if (_.isEmpty(bills)) return tx
const extra = {
dispensed1: bills[0].actualDispense,
dispensed2: bills[1].actualDispense,
rejected1: bills[0].rejected,
rejected2: bills[1].rejected,
denomination1: bills[0].denomination,
denomination2: bills[1].denomination,
'dispenseTime^': 'NOW()'
}
return _.assign(tx, extra)
}
function convertBigNumFields (obj) {
const convert = (value, key) => _.includes(key, ['cryptoAtoms', 'fiat'])
? value.toString()
@ -141,7 +174,7 @@ function convertField (key) {
}
function toDb (tx) {
const massager = _.flow(convertBigNumFields, mapDispense, _.omit(['direction', 'bills']), _.mapKeys(convertField))
const massager = _.flow(convertBigNumFields, _.omit(['direction', 'bills']), _.mapKeys(convertField))
return massager(tx)
}
@ -175,17 +208,47 @@ function nextHd (isHd, tx) {
.then(row => _.set('hdIndex', row.hd_index, tx))
}
function preProcess (tx, newTx, pi) {
if (!tx) {
function preProcess (oldTx, newTx, pi) {
if (!oldTx) {
return pi.isHd(newTx)
.then(isHd => nextHd(isHd, newTx))
.then(newTxHd => {
return pi.newAddress(newTxHd)
.then(_.set('toAddress', _, newTxHd))
})
.then(addressedTx => {
const rec = {toAddress: addressedTx.toAddress}
return logAction('provisionAddress', rec, addressedTx)
})
.catch(err => {
return logError('provisionAddress', err)
.then(() => { throw err })
})
}
return Promise.resolve(updateStatus(tx, newTx))
return Promise.resolve(updateStatus(oldTx, newTx))
.then(updatedTx => {
if (!oldTx) return updatedTx
if (updatedTx.status !== oldTx.status) {
return logAction(updatedTx.status, {}, updatedTx)
}
if (_.isNil(oldTx.dispenseConfirmed) && _.isBoolean(updatedTx.dispenseConfirmed)) {
return logDispense(updatedTx)
.then(pi.updateCassettes(updatedTx))
}
if (!oldTx.phone && newTx.phone) {
return logAction('addPhone', {}, updatedTx)
}
if (!oldTx.redeem && newTx.redeem) {
return logAction('redeemLater', {}, updatedTx)
}
return updatedTx
})
}
function postProcess (txVector, pi) {
@ -197,6 +260,14 @@ function postProcess (txVector, pi) {
pi.sell(newTx)
return _.set('bills', billMath.makeChange(cartridges.cartridges, newTx.fiat), newTx)
})
.then(tx => {
const rec = {provisioned_1: tx.bills[0], provisioned_2: tx.bills[1]}
return logAction('provisionNotes', rec, tx)
})
.catch(err => {
return logError('provisionNotes', err)
.then(() => { throw err })
})
}
return Promise.resolve(newTx)
@ -277,7 +348,7 @@ function monitorUnnotified (settings) {
function cancel (txId) {
const updateRec = {
'dispense_time': 'now()^',
dispense_error: 'Operator cancel',
error: 'Operator cancel',
dispensed: true
}
@ -290,4 +361,5 @@ function cancel (txId) {
.then(res => {
if (res.rowCount !== 1) throw new Error('No such tx-id')
})
.then(() => logActionById('operatorCompleted', {}, txId))
}