From 21708aa75cadc3cd39b12b82cb3f97a62cb0efeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Salgado?= Date: Mon, 12 Apr 2021 01:53:11 +0100 Subject: [PATCH] feat: cashbox history tab feat: add information fields to cashbox_batches table --- lib/cashbox-batches.js | 22 ++- .../graphql/resolvers/cashbox.resolver.js | 9 + lib/new-admin/graphql/resolvers/index.js | 2 + lib/new-admin/graphql/types/cashbox.type.js | 19 +++ lib/new-admin/graphql/types/index.js | 2 + migrations/1617967601902-add-batches-type.js | 21 +++ .../src/pages/Maintenance/CashCassettes.js | 44 +++-- .../src/pages/Maintenance/CashboxHistory.js | 161 ++++++++++++++++++ 8 files changed, 267 insertions(+), 13 deletions(-) create mode 100644 lib/new-admin/graphql/resolvers/cashbox.resolver.js create mode 100644 lib/new-admin/graphql/types/cashbox.type.js create mode 100644 migrations/1617967601902-add-batches-type.js create mode 100644 new-lamassu-admin/src/pages/Maintenance/CashboxHistory.js diff --git a/lib/cashbox-batches.js b/lib/cashbox-batches.js index 8c2604e9..e9693d97 100644 --- a/lib/cashbox-batches.js +++ b/lib/cashbox-batches.js @@ -1,4 +1,5 @@ const db = require('./db') +const _ = require('lodash/fp') function createCashboxBatch (rec) { const sql = 'INSERT INTO cashbox_batches (device_id, created) VALUES ($1, now()) RETURNING *' @@ -15,4 +16,23 @@ function createCashboxBatch (rec) { }) } -module.exports = { createCashboxBatch } +function getBatches () { + 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 FROM cashbox_batches cb LEFT JOIN bills b ON cb.id=b.cashbox_batch_id GROUP BY cb.id` + return db.any(sql).then(res => _.map(it => ({ + id: it.id, + deviceId: it.device_id, + created: it.created, + operationType: it.operation_type, + billCountOverride: it.bill_count_override, + performedBy: it.performed_by, + bills: it.bills + }), res)) +} + +function getBillsByBatchId (id) { + const sql = `SELECT * FROM bills WHERE cashbox_batch_id=$1` + return db.any(sql, [id]) +} + +module.exports = { createCashboxBatch, getBatches, getBillsByBatchId } diff --git a/lib/new-admin/graphql/resolvers/cashbox.resolver.js b/lib/new-admin/graphql/resolvers/cashbox.resolver.js new file mode 100644 index 00000000..55584817 --- /dev/null +++ b/lib/new-admin/graphql/resolvers/cashbox.resolver.js @@ -0,0 +1,9 @@ +const cashbox = require('../../../cashbox-batches') + +const resolvers = { + Query: { + cashboxBatches: () => cashbox.getBatches() + } +} + +module.exports = resolvers diff --git a/lib/new-admin/graphql/resolvers/index.js b/lib/new-admin/graphql/resolvers/index.js index 60ed22c0..cbea1123 100644 --- a/lib/new-admin/graphql/resolvers/index.js +++ b/lib/new-admin/graphql/resolvers/index.js @@ -2,6 +2,7 @@ const { mergeResolvers } = require('@graphql-tools/merge') const bill = require('./bill.resolver') const blacklist = require('./blacklist.resolver') +const cashbox = require('./cashbox.resolver') const config = require('./config.resolver') const currency = require('./currency.resolver') const customer = require('./customer.resolver') @@ -22,6 +23,7 @@ const version = require('./version.resolver') const resolvers = [ bill, blacklist, + cashbox, config, currency, customer, diff --git a/lib/new-admin/graphql/types/cashbox.type.js b/lib/new-admin/graphql/types/cashbox.type.js new file mode 100644 index 00000000..82a66c30 --- /dev/null +++ b/lib/new-admin/graphql/types/cashbox.type.js @@ -0,0 +1,19 @@ +const { gql } = require('apollo-server-express') + +const typeDef = gql` + type CashboxBatch { + id: ID + deviceId: ID + created: Date + operationType: String + customBillCount: Int + performedBy: String + bills: [Bill] + } + + type Query { + cashboxBatches: [CashboxBatch] + } +` + +module.exports = typeDef diff --git a/lib/new-admin/graphql/types/index.js b/lib/new-admin/graphql/types/index.js index 390e5924..0d60c2ba 100644 --- a/lib/new-admin/graphql/types/index.js +++ b/lib/new-admin/graphql/types/index.js @@ -2,6 +2,7 @@ const { mergeTypeDefs } = require('@graphql-tools/merge') const bill = require('./bill.type') const blacklist = require('./blacklist.type') +const cashbox = require('./cashbox.type') const config = require('./config.type') const currency = require('./currency.type') const customer = require('./customer.type') @@ -22,6 +23,7 @@ const version = require('./version.type') const types = [ bill, blacklist, + cashbox, config, currency, customer, diff --git a/migrations/1617967601902-add-batches-type.js b/migrations/1617967601902-add-batches-type.js new file mode 100644 index 00000000..30989271 --- /dev/null +++ b/migrations/1617967601902-add-batches-type.js @@ -0,0 +1,21 @@ +var db = require('./db') + +exports.up = function (next) { + var sqls = [ + `CREATE TYPE cashbox_batch_type AS ENUM( + 'cash-in-empty', + 'cash-out-1-refill', + 'cash-out-1-empty', + 'cash-out-2-refill', + 'cash-out-2-empty' + )`, + `ALTER TABLE cashbox_batches ADD COLUMN operation_type cashbox_batch_type NOT NULL`, + `ALTER TABLE cashbox_batches ADD COLUMN bill_count_override SMALLINT`, + `ALTER TABLE cashbox_batches ADD COLUMN performed_by VARCHAR(64)` + ] + db.multi(sqls, next) +} + +exports.down = function (next) { + next() +} diff --git a/new-lamassu-admin/src/pages/Maintenance/CashCassettes.js b/new-lamassu-admin/src/pages/Maintenance/CashCassettes.js index a0732a3b..7d71f352 100644 --- a/new-lamassu-admin/src/pages/Maintenance/CashCassettes.js +++ b/new-lamassu-admin/src/pages/Maintenance/CashCassettes.js @@ -12,10 +12,13 @@ import { NumberInput, CashCassetteInput } from 'src/components/inputs/formik' import TitleSection from 'src/components/layout/TitleSection' import { EmptyTable } from 'src/components/table' 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 ListingViewIcon } from 'src/styling/icons/circle buttons/listing-view/zodiac.svg' import { fromNamespace } from 'src/utils/config' import styles from './CashCassettes.styles.js' import CashCassettesFooter from './CashCassettesFooter' +import CashboxHistory from './CashboxHistory' import Wizard from './Wizard/Wizard' const useStyles = makeStyles(styles) @@ -90,6 +93,7 @@ const SET_CASSETTE_BILLS = gql` const CashCassettes = () => { const classes = useStyles() + const [showHistory, setShowHistory] = useState(false) const { data } = useQuery(GET_MACHINES_AND_CONFIG) const [wizard, setWizard] = useState(false) @@ -200,21 +204,37 @@ const CashCassettes = () => { return ( <> - +
- + {!showHistory && ( + <> + - {data && R.isEmpty(machines) && ( - + {data && R.isEmpty(machines) && ( + + )} + )} + {showHistory && }
{ + const classes = useStyles() + const { data } = useQuery(GET_BATCHES) + + const batches = R.path(['cashboxBatches'])(data) + + const getOperationRender = { + 'cash-in-empty': ( + <> + + Cash-in emptied + + ), + 'cash-out-1-refill': ( + <> + + Cash-out 1 refill + + ), + 'cash-out-1-empty': ( + <> + + Cash-out 1 emptied + + ), + 'cash-out-2-refill': ( + <> + + Cash-out 2 refill + + ), + 'cash-out-2-empty': ( + <> + + Cash-out 2 emptied + + ) + } + + const elements = [ + { + name: 'operation', + header: 'Operation', + width: 200, + textAlign: 'left', + view: it => ( +
+ {getOperationRender[it.operationType]} +
+ ) + }, + { + name: 'machine', + header: 'Machine', + width: 190, + textAlign: 'left', + view: it => { + return R.find(R.propEq('id', it.deviceId))(machines).name + } + }, + { + name: 'billCount', + header: 'Bill Count', + width: 115, + textAlign: 'left', + input: NumberInput, + inputProps: { + decimalPlaces: 0 + }, + view: it => + R.isNil(it.customBillCount) ? it.bills.length : it.customBillCount + }, + { + name: 'total', + header: 'Total', + width: 125, + textAlign: 'right', + view: it => R.sum(R.map(b => R.prop('fiat', b), it.bills)) + }, + { + name: 'date', + header: 'Date', + width: 125, + textAlign: 'right', + view: it => moment.utc(it.created).format('YYYY-MM-DD') + }, + { + name: 'time', + header: 'Time (h:m)', + width: 125, + textAlign: 'right', + view: it => moment.utc(it.created).format('HH:mm') + }, + { + name: 'performedBy', + header: 'Performed by', + width: 200, + textAlign: 'left', + view: it => (R.isNil(it.performedBy) ? 'Unknown entity' : it.performedBy) + }, + { + name: '', + header: 'Edit', + width: 120, + textAlign: 'right', + view: it => 'aaaaa' + } + ] + + return ( + <> + + + ) +} + +export default CashboxHistory