feat: fiat balance alerts to percentages and config migration
This commit is contained in:
parent
0c0133d01c
commit
3de12e3f6e
7 changed files with 95 additions and 38 deletions
|
|
@ -599,7 +599,7 @@ function plugins (settings, deviceId) {
|
||||||
}
|
}
|
||||||
: null
|
: null
|
||||||
|
|
||||||
const cassette1Alert = cashOutEnabled && device.cassette1 < notifications.fiatBalanceCassette1
|
const cassette1Alert = cashOutEnabled && (device.cassette1 / 500) < notifications.fillingPercentageCassette1
|
||||||
? {
|
? {
|
||||||
code: 'LOW_CASH_OUT',
|
code: 'LOW_CASH_OUT',
|
||||||
cassette: 1,
|
cassette: 1,
|
||||||
|
|
@ -611,7 +611,7 @@ function plugins (settings, deviceId) {
|
||||||
}
|
}
|
||||||
: null
|
: null
|
||||||
|
|
||||||
const cassette2Alert = cashOutEnabled && device.cassette2 < notifications.fiatBalanceCassette2
|
const cassette2Alert = cashOutEnabled && (device.cassette2 / 500) < notifications.fillingPercentageCassette2
|
||||||
? {
|
? {
|
||||||
code: 'LOW_CASH_OUT',
|
code: 'LOW_CASH_OUT',
|
||||||
cassette: 2,
|
cassette: 2,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
const _ = require('lodash/fp')
|
||||||
|
const { saveConfig, loadLatest } = require('../lib/new-settings-loader')
|
||||||
|
|
||||||
|
exports.up = function (next) {
|
||||||
|
loadLatest()
|
||||||
|
.then(({ config }) => {
|
||||||
|
const fiatBalance1 = config.notifications_fiatBalanceCassette1
|
||||||
|
const fiatBalance2 = config.notifications_fiatBalanceCassette2
|
||||||
|
|
||||||
|
if (fiatBalance1) {
|
||||||
|
config.notifications_fiatBalanceCassette1 = (100 * (fiatBalance1 / 500)).toFixed(0)
|
||||||
|
}
|
||||||
|
if (fiatBalance2) {
|
||||||
|
config.notifications_fiatBalanceCassette2 = (100 * (fiatBalance2 / 500)).toFixed(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
const {
|
||||||
|
notifications_fiatBalanceCassette1: notifications_fillingPercentageCassette1,
|
||||||
|
notifications_fiatBalanceCassette2: notifications_fillingPercentageCassette2,
|
||||||
|
...rest
|
||||||
|
} = config
|
||||||
|
|
||||||
|
config = { notifications_fillingPercentageCassette1, notifications_fillingPercentageCassette2, ...rest }
|
||||||
|
|
||||||
|
config.notifications_fiatBalanceOverrides = _.map(override => {
|
||||||
|
if (override.fiatBalanceCassette1) {
|
||||||
|
override.fiatBalanceCassette1 = (100 * (override.fiatBalanceCassette1 / 500)).toFixed(0)
|
||||||
|
}
|
||||||
|
if (override.fiatBalanceCassette2) {
|
||||||
|
override.fiatBalanceCassette2 = (100 * (override.fiatBalanceCassette2 / 500)).toFixed(0)
|
||||||
|
}
|
||||||
|
const {
|
||||||
|
fiatBalanceCassette1: fillingPercentageCassette1,
|
||||||
|
fiatBalanceCassette2: fillingPercentageCassette2,
|
||||||
|
...rest } = override
|
||||||
|
return { fillingPercentageCassette1, fillingPercentageCassette2, ...rest }
|
||||||
|
}, config.notifications_fiatBalanceOverrides)
|
||||||
|
|
||||||
|
return saveConfig(config)
|
||||||
|
.then(() => next())
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
if (err.message === 'lamassu-server is not configured') {
|
||||||
|
return next()
|
||||||
|
}
|
||||||
|
console.log(err.message)
|
||||||
|
return next(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
module.exports.down = function (next) {
|
||||||
|
next()
|
||||||
|
}
|
||||||
|
|
@ -18,20 +18,26 @@ const Cashbox = ({
|
||||||
cashOut = false,
|
cashOut = false,
|
||||||
className,
|
className,
|
||||||
emptyPartClassName,
|
emptyPartClassName,
|
||||||
labelClassName
|
labelClassName,
|
||||||
|
inFiatBalanceAlerts
|
||||||
}) => {
|
}) => {
|
||||||
const classes = cashboxClasses({ percent, cashOut })
|
const classes = cashboxClasses({ percent, cashOut })
|
||||||
const threshold = 51
|
const threshold = 51
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classnames(className, classes.cashbox)}>
|
<div
|
||||||
|
className={
|
||||||
|
inFiatBalanceAlerts
|
||||||
|
? classnames(className, classes.fiatBalanceAlertCashbox)
|
||||||
|
: classnames(className, classes.cashbox)
|
||||||
|
}>
|
||||||
<div className={classnames(emptyPartClassName, classes.emptyPart)}>
|
<div className={classnames(emptyPartClassName, classes.emptyPart)}>
|
||||||
{percent <= threshold && (
|
{!inFiatBalanceAlerts && percent <= threshold && (
|
||||||
<Label2 className={labelClassName}>{percent.toFixed(0)}%</Label2>
|
<Label2 className={labelClassName}>{percent.toFixed(0)}%</Label2>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className={classes.fullPart}>
|
<div className={classes.fullPart}>
|
||||||
{percent > threshold && (
|
{!inFiatBalanceAlerts && percent > threshold && (
|
||||||
<Label2 className={labelClassName}>{percent.toFixed(0)}%</Label2>
|
<Label2 className={labelClassName}>{percent.toFixed(0)}%</Label2>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,13 @@ const cashboxStyles = {
|
||||||
textAlign: 'end',
|
textAlign: 'end',
|
||||||
display: 'inline-block'
|
display: 'inline-block'
|
||||||
},
|
},
|
||||||
|
fiatBalanceAlertCashbox: {
|
||||||
|
borderColor: colorPicker,
|
||||||
|
backgroundColor: colorPicker,
|
||||||
|
height: 118,
|
||||||
|
width: 80,
|
||||||
|
border: '4px solid'
|
||||||
|
},
|
||||||
emptyPart: {
|
emptyPart: {
|
||||||
backgroundColor: 'white',
|
backgroundColor: 'white',
|
||||||
height: ({ percent }) => `${100 - percent}%`,
|
height: ({ percent }) => `${100 - percent}%`,
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,7 @@ const Notifications = ({
|
||||||
<Section
|
<Section
|
||||||
title="Fiat balance alerts"
|
title="Fiat balance alerts"
|
||||||
error={error && section === 'fiat'}>
|
error={error && section === 'fiat'}>
|
||||||
<FiatBalanceAlerts section="fiat" max={500} fieldWidth={50} />
|
<FiatBalanceAlerts section="fiat" max={100} fieldWidth={50} />
|
||||||
{displayOverrides && <FiatBalanceOverrides section="fiat" />}
|
{displayOverrides && <FiatBalanceOverrides section="fiat" />}
|
||||||
</Section>
|
</Section>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,7 @@ const useStyles = makeStyles(styles)
|
||||||
|
|
||||||
const NAME = 'fiatBalanceAlerts'
|
const NAME = 'fiatBalanceAlerts'
|
||||||
|
|
||||||
const FiatBalance = ({
|
const FiatBalance = ({ section, min = 0, max = 100, fieldWidth = 80 }) => {
|
||||||
section,
|
|
||||||
min = 0,
|
|
||||||
max = Number.MAX_SAFE_INTEGER,
|
|
||||||
fieldWidth = 80
|
|
||||||
}) => {
|
|
||||||
const { isEditing, isDisabled, setEditing, data, save } = useContext(
|
const { isEditing, isDisabled, setEditing, data, save } = useContext(
|
||||||
NotificationsCtx
|
NotificationsCtx
|
||||||
)
|
)
|
||||||
|
|
@ -32,13 +27,13 @@ const FiatBalance = ({
|
||||||
const editing = isEditing(NAME)
|
const editing = isEditing(NAME)
|
||||||
|
|
||||||
const schema = Yup.object().shape({
|
const schema = Yup.object().shape({
|
||||||
fiatBalanceCassette1: Yup.number()
|
fillingPercentageCassette1: Yup.number()
|
||||||
.transform(transformNumber)
|
.transform(transformNumber)
|
||||||
.integer()
|
.integer()
|
||||||
.min(min)
|
.min(min)
|
||||||
.max(max)
|
.max(max)
|
||||||
.nullable(),
|
.nullable(),
|
||||||
fiatBalanceCassette2: Yup.number()
|
fillingPercentageCassette2: Yup.number()
|
||||||
.transform(transformNumber)
|
.transform(transformNumber)
|
||||||
.integer()
|
.integer()
|
||||||
.min(min)
|
.min(min)
|
||||||
|
|
@ -46,19 +41,14 @@ const FiatBalance = ({
|
||||||
.nullable()
|
.nullable()
|
||||||
})
|
})
|
||||||
|
|
||||||
const fiatBalanceCassette1Percent =
|
|
||||||
(100 * (data?.fiatBalanceCassette1 ?? 0)) / max
|
|
||||||
const fiatBalanceCassette2Percent =
|
|
||||||
(100 * (data?.fiatBalanceCassette2 ?? 0)) / max
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Formik
|
<Formik
|
||||||
validateOnBlur={false}
|
validateOnBlur={false}
|
||||||
validateOnChange={false}
|
validateOnChange={false}
|
||||||
enableReinitialize
|
enableReinitialize
|
||||||
initialValues={{
|
initialValues={{
|
||||||
fiatBalanceCassette1: data?.fiatBalanceCassette1 ?? '',
|
fillingPercentageCassette1: data?.fillingPercentageCassette1 ?? '',
|
||||||
fiatBalanceCassette2: data?.fiatBalanceCassette2 ?? ''
|
fillingPercentageCassette2: data?.fillingPercentageCassette2 ?? ''
|
||||||
}}
|
}}
|
||||||
validationSchema={schema}
|
validationSchema={schema}
|
||||||
onSubmit={it => save(section, schema.cast(it))}
|
onSubmit={it => save(section, schema.cast(it))}
|
||||||
|
|
@ -79,17 +69,18 @@ const FiatBalance = ({
|
||||||
<Cashbox
|
<Cashbox
|
||||||
labelClassName={classes.cashboxLabel}
|
labelClassName={classes.cashboxLabel}
|
||||||
emptyPartClassName={classes.cashboxEmptyPart}
|
emptyPartClassName={classes.cashboxEmptyPart}
|
||||||
percent={fiatBalanceCassette1Percent}
|
percent={data?.fillingPercentageCassette1}
|
||||||
|
inFiatBalanceAlerts={true}
|
||||||
cashOut
|
cashOut
|
||||||
/>
|
/>
|
||||||
<div className={classes.col2}>
|
<div className={classes.col2}>
|
||||||
<TL2 className={classes.title}>Cassette 1 (Top)</TL2>
|
<TL2 className={classes.title}>Cassette 1 (Top)</TL2>
|
||||||
<EditableNumber
|
<EditableNumber
|
||||||
label="Alert me under"
|
label="Alert me under"
|
||||||
name="fiatBalanceCassette1"
|
name="fillingPercentageCassette1"
|
||||||
editing={editing}
|
editing={editing}
|
||||||
displayValue={x => (x === '' ? '-' : x)}
|
displayValue={x => (x === '' ? '-' : x)}
|
||||||
decoration="notes"
|
decoration="%"
|
||||||
width={fieldWidth}
|
width={fieldWidth}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -99,17 +90,18 @@ const FiatBalance = ({
|
||||||
<Cashbox
|
<Cashbox
|
||||||
labelClassName={classes.cashboxLabel}
|
labelClassName={classes.cashboxLabel}
|
||||||
emptyPartClassName={classes.cashboxEmptyPart}
|
emptyPartClassName={classes.cashboxEmptyPart}
|
||||||
percent={fiatBalanceCassette2Percent}
|
percent={data?.fillingPercentageCassette2}
|
||||||
|
inFiatBalanceAlerts={true}
|
||||||
cashOut
|
cashOut
|
||||||
/>
|
/>
|
||||||
<div className={classes.col2}>
|
<div className={classes.col2}>
|
||||||
<TL2 className={classes.title}>Cassette 2 (Bottom)</TL2>
|
<TL2 className={classes.title}>Cassette 2 (Bottom)</TL2>
|
||||||
<EditableNumber
|
<EditableNumber
|
||||||
label="Alert me under"
|
label="Alert me under"
|
||||||
name="fiatBalanceCassette2"
|
name="fillingPercentageCassette2"
|
||||||
editing={editing}
|
editing={editing}
|
||||||
displayValue={x => (x === '' ? '-' : x)}
|
displayValue={x => (x === '' ? '-' : x)}
|
||||||
decoration="notes"
|
decoration="%"
|
||||||
width={fieldWidth}
|
width={fieldWidth}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@ import { transformNumber } from 'src/utils/number'
|
||||||
|
|
||||||
import NotificationsCtx from '../NotificationsContext'
|
import NotificationsCtx from '../NotificationsContext'
|
||||||
|
|
||||||
const CASSETTE_1_KEY = 'fiatBalanceCassette1'
|
const CASSETTE_1_KEY = 'fillingPercentageCassette1'
|
||||||
const CASSETTE_2_KEY = 'fiatBalanceCassette2'
|
const CASSETTE_2_KEY = 'fillingPercentageCassette2'
|
||||||
const MACHINE_KEY = 'machine'
|
const MACHINE_KEY = 'machine'
|
||||||
const NAME = 'fiatBalanceOverrides'
|
const NAME = 'fiatBalanceOverrides'
|
||||||
|
|
||||||
|
|
@ -44,8 +44,8 @@ const FiatBalanceOverrides = ({ section }) => {
|
||||||
[CASSETTE_2_KEY]: ''
|
[CASSETTE_2_KEY]: ''
|
||||||
}
|
}
|
||||||
|
|
||||||
const notesMin = 0
|
const percentMin = 0
|
||||||
const notesMax = 9999999
|
const percentMax = 100
|
||||||
const validationSchema = Yup.object().shape(
|
const validationSchema = Yup.object().shape(
|
||||||
{
|
{
|
||||||
[MACHINE_KEY]: Yup.string()
|
[MACHINE_KEY]: Yup.string()
|
||||||
|
|
@ -60,8 +60,8 @@ const FiatBalanceOverrides = ({ section }) => {
|
||||||
})
|
})
|
||||||
.transform(transformNumber)
|
.transform(transformNumber)
|
||||||
.integer()
|
.integer()
|
||||||
.min(notesMin)
|
.min(percentMin)
|
||||||
.max(notesMax)
|
.max(percentMax)
|
||||||
.nullable(),
|
.nullable(),
|
||||||
[CASSETTE_2_KEY]: Yup.number()
|
[CASSETTE_2_KEY]: Yup.number()
|
||||||
.label('Cassette 2 (bottom)')
|
.label('Cassette 2 (bottom)')
|
||||||
|
|
@ -71,8 +71,8 @@ const FiatBalanceOverrides = ({ section }) => {
|
||||||
})
|
})
|
||||||
.transform(transformNumber)
|
.transform(transformNumber)
|
||||||
.integer()
|
.integer()
|
||||||
.min(notesMin)
|
.min(percentMin)
|
||||||
.max(notesMax)
|
.max(percentMax)
|
||||||
.nullable()
|
.nullable()
|
||||||
},
|
},
|
||||||
[CASSETTE_1_KEY, CASSETTE_2_KEY]
|
[CASSETTE_1_KEY, CASSETTE_2_KEY]
|
||||||
|
|
@ -102,7 +102,7 @@ const FiatBalanceOverrides = ({ section }) => {
|
||||||
doubleHeader: 'Cash-out (Cassette Empty)',
|
doubleHeader: 'Cash-out (Cassette Empty)',
|
||||||
bold: true,
|
bold: true,
|
||||||
input: NumberInput,
|
input: NumberInput,
|
||||||
suffix: 'notes',
|
suffix: '%',
|
||||||
inputProps: {
|
inputProps: {
|
||||||
decimalPlaces: 0
|
decimalPlaces: 0
|
||||||
}
|
}
|
||||||
|
|
@ -115,7 +115,7 @@ const FiatBalanceOverrides = ({ section }) => {
|
||||||
doubleHeader: 'Cash-out (Cassette Empty)',
|
doubleHeader: 'Cash-out (Cassette Empty)',
|
||||||
bold: true,
|
bold: true,
|
||||||
input: NumberInput,
|
input: NumberInput,
|
||||||
suffix: 'notes',
|
suffix: '%',
|
||||||
inputProps: {
|
inputProps: {
|
||||||
decimalPlaces: 0
|
decimalPlaces: 0
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue