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 promoCodeManager = require('../../promo-codes')
|
||||
const notifierQueries = require('../../notifier/queries')
|
||||
const bills = require('../bills')
|
||||
|
||||
const serverVersion = require('../../../package.json').version
|
||||
const transactions = require('../transactions')
|
||||
|
|
@ -259,6 +260,13 @@ const typeDefs = gql`
|
|||
valid: Boolean
|
||||
}
|
||||
|
||||
type Bills {
|
||||
fiat: Int
|
||||
deviceId: ID
|
||||
created: Date
|
||||
cashbox: Int
|
||||
}
|
||||
|
||||
type Query {
|
||||
countries: [Country]
|
||||
currencies: [Currency]
|
||||
|
|
@ -294,6 +302,7 @@ const typeDefs = gql`
|
|||
notifications: [Notification]
|
||||
alerts: [Notification]
|
||||
hasUnreadNotifications: Boolean
|
||||
bills: [Bills]
|
||||
}
|
||||
|
||||
type SupportLogsResponse {
|
||||
|
|
@ -393,7 +402,8 @@ const resolvers = {
|
|||
fiatRates: () => forex.getFiatRates(),
|
||||
notifications: () => notifierQueries.getNotifications(),
|
||||
hasUnreadNotifications: () => notifierQueries.hasUnreadNotifications(),
|
||||
alerts: () => notifierQueries.getAlerts()
|
||||
alerts: () => notifierQueries.getAlerts(),
|
||||
bills: () => bills.getBills()
|
||||
},
|
||||
Mutation: {
|
||||
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
|
||||
}
|
||||
config
|
||||
bills {
|
||||
fiat
|
||||
deviceId
|
||||
created
|
||||
cashbox
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
|
|
@ -79,14 +85,19 @@ const CashCassettes = () => {
|
|||
const classes = useStyles()
|
||||
|
||||
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, {
|
||||
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 locale = data?.config && fromNamespace('locale')(data.config)
|
||||
const fiatCurrency = locale?.fiatCurrency
|
||||
const machines = R.path(['machines'])(data) ?? []
|
||||
|
||||
const onSave = (...[, { id, cashbox, cassette1, cassette2 }]) => {
|
||||
return setCassetteBills({
|
||||
|
|
@ -99,7 +110,6 @@ const CashCassettes = () => {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
const getCashoutSettings = id => fromNamespace(id)(cashout)
|
||||
const isCashOutDisabled = ({ id }) => !getCashoutSettings(id).active
|
||||
|
||||
|
|
@ -183,7 +193,13 @@ const CashCassettes = () => {
|
|||
<EmptyTable message="No machines so far" />
|
||||
)}
|
||||
</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 * as R from 'ramda'
|
||||
import React from 'react'
|
||||
|
||||
import BigNumber from "bignumber.js"
|
||||
import { Info1, Info2, Info3 } from 'src/components/typography/index'
|
||||
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 { fromNamespace } from 'src/utils/config'
|
||||
|
||||
import styles from './CashCassettesFooter.styles.js'
|
||||
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 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 (
|
||||
<div className={classes.footerContainer}>
|
||||
|
|
@ -27,7 +45,7 @@ const CashCassettesFooter = () => {
|
|||
<Info2 style={{ alignSelf: 'center', marginRight: 8 }}>
|
||||
Cash-in:
|
||||
</Info2>
|
||||
<Info1 style={{ alignSelf: 'center' }}>123123123€</Info1>
|
||||
<Info1 style={{ alignSelf: 'center' }}>{totalInCashBox} {currencyCode}</Info1>
|
||||
</div>
|
||||
<div style={{ display: 'flex' }}>
|
||||
<TxOutIcon
|
||||
|
|
@ -41,11 +59,11 @@ const CashCassettesFooter = () => {
|
|||
<Info2 style={{ alignSelf: 'center', marginRight: 8 }}>
|
||||
Cash-out:
|
||||
</Info2>
|
||||
<Info1 style={{ alignSelf: 'center' }}>123123123€</Info1>
|
||||
<Info1 style={{ alignSelf: 'center' }}>{totalInCassettes} {currencyCode}</Info1>
|
||||
</div>
|
||||
<div style={{ display: 'flex' }}>
|
||||
<Info2 style={{ alignSelf: 'center', marginRight: 8 }}>Total:</Info2>
|
||||
<Info1 style={{ alignSelf: 'center' }}>123123123€</Info1>
|
||||
<Info1 style={{ alignSelf: 'center' }}>{total} {currencyCode}</Info1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ export default {
|
|||
height: 64,
|
||||
backgroundColor: 'white',
|
||||
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