feat: allow for cashbox batch editing
This commit is contained in:
parent
21708aa75c
commit
d6d8280a36
5 changed files with 119 additions and 18 deletions
|
|
@ -30,9 +30,14 @@ function getBatches () {
|
||||||
}), res))
|
}), res))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function editBatchById (id, performedBy) {
|
||||||
|
const sql = `UPDATE cashbox_batches SET performed_by=$1 WHERE id=$2`
|
||||||
|
return db.none(sql, [performedBy, id])
|
||||||
|
}
|
||||||
|
|
||||||
function getBillsByBatchId (id) {
|
function getBillsByBatchId (id) {
|
||||||
const sql = `SELECT * FROM bills WHERE cashbox_batch_id=$1`
|
const sql = `SELECT * FROM bills WHERE cashbox_batch_id=$1`
|
||||||
return db.any(sql, [id])
|
return db.any(sql, [id])
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { createCashboxBatch, getBatches, getBillsByBatchId }
|
module.exports = { createCashboxBatch, getBatches, getBillsByBatchId, editBatchById }
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,9 @@ const cashbox = require('../../../cashbox-batches')
|
||||||
const resolvers = {
|
const resolvers = {
|
||||||
Query: {
|
Query: {
|
||||||
cashboxBatches: () => cashbox.getBatches()
|
cashboxBatches: () => cashbox.getBatches()
|
||||||
|
},
|
||||||
|
Mutation: {
|
||||||
|
editBatch: (...[, { id, performedBy }]) => cashbox.editBatchById(id, performedBy)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,10 @@ const typeDef = gql`
|
||||||
type Query {
|
type Query {
|
||||||
cashboxBatches: [CashboxBatch]
|
cashboxBatches: [CashboxBatch]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Mutation {
|
||||||
|
editBatch(id: ID, performedBy: String): CashboxBatch
|
||||||
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
module.exports = typeDef
|
module.exports = typeDef
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,8 @@ import { NumberInput, CashCassetteInput } from 'src/components/inputs/formik'
|
||||||
import TitleSection from 'src/components/layout/TitleSection'
|
import TitleSection from 'src/components/layout/TitleSection'
|
||||||
import { EmptyTable } from 'src/components/table'
|
import { EmptyTable } from 'src/components/table'
|
||||||
import { ReactComponent as EditIcon } from 'src/styling/icons/action/edit/enabled.svg'
|
import { ReactComponent as EditIcon } from 'src/styling/icons/action/edit/enabled.svg'
|
||||||
import { ReactComponent as ReverseListingViewIcon } from 'src/styling/icons/circle buttons/listing-view/white.svg'
|
import { ReactComponent as ReverseHistoryIcon } from 'src/styling/icons/circle buttons/history/white.svg'
|
||||||
import { ReactComponent as ListingViewIcon } from 'src/styling/icons/circle buttons/listing-view/zodiac.svg'
|
import { ReactComponent as HistoryIcon } from 'src/styling/icons/circle buttons/history/zodiac.svg'
|
||||||
import { fromNamespace } from 'src/utils/config'
|
import { fromNamespace } from 'src/utils/config'
|
||||||
|
|
||||||
import styles from './CashCassettes.styles.js'
|
import styles from './CashCassettes.styles.js'
|
||||||
|
|
@ -208,8 +208,8 @@ const CashCassettes = () => {
|
||||||
title="Cash Cassettes"
|
title="Cash Cassettes"
|
||||||
button={{
|
button={{
|
||||||
text: 'Cashbox history',
|
text: 'Cashbox history',
|
||||||
icon: ListingViewIcon,
|
icon: HistoryIcon,
|
||||||
inverseIcon: ReverseListingViewIcon,
|
inverseIcon: ReverseHistoryIcon,
|
||||||
toggle: setShowHistory
|
toggle: setShowHistory
|
||||||
}}
|
}}
|
||||||
iconClassName={classes.listViewButton}
|
iconClassName={classes.listViewButton}
|
||||||
|
|
@ -234,7 +234,9 @@ const CashCassettes = () => {
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{showHistory && <CashboxHistory machines={machines} />}
|
{showHistory && (
|
||||||
|
<CashboxHistory machines={machines} currency={fiatCurrency} />
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<CashCassettesFooter
|
<CashCassettesFooter
|
||||||
currencyCode={fiatCurrency}
|
currencyCode={fiatCurrency}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,16 @@
|
||||||
import { useQuery } from '@apollo/react-hooks'
|
import { useQuery, useMutation } from '@apollo/react-hooks'
|
||||||
import { makeStyles } from '@material-ui/core'
|
import { makeStyles } from '@material-ui/core'
|
||||||
import gql from 'graphql-tag'
|
import gql from 'graphql-tag'
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
import * as R from 'ramda'
|
import * as R from 'ramda'
|
||||||
import React from 'react'
|
import React, { useState } from 'react'
|
||||||
|
import * as Yup from 'yup'
|
||||||
|
|
||||||
|
import { Link, IconButton } from 'src/components/buttons'
|
||||||
|
import { TextInput } from 'src/components/inputs'
|
||||||
import { NumberInput } from 'src/components/inputs/formik'
|
import { NumberInput } from 'src/components/inputs/formik'
|
||||||
import DataTable from 'src/components/tables/DataTable'
|
import DataTable from 'src/components/tables/DataTable'
|
||||||
|
import { ReactComponent as EditIcon } from 'src/styling/icons/action/edit/enabled.svg'
|
||||||
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'
|
||||||
|
|
||||||
|
|
@ -29,6 +33,14 @@ const GET_BATCHES = gql`
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const EDIT_BATCH = gql`
|
||||||
|
mutation editBatch($id: ID, $performedBy: String) {
|
||||||
|
editBatch(id: $id, performedBy: $performedBy) {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
const styles = {
|
const styles = {
|
||||||
operationType: {
|
operationType: {
|
||||||
marginLeft: 8
|
marginLeft: 8
|
||||||
|
|
@ -37,14 +49,31 @@ const styles = {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center'
|
alignItems: 'center'
|
||||||
|
},
|
||||||
|
saveAndCancel: {
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const schema = Yup.object().shape({
|
||||||
|
performedBy: Yup.string().nullable()
|
||||||
|
})
|
||||||
|
|
||||||
const useStyles = makeStyles(styles)
|
const useStyles = makeStyles(styles)
|
||||||
|
|
||||||
const CashboxHistory = ({ machines }) => {
|
const CashboxHistory = ({ machines, currency }) => {
|
||||||
const classes = useStyles()
|
const classes = useStyles()
|
||||||
const { data } = useQuery(GET_BATCHES)
|
const [editing, setEditing] = useState(false)
|
||||||
|
const [error, setError] = useState(false)
|
||||||
|
const [fields, setFields] = useState({})
|
||||||
|
|
||||||
|
const { data, loading } = useQuery(GET_BATCHES)
|
||||||
|
|
||||||
|
const [editBatch] = useMutation(EDIT_BATCH, {
|
||||||
|
refetchQueries: () => ['cashboxBatches']
|
||||||
|
})
|
||||||
|
|
||||||
const batches = R.path(['cashboxBatches'])(data)
|
const batches = R.path(['cashboxBatches'])(data)
|
||||||
|
|
||||||
|
|
@ -81,6 +110,24 @@ const CashboxHistory = ({ machines }) => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const save = row => {
|
||||||
|
schema
|
||||||
|
.isValid(fields)
|
||||||
|
.then(() => {
|
||||||
|
setError(false)
|
||||||
|
editBatch({
|
||||||
|
variables: { id: row.id, performedBy: fields?.performedBy }
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch(setError(true))
|
||||||
|
return close()
|
||||||
|
}
|
||||||
|
|
||||||
|
const close = () => {
|
||||||
|
setFields({})
|
||||||
|
return setEditing(false)
|
||||||
|
}
|
||||||
|
|
||||||
const elements = [
|
const elements = [
|
||||||
{
|
{
|
||||||
name: 'operation',
|
name: 'operation',
|
||||||
|
|
@ -96,7 +143,7 @@ const CashboxHistory = ({ machines }) => {
|
||||||
{
|
{
|
||||||
name: 'machine',
|
name: 'machine',
|
||||||
header: 'Machine',
|
header: 'Machine',
|
||||||
width: 190,
|
width: 200,
|
||||||
textAlign: 'left',
|
textAlign: 'left',
|
||||||
view: it => {
|
view: it => {
|
||||||
return R.find(R.propEq('id', it.deviceId))(machines).name
|
return R.find(R.propEq('id', it.deviceId))(machines).name
|
||||||
|
|
@ -117,9 +164,13 @@ const CashboxHistory = ({ machines }) => {
|
||||||
{
|
{
|
||||||
name: 'total',
|
name: 'total',
|
||||||
header: 'Total',
|
header: 'Total',
|
||||||
width: 125,
|
width: 100,
|
||||||
textAlign: 'right',
|
textAlign: 'right',
|
||||||
view: it => R.sum(R.map(b => R.prop('fiat', b), it.bills))
|
view: it => (
|
||||||
|
<span>
|
||||||
|
{R.sum(R.map(b => R.prop('fiat', b), it.bills))} {currency}
|
||||||
|
</span>
|
||||||
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'date',
|
name: 'date',
|
||||||
|
|
@ -138,22 +189,58 @@ const CashboxHistory = ({ machines }) => {
|
||||||
{
|
{
|
||||||
name: 'performedBy',
|
name: 'performedBy',
|
||||||
header: 'Performed by',
|
header: 'Performed by',
|
||||||
width: 200,
|
width: 190,
|
||||||
textAlign: 'left',
|
textAlign: 'left',
|
||||||
view: it => (R.isNil(it.performedBy) ? 'Unknown entity' : it.performedBy)
|
view: it => {
|
||||||
|
if (!editing)
|
||||||
|
return R.isNil(it.performedBy) ? 'Unknown entity' : it.performedBy
|
||||||
|
return (
|
||||||
|
<TextInput
|
||||||
|
onChange={e =>
|
||||||
|
setFields({ ...fields, performedBy: e.target.value })
|
||||||
|
}
|
||||||
|
error={error}
|
||||||
|
width={190 * 0.85}
|
||||||
|
value={fields.performedBy ?? ''}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '',
|
name: '',
|
||||||
header: 'Edit',
|
header: 'Edit',
|
||||||
width: 120,
|
width: 150,
|
||||||
textAlign: 'right',
|
textAlign: 'right',
|
||||||
view: it => 'aaaaa'
|
view: it => {
|
||||||
|
if (!editing)
|
||||||
|
return (
|
||||||
|
<IconButton
|
||||||
|
onClick={() => {
|
||||||
|
setFields({})
|
||||||
|
setEditing(true)
|
||||||
|
}}>
|
||||||
|
<EditIcon />
|
||||||
|
</IconButton>
|
||||||
|
)
|
||||||
|
return (
|
||||||
|
<div className={classes.saveAndCancel}>
|
||||||
|
<Link type="submit" color="primary" onClick={() => save(it)}>
|
||||||
|
Save
|
||||||
|
</Link>
|
||||||
|
<Link color="secondary" onClick={close}>
|
||||||
|
Cancel
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<DataTable name="cashboxHistory" elements={elements} data={batches} />
|
{!loading && (
|
||||||
|
<DataTable name="cashboxHistory" elements={elements} data={batches} />
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue