diff --git a/lib/cash-out/cash-out-atomic.js b/lib/cash-out/cash-out-atomic.js index f3365123..ea65402f 100644 --- a/lib/cash-out/cash-out-atomic.js +++ b/lib/cash-out/cash-out-atomic.js @@ -9,6 +9,8 @@ const helper = require('./cash-out-helper') const cashOutActions = require('./cash-out-actions') const cashOutLow = require('./cash-out-low') +const notifier = require("../notifier/index") + const toObj = helper.toObj module.exports = {atomic} @@ -122,8 +124,10 @@ function updateCassettes (t, tx) { tx.deviceId ] - return t.one(sql, values) - .then(r => socket.emit(_.assign(r, {op: 'cassetteUpdate', deviceId: tx.deviceId}))) + return t.one(sql, values).then(r => { + notifier.cashCassettesNotify(r, tx.deviceId) + return socket.emit(_.assign(r, {op: 'cassetteUpdate', deviceId: tx.deviceId})) + }) } function wasJustAuthorized (oldTx, newTx, isZeroConf) { diff --git a/lib/machine-loader.js b/lib/machine-loader.js index 6308ea9e..0ccdf277 100644 --- a/lib/machine-loader.js +++ b/lib/machine-loader.js @@ -99,7 +99,10 @@ function renameMachine (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]) } diff --git a/lib/notifier/index.js b/lib/notifier/index.js index 292afdb3..751b9e7a 100644 --- a/lib/notifier/index.js +++ b/lib/notifier/index.js @@ -143,7 +143,7 @@ async function transactionNotify (tx, rec) { const isCashOut = tx.direction === 'cashOut' // high value tx on database - if(highValueTx) { + if(highValueTx && tx.direction === 'cashIn' || highValueTx && tx.direction === 'cashOut' && rec.isRedemption) { queries.addHighValueTx(tx) } @@ -205,10 +205,40 @@ async function sendTransactionMessage(rec, isHighValueTx) { 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 = { transactionNotify, checkNotification, checkPings, checkStuckScreen, - sendRedemptionMessage + sendRedemptionMessage, + cashCassettesNotify } diff --git a/lib/notifier/queries.js b/lib/notifier/queries.js index f7c3d66a..f9f0ea50 100644 --- a/lib/notifier/queries.js +++ b/lib/notifier/queries.js @@ -2,6 +2,15 @@ const dbm = require('../postgresql_interface') const db = require('../db') 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 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' @@ -9,4 +18,15 @@ const addHighValueTx = (tx) => { 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 } diff --git a/migrations/1607009558538-create-notifications-table.js b/migrations/1607009558538-create-notifications-table.js index f90d0b3f..1435119e 100644 --- a/migrations/1607009558538-create-notifications-table.js +++ b/migrations/1607009558538-create-notifications-table.js @@ -21,6 +21,7 @@ exports.up = function (next) { CREATE TABLE IF NOT EXISTS "notifications" ( "id" uuid NOT NULL PRIMARY KEY, "type" notification_type NOT NULL, + "detail" TEXT, "device_id" TEXT NOT NULL, "message" TEXT NOT NULL, "created" time with time zone NOT NULL,