Feat: save cash balance notifications in DB
Feat: add "detail" row in notifications table migration This makes searching for specific notifications in the code like cashbox number easier because we don't need to scrub the notification message column anymore to search for notifications relating the cashbox 1 for example. Feat: clear notifications on cash cassette balance update
This commit is contained in:
parent
2ced230020
commit
196a05549f
5 changed files with 64 additions and 6 deletions
|
|
@ -9,6 +9,8 @@ const helper = require('./cash-out-helper')
|
||||||
const cashOutActions = require('./cash-out-actions')
|
const cashOutActions = require('./cash-out-actions')
|
||||||
const cashOutLow = require('./cash-out-low')
|
const cashOutLow = require('./cash-out-low')
|
||||||
|
|
||||||
|
const notifier = require("../notifier/index")
|
||||||
|
|
||||||
const toObj = helper.toObj
|
const toObj = helper.toObj
|
||||||
|
|
||||||
module.exports = {atomic}
|
module.exports = {atomic}
|
||||||
|
|
@ -122,8 +124,10 @@ function updateCassettes (t, tx) {
|
||||||
tx.deviceId
|
tx.deviceId
|
||||||
]
|
]
|
||||||
|
|
||||||
return t.one(sql, values)
|
return t.one(sql, values).then(r => {
|
||||||
.then(r => socket.emit(_.assign(r, {op: 'cassetteUpdate', deviceId: tx.deviceId})))
|
notifier.cashCassettesNotify(r, tx.deviceId)
|
||||||
|
return socket.emit(_.assign(r, {op: 'cassetteUpdate', deviceId: tx.deviceId}))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function wasJustAuthorized (oldTx, newTx, isZeroConf) {
|
function wasJustAuthorized (oldTx, newTx, isZeroConf) {
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,10 @@ function renameMachine (rec) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetCashOutBills (rec) {
|
function resetCashOutBills (rec) {
|
||||||
const sql = 'update devices set cassette1=$1, cassette2=$2 where device_id=$3'
|
const sql = `
|
||||||
|
update devices set cassette1=$1, cassette2=$2 where device_id=$3;
|
||||||
|
update notifications set read = 't' where device_id = $3 AND type = 'fiatBalance' AND read = 'f';
|
||||||
|
`
|
||||||
return db.none(sql, [rec.cassettes[0], rec.cassettes[1], rec.deviceId])
|
return db.none(sql, [rec.cassettes[0], rec.cassettes[1], rec.deviceId])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,7 @@ async function transactionNotify (tx, rec) {
|
||||||
const isCashOut = tx.direction === 'cashOut'
|
const isCashOut = tx.direction === 'cashOut'
|
||||||
|
|
||||||
// high value tx on database
|
// high value tx on database
|
||||||
if(highValueTx) {
|
if(highValueTx && tx.direction === 'cashIn' || highValueTx && tx.direction === 'cashOut' && rec.isRedemption) {
|
||||||
queries.addHighValueTx(tx)
|
queries.addHighValueTx(tx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -205,10 +205,40 @@ async function sendTransactionMessage(rec, isHighValueTx) {
|
||||||
return Promise.all(promises)
|
return Promise.all(promises)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const cashCassettesNotify = (cassettes, deviceId) => {
|
||||||
|
settingsLoader.loadLatest()
|
||||||
|
.then(settings =>
|
||||||
|
[
|
||||||
|
configManager.getNotifications(null, deviceId, settings.config),
|
||||||
|
configManager.getCashOut(deviceId,settings.config).active
|
||||||
|
])
|
||||||
|
.then(([notifications, cashOutEnabled]) => {
|
||||||
|
const cassette1Count = cassettes.cassette1
|
||||||
|
const cassette2Count = cassettes.cassette2
|
||||||
|
const cassette1Threshold = notifications.fiatBalanceCassette1
|
||||||
|
const cassette2Threshold = notifications.fiatBalanceCassette2
|
||||||
|
|
||||||
|
if(cashOutEnabled) {
|
||||||
|
// we only want to add this notification if there isn't one already set and unread in the database
|
||||||
|
Promise.all([queries.getUnreadCassetteNotifications(1), queries.getUnreadCassetteNotifications(2)]).then(res => {
|
||||||
|
if(res[0].length === 0 && cassette1Count < cassette1Threshold) {
|
||||||
|
console.log("Adding fiatBalance alert for cashbox 1 in database - count & threshold: ", cassette1Count, cassette1Threshold )
|
||||||
|
queries.addCashCassetteWarning(1, deviceId)
|
||||||
|
}
|
||||||
|
if(res[1].length === 0 && cassette2Count < cassette2Threshold) {
|
||||||
|
console.log("Adding fiatBalance alert for cashbox 2 in database - count & threshold: ", cassette2Count, cassette2Threshold )
|
||||||
|
queries.addCashCassetteWarning(2, deviceId)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
transactionNotify,
|
transactionNotify,
|
||||||
checkNotification,
|
checkNotification,
|
||||||
checkPings,
|
checkPings,
|
||||||
checkStuckScreen,
|
checkStuckScreen,
|
||||||
sendRedemptionMessage
|
sendRedemptionMessage,
|
||||||
|
cashCassettesNotify
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,15 @@ const dbm = require('../postgresql_interface')
|
||||||
const db = require('../db')
|
const db = require('../db')
|
||||||
const { v4: uuidv4 } = require('uuid')
|
const { v4: uuidv4 } = require('uuid')
|
||||||
|
|
||||||
|
// types of notifications able to be inserted into db:
|
||||||
|
/*
|
||||||
|
highValueTransaction - for transactions of value higher than threshold
|
||||||
|
fiatBalance - when the number of notes in cash cassettes falls below threshold
|
||||||
|
cryptoBalance - when ammount of crypto balance in fiat falls below or above low/high threshold
|
||||||
|
compliance - notifications related to warnings triggered by compliance settings
|
||||||
|
error - notifications related to errors
|
||||||
|
*/
|
||||||
|
|
||||||
const addHighValueTx = (tx) => {
|
const addHighValueTx = (tx) => {
|
||||||
const sql = `INSERT INTO notifications (id, type, device_id, message, created) values($1, $2, $3, $4, CURRENT_TIMESTAMP)`
|
const sql = `INSERT INTO notifications (id, type, device_id, message, created) values($1, $2, $3, $4, CURRENT_TIMESTAMP)`
|
||||||
const direction = tx.direction === "cashOut" ? 'cash-out' : 'cash-in'
|
const direction = tx.direction === "cashOut" ? 'cash-out' : 'cash-in'
|
||||||
|
|
@ -9,4 +18,15 @@ const addHighValueTx = (tx) => {
|
||||||
return db.oneOrNone(sql, [uuidv4(), 'highValueTransaction', tx.deviceId, message])
|
return db.oneOrNone(sql, [uuidv4(), 'highValueTransaction', tx.deviceId, message])
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { machineEvents: dbm.machineEvents, addHighValueTx }
|
const addCashCassetteWarning = (cassetteNumber, deviceId) => {
|
||||||
|
const sql = `INSERT INTO notifications (id, type, detail, device_id, message, created) values($1, $2, $3, $4, $5, CURRENT_TIMESTAMP)`
|
||||||
|
const message = `Cash-out cassette ${cassetteNumber} almost empty!`
|
||||||
|
return db.oneOrNone(sql, [uuidv4(), 'fiatBalance', cassetteNumber, deviceId, message])
|
||||||
|
}
|
||||||
|
|
||||||
|
const getUnreadCassetteNotifications = (cassetteNumber) => {
|
||||||
|
const sql = `SELECT * FROM notifications WHERE read = 'f' AND TYPE = 'fiatBalance' AND detail = '$1'`
|
||||||
|
return db.any(sql, [cassetteNumber])
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { machineEvents: dbm.machineEvents, addHighValueTx, addCashCassetteWarning, getUnreadCassetteNotifications }
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ exports.up = function (next) {
|
||||||
CREATE TABLE IF NOT EXISTS "notifications" (
|
CREATE TABLE IF NOT EXISTS "notifications" (
|
||||||
"id" uuid NOT NULL PRIMARY KEY,
|
"id" uuid NOT NULL PRIMARY KEY,
|
||||||
"type" notification_type NOT NULL,
|
"type" notification_type NOT NULL,
|
||||||
|
"detail" TEXT,
|
||||||
"device_id" TEXT NOT NULL,
|
"device_id" TEXT NOT NULL,
|
||||||
"message" TEXT NOT NULL,
|
"message" TEXT NOT NULL,
|
||||||
"created" time with time zone NOT NULL,
|
"created" time with time zone NOT NULL,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue