Feat: footer calculate cashout total
This commit is contained in:
parent
26aaf0c366
commit
bce45d34e0
5 changed files with 74 additions and 11 deletions
18
lib/new-admin/bills.js
Normal file
18
lib/new-admin/bills.js
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
const db = require('../db')
|
||||||
|
|
||||||
|
// Get all bills with device id
|
||||||
|
const getBills = () => {
|
||||||
|
return db.any(`SELECT d.device_id, b.fiat, b.created, d.cashbox FROM cash_in_txs INNER JOIN bills AS b ON b.cash_in_txs_id = cash_in_txs.id INNER JOIN devices as d ON d.device_id = cash_in_txs.device_id ORDER BY device_id, created DESC`)
|
||||||
|
.then(res => {
|
||||||
|
return res.map(item => ({
|
||||||
|
fiat: item.fiat,
|
||||||
|
deviceId: item.device_id,
|
||||||
|
cashbox: item.cashbox,
|
||||||
|
created: item.created
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
getBills
|
||||||
|
}
|
||||||
|
|
@ -15,6 +15,7 @@ const blacklist = require('../../blacklist')
|
||||||
const machineEventsByIdBatch = require('../../postgresql_interface').machineEventsByIdBatch
|
const machineEventsByIdBatch = require('../../postgresql_interface').machineEventsByIdBatch
|
||||||
const promoCodeManager = require('../../promo-codes')
|
const promoCodeManager = require('../../promo-codes')
|
||||||
const notifierQueries = require('../../notifier/queries')
|
const notifierQueries = require('../../notifier/queries')
|
||||||
|
const bills = require('../bills')
|
||||||
|
|
||||||
const serverVersion = require('../../../package.json').version
|
const serverVersion = require('../../../package.json').version
|
||||||
const transactions = require('../transactions')
|
const transactions = require('../transactions')
|
||||||
|
|
@ -259,6 +260,13 @@ const typeDefs = gql`
|
||||||
valid: Boolean
|
valid: Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Bills {
|
||||||
|
fiat: Int
|
||||||
|
deviceId: ID
|
||||||
|
created: Date
|
||||||
|
cashbox: Int
|
||||||
|
}
|
||||||
|
|
||||||
type Query {
|
type Query {
|
||||||
countries: [Country]
|
countries: [Country]
|
||||||
currencies: [Currency]
|
currencies: [Currency]
|
||||||
|
|
@ -294,6 +302,7 @@ const typeDefs = gql`
|
||||||
notifications: [Notification]
|
notifications: [Notification]
|
||||||
alerts: [Notification]
|
alerts: [Notification]
|
||||||
hasUnreadNotifications: Boolean
|
hasUnreadNotifications: Boolean
|
||||||
|
bills: [Bills]
|
||||||
}
|
}
|
||||||
|
|
||||||
type SupportLogsResponse {
|
type SupportLogsResponse {
|
||||||
|
|
@ -393,7 +402,8 @@ const resolvers = {
|
||||||
fiatRates: () => forex.getFiatRates(),
|
fiatRates: () => forex.getFiatRates(),
|
||||||
notifications: () => notifierQueries.getNotifications(),
|
notifications: () => notifierQueries.getNotifications(),
|
||||||
hasUnreadNotifications: () => notifierQueries.hasUnreadNotifications(),
|
hasUnreadNotifications: () => notifierQueries.hasUnreadNotifications(),
|
||||||
alerts: () => notifierQueries.getAlerts()
|
alerts: () => notifierQueries.getAlerts(),
|
||||||
|
bills: () => bills.getBills()
|
||||||
},
|
},
|
||||||
Mutation: {
|
Mutation: {
|
||||||
machineAction: (...[, { deviceId, action, cashbox, cassette1, cassette2, newName }]) => machineAction({ deviceId, action, cashbox, cassette1, cassette2, newName }),
|
machineAction: (...[, { deviceId, action, cashbox, cassette1, cassette2, newName }]) => machineAction({ deviceId, action, cashbox, cassette1, cassette2, newName }),
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,12 @@ const GET_MACHINES_AND_CONFIG = gql`
|
||||||
cassette2
|
cassette2
|
||||||
}
|
}
|
||||||
config
|
config
|
||||||
|
bills {
|
||||||
|
fiat
|
||||||
|
deviceId
|
||||||
|
created
|
||||||
|
cashbox
|
||||||
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|
@ -79,14 +85,19 @@ const CashCassettes = () => {
|
||||||
const classes = useStyles()
|
const classes = useStyles()
|
||||||
|
|
||||||
const { data } = useQuery(GET_MACHINES_AND_CONFIG)
|
const { data } = useQuery(GET_MACHINES_AND_CONFIG)
|
||||||
|
|
||||||
|
const machines = R.path(['machines'])(data) ?? []
|
||||||
|
const config = R.path(['config'])(data) ?? {}
|
||||||
const [setCassetteBills, { error }] = useMutation(SET_CASSETTE_BILLS, {
|
const [setCassetteBills, { error }] = useMutation(SET_CASSETTE_BILLS, {
|
||||||
refetchQueries: () => ['getData']
|
refetchQueries: () => ['getData']
|
||||||
})
|
})
|
||||||
|
const bills = R.groupBy(bill => bill.deviceId)(R.path(['bills'])(data) ?? [])
|
||||||
|
const deviceIds = R.uniq(
|
||||||
|
R.map(R.prop('deviceId'))(R.path(['bills'])(data) ?? [])
|
||||||
|
)
|
||||||
const cashout = data?.config && fromNamespace('cashOut')(data.config)
|
const cashout = data?.config && fromNamespace('cashOut')(data.config)
|
||||||
const locale = data?.config && fromNamespace('locale')(data.config)
|
const locale = data?.config && fromNamespace('locale')(data.config)
|
||||||
const fiatCurrency = locale?.fiatCurrency
|
const fiatCurrency = locale?.fiatCurrency
|
||||||
const machines = R.path(['machines'])(data) ?? []
|
|
||||||
|
|
||||||
const onSave = (...[, { id, cashbox, cassette1, cassette2 }]) => {
|
const onSave = (...[, { id, cashbox, cassette1, cassette2 }]) => {
|
||||||
return setCassetteBills({
|
return setCassetteBills({
|
||||||
|
|
@ -99,7 +110,6 @@ const CashCassettes = () => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const getCashoutSettings = id => fromNamespace(id)(cashout)
|
const getCashoutSettings = id => fromNamespace(id)(cashout)
|
||||||
const isCashOutDisabled = ({ id }) => !getCashoutSettings(id).active
|
const isCashOutDisabled = ({ id }) => !getCashoutSettings(id).active
|
||||||
|
|
||||||
|
|
@ -183,7 +193,13 @@ const CashCassettes = () => {
|
||||||
<EmptyTable message="No machines so far" />
|
<EmptyTable message="No machines so far" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<CashCassettesFooter />
|
<CashCassettesFooter
|
||||||
|
currencyCode={fiatCurrency}
|
||||||
|
machines={machines}
|
||||||
|
config={config}
|
||||||
|
bills={bills}
|
||||||
|
deviceIds={deviceIds}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,33 @@
|
||||||
|
/*eslint-disable*/
|
||||||
import { makeStyles } from '@material-ui/core'
|
import { makeStyles } from '@material-ui/core'
|
||||||
|
import * as R from 'ramda'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import BigNumber from "bignumber.js"
|
||||||
import { Info1, Info2, Info3 } from 'src/components/typography/index'
|
import { Info1, Info2, Info3 } from 'src/components/typography/index'
|
||||||
import { ReactComponent as TxInIcon } from 'src/styling/icons/direction/cash-in.svg'
|
import { ReactComponent as TxInIcon } from 'src/styling/icons/direction/cash-in.svg'
|
||||||
import { ReactComponent as TxOutIcon } from 'src/styling/icons/direction/cash-out.svg'
|
import { ReactComponent as TxOutIcon } from 'src/styling/icons/direction/cash-out.svg'
|
||||||
|
import { fromNamespace } from 'src/utils/config'
|
||||||
|
|
||||||
import styles from './CashCassettesFooter.styles.js'
|
import styles from './CashCassettesFooter.styles.js'
|
||||||
const useStyles = makeStyles(styles)
|
const useStyles = makeStyles(styles)
|
||||||
|
|
||||||
const CashCassettesFooter = () => {
|
const sortDate = function(a, b) { return new Date(b.created).getTime() - new Date(a.created).getTime()}
|
||||||
|
|
||||||
|
const CashCassettesFooter = ({ machines, config, currencyCode, bills, deviceIds }) => {
|
||||||
const classes = useStyles()
|
const classes = useStyles()
|
||||||
|
const cashout = config && fromNamespace('cashOut')(config)
|
||||||
|
const getCashoutSettings = id => fromNamespace(id)(cashout)
|
||||||
|
const reducerFn = (acc, { cassette1, cassette2, id }) => [
|
||||||
|
(acc[0] += cassette1 * getCashoutSettings(id).top),
|
||||||
|
(acc[1] += cassette2 * getCashoutSettings(id).bottom)
|
||||||
|
]
|
||||||
|
const totalInCassettes = R.sum(R.reduce(reducerFn, [0,0], machines))
|
||||||
|
const totalInCashBox = R.sum(R.flatten(R.map(id => {
|
||||||
|
const sliceIdx = R.path([id, 0, 'cashbox'])(bills) ?? 0
|
||||||
|
return R.map(R.prop('fiat'), R.slice(0, sliceIdx, R.sort(sortDate, bills[id] ?? [])))
|
||||||
|
}, deviceIds)))
|
||||||
|
const total = new BigNumber(totalInCassettes + totalInCashBox).toFormat(0)
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classes.footerContainer}>
|
<div className={classes.footerContainer}>
|
||||||
|
|
@ -27,7 +45,7 @@ const CashCassettesFooter = () => {
|
||||||
<Info2 style={{ alignSelf: 'center', marginRight: 8 }}>
|
<Info2 style={{ alignSelf: 'center', marginRight: 8 }}>
|
||||||
Cash-in:
|
Cash-in:
|
||||||
</Info2>
|
</Info2>
|
||||||
<Info1 style={{ alignSelf: 'center' }}>123123123€</Info1>
|
<Info1 style={{ alignSelf: 'center' }}>{totalInCashBox} {currencyCode}</Info1>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ display: 'flex' }}>
|
<div style={{ display: 'flex' }}>
|
||||||
<TxOutIcon
|
<TxOutIcon
|
||||||
|
|
@ -41,11 +59,11 @@ const CashCassettesFooter = () => {
|
||||||
<Info2 style={{ alignSelf: 'center', marginRight: 8 }}>
|
<Info2 style={{ alignSelf: 'center', marginRight: 8 }}>
|
||||||
Cash-out:
|
Cash-out:
|
||||||
</Info2>
|
</Info2>
|
||||||
<Info1 style={{ alignSelf: 'center' }}>123123123€</Info1>
|
<Info1 style={{ alignSelf: 'center' }}>{totalInCassettes} {currencyCode}</Info1>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ display: 'flex' }}>
|
<div style={{ display: 'flex' }}>
|
||||||
<Info2 style={{ alignSelf: 'center', marginRight: 8 }}>Total:</Info2>
|
<Info2 style={{ alignSelf: 'center', marginRight: 8 }}>Total:</Info2>
|
||||||
<Info1 style={{ alignSelf: 'center' }}>123123123€</Info1>
|
<Info1 style={{ alignSelf: 'center' }}>{total} {currencyCode}</Info1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ export default {
|
||||||
height: 64,
|
height: 64,
|
||||||
backgroundColor: 'white',
|
backgroundColor: 'white',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
justifyContent: 'space-around'
|
justifyContent: 'space-around',
|
||||||
|
boxShadow: [[0, -1, 10, 0, 'rgba(50, 50, 50, 0.1)']]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue