diff --git a/package-lock.json b/package-lock.json index 2b0f556..6a3d54f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,6 +38,11 @@ "integrity": "sha1-PaDM6dbsY3OWS4TzXbfPw996tRQ=", "dev": true }, + "accounting": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/accounting/-/accounting-0.4.1.tgz", + "integrity": "sha1-h91BA+/39EYPHhhvXGd+1s9WaIM=" + }, "accounting-js": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/accounting-js/-/accounting-js-1.1.1.tgz", @@ -1639,6 +1644,11 @@ "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==" }, + "bignumber.js": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-4.1.0.tgz", + "integrity": "sha512-eJzYkFYy9L4JzXsbymsFn3p54D+llV27oTQ+ziJG7WFRheJcNZilgVXMG0LoZtlQSKBsJdWtLFqOD0u+U0jZKA==" + }, "binary": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", @@ -2755,8 +2765,7 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "cosmiconfig": { "version": "2.2.2", @@ -6966,8 +6975,7 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "ini": { "version": "1.3.5", @@ -7442,8 +7450,7 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "isbinaryfile": { "version": "3.0.2", @@ -8479,6 +8486,46 @@ "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", "dev": true }, + "mysql": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.16.0.tgz", + "integrity": "sha512-dPbN2LHonQp7D5ja5DJXNbCLe/HRdu+f3v61aguzNRQIrmZLOeRoymBYyeThrR6ug+FqzDL95Gc9maqZUJS+Gw==", + "requires": { + "bignumber.js": "4.1.0", + "readable-stream": "2.3.6", + "safe-buffer": "5.1.2", + "sqlstring": "2.3.1" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.6", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.2", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "5.1.2" + } + } + } + }, "nan": { "version": "2.9.2", "resolved": "https://registry.npmjs.org/nan/-/nan-2.9.2.tgz", @@ -11246,8 +11293,7 @@ "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "dev": true + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" }, "progress": { "version": "2.0.0", @@ -12697,6 +12743,11 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, + "sqlstring": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", + "integrity": "sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A=" + }, "sshpk": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.1.tgz", @@ -13803,8 +13854,7 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "utila": { "version": "0.4.0", @@ -13875,11 +13925,24 @@ "resolved": "https://registry.npmjs.org/vue/-/vue-2.5.16.tgz", "integrity": "sha512-/ffmsiVuPC8PsWcFkZngdpas19ABm5mh2wA7iDqcltyCTwlgZjHGeJYOXkBMo422iPwIcviOtrTCUpSfXmToLQ==" }, + "vue-currency-filter": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/vue-currency-filter/-/vue-currency-filter-3.2.0.tgz", + "integrity": "sha512-/2e+sreniqWO9UAvnh/WgcJn22r3LEYth/zC6h9f54j6a5KaC0iSeXK0L7sgaPqHviN00+PESqcGDDfnlQaVQg==", + "requires": { + "accounting": "0.4.1" + } + }, "vue-electron": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/vue-electron/-/vue-electron-1.0.6.tgz", "integrity": "sha1-55jgMYC4kzU53v4x+S5TuSQrlAY=" }, + "vue-form-wizard": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/vue-form-wizard/-/vue-form-wizard-0.8.4.tgz", + "integrity": "sha512-/Zk1+B7bz7qHFJ16mwu021lpPXWf/9Tlr2mTNG3J7M0Hdy3rgA802lWsbKYySns0B0qtsD8BYGjQ2Wyxgg+4uw==" + }, "vue-hot-reload-api": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.0.tgz", @@ -14062,6 +14125,14 @@ } } }, + "vue-moment": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/vue-moment/-/vue-moment-4.0.0.tgz", + "integrity": "sha512-lNkEPuA3i3A4q4TDSwOXoRF4Y2vHHdaTOSvpPyGgxoFQP8n4sUh6jU5aJj3FIMlXo5UaHLPIz5hvvpvYx9Wj0w==", + "requires": { + "moment": "2.21.0" + } + }, "vue-numeric": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/vue-numeric/-/vue-numeric-2.3.0.tgz", @@ -14126,6 +14197,11 @@ "resolved": "https://registry.npmjs.org/vuejs-datepicker/-/vuejs-datepicker-0.9.29.tgz", "integrity": "sha512-9zHkUrDudf1Ej+Mkd/BtjE23R+SXU665REK30iOWmreDPXMJk8vqdhVRRHNyPYfCFaEUaDGOgZl0G83xTdwhFw==" }, + "vuelidate": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/vuelidate/-/vuelidate-0.7.4.tgz", + "integrity": "sha512-QHZWYOL325Zo+2K7VBNEJTZ496Kd8Z31p85aQJFldKudUUGBmgw4zu4ghl4CyqPwjRCmqZ9lDdx4FSdMnu4fGg==" + }, "vuex": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/vuex/-/vuex-2.5.0.tgz", diff --git a/package.json b/package.json index a111afa..ff2510b 100644 --- a/package.json +++ b/package.json @@ -26,17 +26,22 @@ "autoprefixer": "^8.1.0", "cssnano": "^3.10.0", "moment": "^2.21.0", + "mysql": "^2.16.0", "postcss-cssnext": "^3.1.0", "postcss-import": "^11.1.0", "postcss-loader": "^2.1.1", "sugarss": "^1.0.1", "vue": "^2.3.3", + "vue-currency-filter": "^3.2.0", "vue-electron": "^1.0.6", + "vue-form-wizard": "^0.8.4", + "vue-moment": "^4.0.0", "vue-numeric": "^2.3.0", "vue-paginate": "^3.5.1", "vue-router": "^2.5.3", "vue2-filters": "^0.3.0", "vuejs-datepicker": "^0.9.29", + "vuelidate": "^0.7.4", "vuex": "^2.3.1" }, "devDependencies": { diff --git a/src/renderer/BarSession.js b/src/renderer/BarSession.js index 93feb78..adc68b1 100644 --- a/src/renderer/BarSession.js +++ b/src/renderer/BarSession.js @@ -1,71 +1,57 @@ -import CashState from './CashState' +import BarSessionType from './BarSessionType' +import CashDrawerContents from './CashDrawerContents' +import SafeContents from './SafeContents' import BarSessionFile from './BarSessionFile' export default class BarSession { - constructor (type, date, file = BarSessionFile.fromTypeAndDate(type, date)) { - this.initialCashState = new CashState() - this.finalCashState = new CashState() - this._effluentCashState = new CashState(false) + constructor () { + this.date = new Date() + this.type = BarSessionType.getDefaultForDate(this.date) + this.originalAuthorName = '' + this.closingAuthorName = '' - this.theoreticalCashRegisterStaffTotal = 0 - this.theoreticalCashRegisterTotal = 0 + this.cashAtStart = new CashDrawerContents() + this.cashAtEnd = new CashDrawerContents() + this.cashToSafe = new SafeContents(this.cashAtEnd) // Serialization note: SafeContents has extra fields - this.theoreticalPinTotal = 0 + this.posDataRetrieved = false + this.posCashTotal = 0.0 + this.posPinTotal = 0.0 + this.posFreeTotal = 0.0 - this.pinTerminalTotal = 0 + this.actualPinTotal = 0.0 - this.type = type - this.date = date - - this.file = file - } - - theoreticalCashRegisterRevenue () { - return this.theoreticalCashRegisterTotal - this.theoreticalCashRegisterStaffTotal - } - - cashDifferenceTotal () { - return this.finalCashState.total() - this.initialCashState.total() - } - - revenueTotal () { - return this.cashDifferenceTotal() + this.pinTerminalTotal + this.file = undefined } - effluentTotal () { - return this.effluentCashState().total() + saveToDisk () { + if (!this.file) { + this.file = BarSessionFile.fromTypeAndDate(this.type, this.date) + } + this.file.store(this) } - changeSafeTotal () { - return this.finalCashState.total() - this.effluentTotal() - } + static fromFile (file, contents) { + const barSession = new BarSession() - effluentCashState () { - let state = new CashState(false) + barSession.date = new Date(contents.date) + barSession.type = BarSessionType.getById(contents.type.id) + barSession.originalAuthorName = contents.originalAuthorName + barSession.closingAuthorName = contents.closingAuthorName - state.author = this.finalCashState.author + barSession.cashAtStart = CashDrawerContents.fromFile(contents.cashAtStart) + barSession.cashAtEnd = CashDrawerContents.fromFile(contents.cashAtEnd) + barSession.cashToSafe = SafeContents.fromFile(barSession.cashAtEnd, contents.cashToSafe) - // Always put all 50 and 100 euro bills in the grey safe - state.bills[0].count = this.finalCashState.bills[0].count - state.bills[1].count = this.finalCashState.bills[1].count + barSession.posDataRetrieved = contents.posDataRetrieved + barSession.posCashTotal = contents.posCashTotal + barSession.posPinTotal = contents.posPinTotal + barSession.posFreeTotal = contents.posFreeTotal - const totalCash = this.finalCashState.total() - this.finalCashState.emergencyCash + barSession.actualPinTotal = contents.actualPinTotal - // Starting with the 20 euro bills, put more in the grey safe until the remainder - // is close to 200 - let nextBill = 2 - while (totalCash - state.total() > 220 && nextBill < state.bills.length) { - state.bills[nextBill].count = Math.min( - this.finalCashState.bills[nextBill].count, - Math.floor((totalCash - state.total() - 200) / state.bills[nextBill].amount) - ) - nextBill++ - } + barSession.file = file - return state - } - - store () { - this.file.store(this) + return barSession } } diff --git a/src/renderer/BarSessionFile.js b/src/renderer/BarSessionFile.js index 404510d..ba24de8 100644 --- a/src/renderer/BarSessionFile.js +++ b/src/renderer/BarSessionFile.js @@ -3,11 +3,10 @@ import fs from 'fs' import path from 'path' import uniqueFilename from 'unique-filename' import BarSession from './BarSession' -import Bill from './Bill' import BarSessionType from './BarSessionType' const userDataPath = path.join(remote.app.getPath('userData')) -const prefix = 'session' +const prefix = 'sessionv2' export default class BarSessionFile { constructor (filePath) { @@ -36,30 +35,7 @@ export default class BarSessionFile { const fileContents = fs.readFileSync(this.filePath, 'utf8') const rawObject = JSON.parse(fileContents) - const date = new Date(rawObject.date) - const type = BarSessionType.getById(rawObject.type.id) - - const barSession = new BarSession(type, date, this) - - barSession.initialCashState.bills = rawObject.initialCashState.bills.map(bill => new Bill(bill.amount, bill.count)) - barSession.initialCashState.author = rawObject.initialCashState.author - barSession.initialCashState.emergencyCash = rawObject.initialCashState.emergencyCash - - barSession.finalCashState.bills = rawObject.finalCashState.bills.map(bill => new Bill(bill.amount, bill.count)) - barSession.finalCashState.author = rawObject.finalCashState.author - barSession.finalCashState.emergencyCash = rawObject.finalCashState.emergencyCash - - barSession._effluentCashState.bills = rawObject._effluentCashState.bills.map(bill => new Bill(bill.amount, bill.count)) - barSession._effluentCashState.author = rawObject._effluentCashState.author - barSession._effluentCashState.emergencyCash = rawObject._effluentCashState.emergencyCash - - barSession.theoreticalCashRegisterStaffTotal = rawObject.theoreticalCashRegisterStaffTotal - barSession.theoreticalCashRegisterTotal = rawObject.theoreticalCashRegisterTotal - barSession.theoreticalPinTotal = rawObject.theoreticalPinTotal - - barSession.pinTerminalTotal = rawObject.pinTerminalTotal - - return barSession + return BarSession.fromFile(this, rawObject) } parseType () { diff --git a/src/renderer/BarSessionType.js b/src/renderer/BarSessionType.js index 341abd2..510e56a 100644 --- a/src/renderer/BarSessionType.js +++ b/src/renderer/BarSessionType.js @@ -1,16 +1,36 @@ -const types = ['EatingOUT', 'Fillum', 'Outsite', 'Vrijdagbar', 'Potterie', 'Overig'] - -export default class BarSessionType { +class BarSessionType { static all () { - return types.map((name, id) => new BarSessionType(id, name)) + return types + } + + static getDefaultForDate (date) { + const type = types.find(type => type.dayOfTheWeek === date.getDay()) + + if (type === undefined) { + return types.find(type => type.dayOfTheWeek === -1) + } + + return type } static getById (id) { - return new BarSessionType(id, types[id]) + return types.find(type => type.id === id) } - constructor (id, name) { + constructor (id, name, dayOfTheWeek = -1) { this.id = id this.name = name + this.dayOfTheWeek = dayOfTheWeek } } + +const types = [ + new BarSessionType(0, 'EatingOUT', 2), + new BarSessionType(1, 'Fillum', 3), + new BarSessionType(2, 'Outsite', 4), + new BarSessionType(3, 'Vrijdagbar', 5), + new BarSessionType(4, 'SHE', 6), + new BarSessionType(5, 'Other') +] + +export default BarSessionType diff --git a/src/renderer/Bill.js b/src/renderer/Bill.js deleted file mode 100644 index 4fd4d29..0000000 --- a/src/renderer/Bill.js +++ /dev/null @@ -1,10 +0,0 @@ -export default class Bill { - constructor (amount, count = 0) { - this.amount = amount - this.count = count - } - - total () { - return this.amount * this.count - } -} diff --git a/src/renderer/CashDrawerContents.js b/src/renderer/CashDrawerContents.js new file mode 100644 index 0000000..ee8c9c2 --- /dev/null +++ b/src/renderer/CashDrawerContents.js @@ -0,0 +1,40 @@ +const billValues = [100, 50, 20, 10, 5, 2, 1, 0.50, 0.20, 0.10, 0.05] + +class Bill { + constructor (amount, count = 0) { + this.amount = amount + this.count = count + } + + total () { + return this.amount * this.count + } +} + +export default class CashDrawerContents { + constructor () { + this.bills = billValues.map(value => new Bill(value)) + this.emergencyCash = 0 + } + + total (includeEmergencyCash = true) { + return this.bills.reduce((sum, current) => sum + current.total(), 0) + (includeEmergencyCash ? this.emergencyCash : 0) + } + + supportsPredictions () { + return false + } + + supportsEmergencyCash () { + return true + } + + static fromFile (json) { + const cashDrawerContents = new CashDrawerContents() + + json.bills.forEach(bill => { cashDrawerContents.bills.find(b => b.amount === bill.amount).count = bill.count }) + this.emergencyCash = json.emergencyCash + + return cashDrawerContents + } +} diff --git a/src/renderer/CashState.js b/src/renderer/CashState.js deleted file mode 100644 index 6be2726..0000000 --- a/src/renderer/CashState.js +++ /dev/null @@ -1,16 +0,0 @@ -import Bill from './Bill' - -const billValues = [100, 50, 20, 10, 5, 2, 1, 0.50, 0.20, 0.10, 0.05] - -export default class CashState { - constructor (editable = true) { - this.bills = billValues.map(value => new Bill(value)) - this.emergencyCash = 0 - this.author = '' - this.editable = editable - } - - total () { - return this.bills.reduce((sum, current) => sum + current.total(), 0) + this.emergencyCash - } -} diff --git a/src/renderer/SafeContents.js b/src/renderer/SafeContents.js new file mode 100644 index 0000000..07e7a79 --- /dev/null +++ b/src/renderer/SafeContents.js @@ -0,0 +1,63 @@ +import CashDrawerContents from './CashDrawerContents' + +const targetAmountCashDrawerContents = 200 + +export default class SafeContents extends CashDrawerContents { + constructor (cashAtEnd) { + super() // needed ? + + this.cashAtEnd = cashAtEnd + this.predicted = false + } + + supportsPredictions () { + return true + } + + supportsEmergencyCash () { + return false + } + + predict (force = false) { + if (this.predicted && !force) return + this.predicted = true + + // Reset all counts of safe bills + this.bills.forEach(b => { b.count = 0 }) + + // Copy array + const endBills = this.cashAtEnd.bills.slice().reverse() + + // Always put 100/50 euro bills in the safe + this.bills.find(b => b.amount === 100).count = endBills.pop().count + this.bills.find(b => b.amount === 50).count = endBills.pop().count + + // Pop bills until there is less than 220 euros in the cash drawer + while (this.remainingCashInDrawer() > targetAmountCashDrawerContents && endBills.length) { + const endBill = endBills.pop() + + const cashAmountThatNeedsToBeRemoved = this.remainingCashInDrawer() - targetAmountCashDrawerContents + + if (cashAmountThatNeedsToBeRemoved < endBill.total()) { + this.bills.find(b => b.amount === endBill.amount).count = Math.floor(cashAmountThatNeedsToBeRemoved / endBill.amount) + } else { + this.bills.find(b => b.amount === endBill.amount).count = endBill.count + } + } + } + + // Add note to UI that this does not include emergency cash + remainingCashInDrawer (includeEmergencyCash = false) { + return this.cashAtEnd.total(includeEmergencyCash) - this.total(false) + } + + static fromFile (cashAtEnd, json) { + const safeContents = new SafeContents(cashAtEnd) + + json.bills.forEach(bill => { safeContents.bills.find(b => b.amount === bill.amount).count = bill.count }) + safeContents.emergencyCash = json.emergencyCash + safeContents.predicted = json.predicted + + return safeContents + } +} diff --git a/src/renderer/Unicenta.js b/src/renderer/Unicenta.js new file mode 100644 index 0000000..d51d321 --- /dev/null +++ b/src/renderer/Unicenta.js @@ -0,0 +1,59 @@ +import mysql from 'mysql' + +export default class Unicenta { + connectAndExecute (action) { + const connection = mysql.createConnection({ + host: '127.0.0.1', + user: 'root', + password: 'admin', + database: 'unicentaopos' + }) + + connection.connect() + const result = action(connection) + connection.end() + + return result + } + + requestRawData (query) { + return this.connectAndExecute(connection => { + return new Promise((resolve, reject) => { + connection.query(query, function (error, results, fields) { + if (error) throw error + resolve(results) + }) + }) + }) + } + + requestTotals () { + return this.requestRawData(` + SELECT closedcash.datestart as start_date, closedcash.dateend as end_date, payments.payment as type, + SUM(payments.TOTAL) AS amount + FROM (SELECT * FROM closedcash WHERE dateend IS NOT NULL ORDER BY dateend DESC LIMIT 1) as closedcash, payments, receipts + WHERE closedcash.money = receipts.money AND payments.receipt = receipts.id + GROUP BY closedcash.host, closedcash.hostsequence, closedcash.money, closedcash.datestart, closedcash.dateend, payments.payment + ORDER BY closedcash.host, closedcash.hostsequence + `).then(results => { + if (results.length === 0) return undefined + + return { + startDate: results[0]['start_date'], + endDate: results[0]['end_date'], + + cashTotal: this.findTotal(results, 'cash'), + pinTotal: this.findTotal(results, 'magcard'), + freeTotal: this.findTotal(results, 'free') + } + }) + } + + findTotal (results, type) { + const result = results.find(result => result.type === type) + + if (result === undefined) return 0.0 + + return result['amount'] + } +} diff --git a/src/renderer/assets/logo.png b/src/renderer/assets/logo.png deleted file mode 100644 index 63736e2..0000000 Binary files a/src/renderer/assets/logo.png and /dev/null differ diff --git a/src/renderer/assets/styles/main.css b/src/renderer/assets/styles/main.css index a872f61..cc67c94 100644 --- a/src/renderer/assets/styles/main.css +++ b/src/renderer/assets/styles/main.css @@ -9,14 +9,36 @@ body { } .form-input { - @apply appearance-none bg-grey-lighter text-grey-darker rounded py-3 px-4 + @apply appearance-none bg-white text-grey-darker rounded py-3 px-4 } - .form-input-disabled { @apply appearance-none bg-grey-lightest text-grey-darker rounded py-3 px-4 } +.form-input-error { + @apply border border-red-dark +} + +.error { + @apply text-red-darker rounded bg-red-lighter mt-2 px-2 py-1 +} + +.help-note { + @apply p-4 mb-2 bg-white rounded shadow text-grey-darkest +} + +.help-note-small { + @apply p-3 text-sm +} + +.help-note-circle { + height: 1.5rem; + width: 1.5rem; + padding-top: 0.1rem; + @apply rounded-full border text-grey-light mr-2 mb-2 text-center font-bold text-sm absolute pin-r pin-b leading-tight border-grey-light +} + input::-webkit-inner-spin-button { /* display: none; <- Crashes Chrome on hover */ -webkit-appearance: none; diff --git a/src/renderer/components/BarSession.vue b/src/renderer/components/BarSession.vue deleted file mode 100644 index 297c050..0000000 --- a/src/renderer/components/BarSession.vue +++ /dev/null @@ -1,120 +0,0 @@ - - - diff --git a/src/renderer/components/BarSessionCashDrawerTicket.vue b/src/renderer/components/BarSessionCashDrawerTicket.vue new file mode 100644 index 0000000..323dad4 --- /dev/null +++ b/src/renderer/components/BarSessionCashDrawerTicket.vue @@ -0,0 +1,37 @@ + + + diff --git a/src/renderer/components/BarSessionCashSpecificationTicket.vue b/src/renderer/components/BarSessionCashSpecificationTicket.vue deleted file mode 100644 index 5e5a15d..0000000 --- a/src/renderer/components/BarSessionCashSpecificationTicket.vue +++ /dev/null @@ -1,68 +0,0 @@ - - - diff --git a/src/renderer/components/BarSessionHome.vue b/src/renderer/components/BarSessionHome.vue index b5c92b2..d53a48d 100644 --- a/src/renderer/components/BarSessionHome.vue +++ b/src/renderer/components/BarSessionHome.vue @@ -1,119 +1,134 @@ \ No newline at end of file diff --git a/src/renderer/components/BarSessionOverview.vue b/src/renderer/components/BarSessionOverview.vue deleted file mode 100644 index 3b8b2d6..0000000 --- a/src/renderer/components/BarSessionOverview.vue +++ /dev/null @@ -1,133 +0,0 @@ - - - - - diff --git a/src/renderer/components/BarSessionPrinter.vue b/src/renderer/components/BarSessionPrinter.vue deleted file mode 100644 index 3b10d2c..0000000 --- a/src/renderer/components/BarSessionPrinter.vue +++ /dev/null @@ -1,30 +0,0 @@ - - - diff --git a/src/renderer/components/BarSessionTicket.vue b/src/renderer/components/BarSessionTicket.vue index 5f5cb5a..6a766fc 100644 --- a/src/renderer/components/BarSessionTicket.vue +++ b/src/renderer/components/BarSessionTicket.vue @@ -1,62 +1,117 @@ diff --git a/src/renderer/components/CashStateForm.vue b/src/renderer/components/CashStateForm.vue deleted file mode 100644 index 19f6e23..0000000 --- a/src/renderer/components/CashStateForm.vue +++ /dev/null @@ -1,73 +0,0 @@ - - - - - diff --git a/src/renderer/components/HelpNote.vue b/src/renderer/components/HelpNote.vue new file mode 100644 index 0000000..9e2f146 --- /dev/null +++ b/src/renderer/components/HelpNote.vue @@ -0,0 +1,6 @@ + \ No newline at end of file diff --git a/src/renderer/components/MoneyInput.vue b/src/renderer/components/MoneyInput.vue index 22d38aa..e00a500 100644 --- a/src/renderer/components/MoneyInput.vue +++ b/src/renderer/components/MoneyInput.vue @@ -1,5 +1,5 @@ diff --git a/src/renderer/components/TopBar.vue b/src/renderer/components/TopBar.vue index 96c9cb8..7da0dc4 100644 --- a/src/renderer/components/TopBar.vue +++ b/src/renderer/components/TopBar.vue @@ -4,7 +4,7 @@
-

Barstaat

+

Cash Register Balance

diff --git a/src/renderer/components/Totals.vue b/src/renderer/components/Totals.vue deleted file mode 100644 index 6ddfb49..0000000 --- a/src/renderer/components/Totals.vue +++ /dev/null @@ -1,99 +0,0 @@ - - - - - diff --git a/src/renderer/components/steps/CashForm.vue b/src/renderer/components/steps/CashForm.vue new file mode 100644 index 0000000..cd22141 --- /dev/null +++ b/src/renderer/components/steps/CashForm.vue @@ -0,0 +1,80 @@ + + + + + \ No newline at end of file diff --git a/src/renderer/components/steps/Close.vue b/src/renderer/components/steps/Close.vue new file mode 100644 index 0000000..be597fc --- /dev/null +++ b/src/renderer/components/steps/Close.vue @@ -0,0 +1,22 @@ + + + diff --git a/src/renderer/components/steps/Review.vue b/src/renderer/components/steps/Review.vue new file mode 100644 index 0000000..d4fdb9f --- /dev/null +++ b/src/renderer/components/steps/Review.vue @@ -0,0 +1,122 @@ + + + diff --git a/src/renderer/components/steps/SessionDetails.vue b/src/renderer/components/steps/SessionDetails.vue new file mode 100644 index 0000000..5d926da --- /dev/null +++ b/src/renderer/components/steps/SessionDetails.vue @@ -0,0 +1,55 @@ + + + diff --git a/src/renderer/components/steps/StartPos.vue b/src/renderer/components/steps/StartPos.vue new file mode 100644 index 0000000..c7b35d9 --- /dev/null +++ b/src/renderer/components/steps/StartPos.vue @@ -0,0 +1,31 @@ + + + diff --git a/src/renderer/components/steps/Totals.vue b/src/renderer/components/steps/Totals.vue new file mode 100644 index 0000000..ef1c78b --- /dev/null +++ b/src/renderer/components/steps/Totals.vue @@ -0,0 +1,121 @@ + + + diff --git a/src/renderer/main.js b/src/renderer/main.js index 68796d7..4825aaa 100644 --- a/src/renderer/main.js +++ b/src/renderer/main.js @@ -4,19 +4,37 @@ import App from './App' import router from './router' import store from './store' -import Vue2Filters from 'vue2-filters' -import VueNumeric from 'vue-numeric' -import VuePaginate from 'vue-paginate' -import moment from 'moment' +// import Vue2Filters from 'vue2-filters' +// import VueNumeric from 'vue-numeric' +// import VuePaginate from 'vue-paginate' +import VueCurrencyFilter from 'vue-currency-filter' +import Vuelidate from 'vuelidate' +import VueMoment from 'vue-moment' +import moment from 'moment' // unused? import { remote } from 'electron' +import HelpNote from './components/HelpNote' + if (!process.env.IS_WEB) Vue.use(require('vue-electron')) Vue.config.productionTip = false -Vue.use(Vue2Filters) -Vue.use(VueNumeric) -Vue.use(VuePaginate) +// Vue.use(Vue2Filters) +// Vue.use(VueNumeric) +// Vue.use(VuePaginate) +Vue.use(Vuelidate) +Vue.use(VueMoment) + +Vue.use(VueCurrencyFilter, { + symbol: '€', + thousandsSeparator: '.', + fractionCount: 2, + fractionSeparator: ',', + symbolPosition: 'front', + symbolSpacing: true +}) + +Vue.component('help-note', HelpNote) /* eslint-disable no-new */ new Vue({ diff --git a/src/renderer/router/index.js b/src/renderer/router/index.js index 161da6e..61c5865 100644 --- a/src/renderer/router/index.js +++ b/src/renderer/router/index.js @@ -10,16 +10,6 @@ export default new Router({ name: 'landing-page', component: require('@/components/BarSessionHome').default }, - { - path: '/overview', - name: 'overview', - component: require('@/components/BarSessionOverview').default - }, - { - path: '/barsession', - name: 'BarSession', - component: require('@/components/BarSession').default - }, { path: '*', redirect: '/' diff --git a/tailwind.js b/tailwind.js index 9d7baac..76ea32d 100644 --- a/tailwind.js +++ b/tailwind.js @@ -305,6 +305,7 @@ module.exports = { 'tight': 1.25, 'normal': 1.5, 'loose': 2, + '24': 6 },