feat: add cashbox batches log downloader
This commit is contained in:
parent
b8ae64a798
commit
f2f34c6ecd
8 changed files with 60 additions and 30 deletions
|
|
@ -47,15 +47,16 @@ function updateMachineWithBatch (machineContext, oldCashboxCount) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBatches () {
|
function getBatches (from = new Date(0).toISOString(), until = new Date().toISOString()) {
|
||||||
const sql = `
|
const sql = `
|
||||||
SELECT cb.id, cb.device_id, cb.created, cb.operation_type, cb.bill_count_override, cb.performed_by, json_agg(b.*) AS bills
|
SELECT cb.id, cb.device_id, cb.created, cb.operation_type, cb.bill_count_override, cb.performed_by, json_agg(b.*) AS bills
|
||||||
FROM cashbox_batches AS cb
|
FROM cashbox_batches AS cb
|
||||||
LEFT JOIN bills AS b ON cb.id = b.cashbox_batch_id
|
LEFT JOIN bills AS b ON cb.id = b.cashbox_batch_id
|
||||||
|
WHERE cb.created >= $1 AND cb.created <= $2
|
||||||
GROUP BY cb.id
|
GROUP BY cb.id
|
||||||
ORDER BY cb.created DESC
|
ORDER BY cb.created DESC
|
||||||
`
|
`
|
||||||
return db.any(sql).then(res => _.map(it => _.mapKeys(ite => _.camelCase(ite), it), res))
|
return db.any(sql, [from, until]).then(res => _.map(it => _.mapKeys(ite => _.camelCase(ite), it), res))
|
||||||
}
|
}
|
||||||
|
|
||||||
function editBatchById (id, performedBy) {
|
function editBatchById (id, performedBy) {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
|
const { parseAsync } = require('json2csv')
|
||||||
const cashbox = require('../../../cashbox-batches')
|
const cashbox = require('../../../cashbox-batches')
|
||||||
|
const logDateFormat = require('../../../logs').logDateFormat
|
||||||
|
|
||||||
const resolvers = {
|
const resolvers = {
|
||||||
Query: {
|
Query: {
|
||||||
cashboxBatches: () => cashbox.getBatches()
|
cashboxBatches: () => cashbox.getBatches(),
|
||||||
|
cashboxBatchesCsv: (...[, { from, until, timezone }]) => cashbox.getBatches(from, until).then(data => parseAsync(logDateFormat(timezone, data, ['created'])))
|
||||||
},
|
},
|
||||||
Mutation: {
|
Mutation: {
|
||||||
createBatch: (...[, { deviceId, cashboxCount }]) => cashbox.createCashboxBatch(deviceId, cashboxCount),
|
createBatch: (...[, { deviceId, cashboxCount }]) => cashbox.createCashboxBatch(deviceId, cashboxCount),
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,13 @@ const typeDef = gql`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Query {
|
type Query {
|
||||||
cashboxBatches: [CashboxBatch]
|
cashboxBatches: [CashboxBatch] @auth
|
||||||
|
cashboxBatchesCsv(from: Date, until: Date, timezone: String): String @auth
|
||||||
}
|
}
|
||||||
|
|
||||||
type Mutation {
|
type Mutation {
|
||||||
createBatch(deviceId: ID, cashboxCount: Int): CashboxBatch
|
createBatch(deviceId: ID, cashboxCount: Int): CashboxBatch @auth
|
||||||
editBatch(id: ID, performedBy: String): CashboxBatch
|
editBatch(id: ID, performedBy: String): CashboxBatch @auth
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,8 @@ const LogsDownloaderPopover = ({
|
||||||
title,
|
title,
|
||||||
getLogs,
|
getLogs,
|
||||||
timezone,
|
timezone,
|
||||||
simplified
|
simplified,
|
||||||
|
className
|
||||||
}) => {
|
}) => {
|
||||||
const [selectedRadio, setSelectedRadio] = useState(ALL)
|
const [selectedRadio, setSelectedRadio] = useState(ALL)
|
||||||
const [selectedAdvancedRadio, setSelectedAdvancedRadio] = useState(ADVANCED)
|
const [selectedAdvancedRadio, setSelectedAdvancedRadio] = useState(ADVANCED)
|
||||||
|
|
@ -245,7 +246,7 @@ const LogsDownloaderPopover = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ClickAwayListener onClickAway={handleClickAway}>
|
<ClickAwayListener onClickAway={handleClickAway}>
|
||||||
<div>
|
<div className={className}>
|
||||||
<FeatureButton
|
<FeatureButton
|
||||||
Icon={Download}
|
Icon={Download}
|
||||||
InverseIcon={DownloadInverseIcon}
|
InverseIcon={DownloadInverseIcon}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { makeStyles, Box } from '@material-ui/core'
|
import { makeStyles, Box } from '@material-ui/core'
|
||||||
import classnames from 'classnames'
|
import classnames from 'classnames'
|
||||||
|
import * as R from 'ramda'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
import ErrorMessage from 'src/components/ErrorMessage'
|
import ErrorMessage from 'src/components/ErrorMessage'
|
||||||
|
|
@ -32,7 +33,10 @@ const TitleSection = ({
|
||||||
)}
|
)}
|
||||||
{buttons.length > 0 && (
|
{buttons.length > 0 && (
|
||||||
<>
|
<>
|
||||||
{buttons.map((button, idx) => (
|
{buttons.map((button, idx) =>
|
||||||
|
!R.isNil(button.component) ? (
|
||||||
|
button.component
|
||||||
|
) : (
|
||||||
<SubpageButton
|
<SubpageButton
|
||||||
key={idx}
|
key={idx}
|
||||||
className={classes.subpageButton}
|
className={classes.subpageButton}
|
||||||
|
|
@ -42,7 +46,8 @@ const TitleSection = ({
|
||||||
forceDisable={button.forceDisable}>
|
forceDisable={button.forceDisable}>
|
||||||
<Info1 className={classes.buttonText}>{button.text}</Info1>
|
<Info1 className={classes.buttonText}>{button.text}</Info1>
|
||||||
</SubpageButton>
|
</SubpageButton>
|
||||||
))}
|
)
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import * as R from 'ramda'
|
||||||
import React, { useState } from 'react'
|
import React, { useState } from 'react'
|
||||||
import * as Yup from 'yup'
|
import * as Yup from 'yup'
|
||||||
|
|
||||||
|
import LogsDowloaderPopover from 'src/components/LogsDownloaderPopper'
|
||||||
import Modal from 'src/components/Modal'
|
import Modal from 'src/components/Modal'
|
||||||
import { IconButton, Button } from 'src/components/buttons'
|
import { IconButton, Button } from 'src/components/buttons'
|
||||||
import { Table as EditableTable } from 'src/components/editableTable'
|
import { Table as EditableTable } from 'src/components/editableTable'
|
||||||
|
|
@ -147,6 +148,12 @@ const SET_CASSETTE_BILLS = gql`
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const GET_BATCHES_CSV = gql`
|
||||||
|
query cashboxBatchesCsv($from: Date, $until: Date, $timezone: String) {
|
||||||
|
cashboxBatchesCsv(from: $from, until: $until, timezone: $timezone)
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
const CashCassettes = () => {
|
const CashCassettes = () => {
|
||||||
const classes = useStyles()
|
const classes = useStyles()
|
||||||
const [showHistory, setShowHistory] = useState(false)
|
const [showHistory, setShowHistory] = useState(false)
|
||||||
|
|
@ -175,6 +182,8 @@ const CashCassettes = () => {
|
||||||
refetchQueries: () => ['getData']
|
refetchQueries: () => ['getData']
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const timezone = R.path(['config', 'locale_timezone'], data)
|
||||||
|
|
||||||
const bills = R.groupBy(bill => bill.deviceId)(R.path(['bills'])(data) ?? [])
|
const bills = R.groupBy(bill => bill.deviceId)(R.path(['bills'])(data) ?? [])
|
||||||
const deviceIds = R.uniq(
|
const deviceIds = R.uniq(
|
||||||
R.map(R.prop('deviceId'))(R.path(['bills'])(data) ?? [])
|
R.map(R.prop('deviceId'))(R.path(['bills'])(data) ?? [])
|
||||||
|
|
@ -317,6 +326,21 @@ const CashCassettes = () => {
|
||||||
icon: HistoryIcon,
|
icon: HistoryIcon,
|
||||||
inverseIcon: ReverseHistoryIcon,
|
inverseIcon: ReverseHistoryIcon,
|
||||||
toggle: setShowHistory
|
toggle: setShowHistory
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: showHistory ? (
|
||||||
|
<LogsDowloaderPopover
|
||||||
|
className={classes.downloadLogsButton}
|
||||||
|
title="Download logs"
|
||||||
|
name="cashboxHistory"
|
||||||
|
query={GET_BATCHES_CSV}
|
||||||
|
getLogs={logs => R.path(['cashboxBatchesCsv'])(logs)}
|
||||||
|
timezone={timezone}
|
||||||
|
args={{ timezone }}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
iconClassName={classes.listViewButton}
|
iconClassName={classes.listViewButton}
|
||||||
|
|
@ -364,6 +388,7 @@ const CashCassettes = () => {
|
||||||
<CashboxHistory
|
<CashboxHistory
|
||||||
machines={R.concat(machines, unpairedMachines)}
|
machines={R.concat(machines, unpairedMachines)}
|
||||||
currency={fiatCurrency}
|
currency={fiatCurrency}
|
||||||
|
timezone={timezone}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<CashCassettesFooter
|
<CashCassettesFooter
|
||||||
|
|
|
||||||
|
|
@ -23,5 +23,8 @@ export default {
|
||||||
},
|
},
|
||||||
selection: {
|
selection: {
|
||||||
marginRight: 12
|
marginRight: 12
|
||||||
|
},
|
||||||
|
downloadLogsButton: {
|
||||||
|
marginLeft: 13
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,12 +41,6 @@ const GET_BATCHES = gql`
|
||||||
}
|
}
|
||||||
` */
|
` */
|
||||||
|
|
||||||
const GET_DATA = gql`
|
|
||||||
query getData {
|
|
||||||
config
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const styles = {
|
const styles = {
|
||||||
operationType: {
|
operationType: {
|
||||||
marginLeft: 8
|
marginLeft: 8
|
||||||
|
|
@ -69,7 +63,7 @@ const styles = {
|
||||||
|
|
||||||
const useStyles = makeStyles(styles)
|
const useStyles = makeStyles(styles)
|
||||||
|
|
||||||
const CashboxHistory = ({ machines, currency }) => {
|
const CashboxHistory = ({ machines, currency, timezone }) => {
|
||||||
const classes = useStyles()
|
const classes = useStyles()
|
||||||
|
|
||||||
/* const [error, setError] = useState(false)
|
/* const [error, setError] = useState(false)
|
||||||
|
|
@ -82,10 +76,7 @@ const CashboxHistory = ({ machines, currency }) => {
|
||||||
refetchQueries: () => ['cashboxBatches']
|
refetchQueries: () => ['cashboxBatches']
|
||||||
}) */
|
}) */
|
||||||
|
|
||||||
const { data: configData, loading: configLoading } = useQuery(GET_DATA)
|
const loading = batchesLoading
|
||||||
const timezone = R.path(['config', 'locale_timezone'], configData)
|
|
||||||
|
|
||||||
const loading = batchesLoading || configLoading
|
|
||||||
|
|
||||||
const batches = R.path(['cashboxBatches'])(batchesData)
|
const batches = R.path(['cashboxBatches'])(batchesData)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue