diff --git a/client/wrap.html b/client/wrap.html new file mode 100644 index 0000000..93b3de1 --- /dev/null +++ b/client/wrap.html @@ -0,0 +1,45 @@ + + + + + + chikin wrap 0.1 + + + + + + + + + + + + + + + +
+
+
+
+
+ + + diff --git a/client/wrap.js b/client/wrap.js new file mode 100644 index 0000000..5f9436e --- /dev/null +++ b/client/wrap.js @@ -0,0 +1,102 @@ +const config = 'dev'; +const backend_api = { + 'prod': '/zetikettes/srv/', + 'dev': 'http://scrawny.local:3000', +}[config]; + +const token = localStorage.getItem('token'); + +async function getBandz() { + const uri = `${backend_api}/bandz`; + const res = await $.ajax(uri, {headers: {Authorization: `Bearer ${token}`}}); + return res.bandz; +} + +async function wrapAChikin(req) { + const uri = `${backend_api}/wrap`; + const res = await $.ajax(uri, { + type: 'POST', + contentType: 'application/json', + data: JSON.stringify(req), + headers: {Authorization: `Bearer ${token}`}, + }); + return res.chikinId; +} + +function printLabel(chikinId) { + const uri = `${backend_api}/print`; + $.ajax(uri, { + type: 'POST', + contentType: 'application/json', + data: JSON.stringify({chikinId}), + headers: {Authorization: `Bearer ${token}`}, + }); +} + +$(document).ready(() => { + const appbody = $("#appbody"); + + const bandSelect = $('
') + .append( + $('') + .append('') + ); + + const loader = $('
') + .hide(); + + const action = $('
') + .append( + $('wrap-a-chikinsend') + .click(async () => { + loader.show(); + $('.btn').addClass("disabled"); + + const req = { + bandId: $('select').val(), + wrapDate: $('.datepicker').val(), + weight: $('#weight').val(), + }; + + try { + const chikinId = await wrapAChikin(req); + printLabel(chikinId); + } finally { + loader.hide(); + $('#weight').val(''); + $('.btn').removeClass('disabled'); + } + }) + ); + + block + .append( + $('
') + .append('') + .append('') + ) + .append( + $('
') + .append(action) + .append(loader) + ) + ; + appbody.append(block); + + getBandz().then(bandz => { + $('select').append(bandz.map(band => ``)); + $('select').formSelect(); + }); + + $('select').formSelect(); + $('.datepicker').datepicker({setDefaultDate: true, defaultDate: new Date()}); +}); diff --git a/index.js b/index.js index 031e634..710d9a7 100644 --- a/index.js +++ b/index.js @@ -1,4 +1,6 @@ const bodyParser = require('body-parser'); +const child_process = require('child_process'); +const cors = require('cors'); const express = require('express'); require('express-async-errors'); const jwt = require('jsonwebtoken'); @@ -28,9 +30,9 @@ CREATE TABLE IF NOT EXISTS Chikinz ( id INTEGER PRIMARY KEY AUTOINCREMENT, bandId INTEGER NOT NULL, weight REAL NOT NULL, - killedDate DATE, - wrappedDate DATE NOT NULL, - soldDate DATE, + killDate DATE, + wrapDate DATE NOT NULL, + sellDate DATE, misc TEXT );`); @@ -38,17 +40,15 @@ makeTable(` CREATE TABLE IF NOT EXISTS Bandz ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, - receivedDate DATE, + receiveDate DATE, misc TEXT );`); -const app = express(); - function addChikin(db, chikin) { - const sql_insert = 'INSERT INTO Chikinz (bandId, weight, killedDate, wrappedDate) VALUES (?, ?, ?, ?);'; - const {bandId, weight, killedDate, wrappedDate} = chikin; + const sql_insert = 'INSERT INTO Chikinz (bandId, weight, killDate, wrapDate) VALUES (?, ?, ?, ?);'; + const {bandId, weight, killDate, wrapDate} = chikin; return new Promise((resolve, reject) => { - db.run(sql_insert, [bandId, weight, killedDate, wrappedDate], function(err) { + db.run(sql_insert, [bandId, weight, killDate, wrapDate], function(err) { if (err) { return reject(err); } @@ -74,6 +74,17 @@ function getBandz(db) { }); } +function getChikin(db, chikinId) { + return new Promise((resolve, reject) => { + db.get('SELECT * from Chikinz where id=?', chikinId, (err, row) => { + if (err) { + return reject(err); + } + resolve(row); + }); + }); +} + const authenticateJWT = (req, res, next) => { const authHeader = req.headers.authorization; @@ -98,7 +109,10 @@ const authenticateJWT = (req, res, next) => { } }; +const app = express(); + app.use(bodyParser.json()); +app.use(cors()); app.listen(3000, () => { console.log('Server started (http://localhost:3000/)!'); @@ -118,7 +132,6 @@ app.get('/bandz', authenticateJWT, async (req, res) => { app.post('/toktok', (req, res) => { const {password} = req.body; - console.log(req.body); if (password != 'goldchocoboisbestchocobo.goldchocoboisonlychocobo') { return res.json({message: 'This is not the way.'}); @@ -134,9 +147,30 @@ app.post('/wrap', authenticateJWT, async (req, res) => { const chikin = req.body; console.log(chikin); const {lastID} = await addChikin(db, chikin); - res.json({message: 'This is the way.', id: lastID}); + res.json({message: 'This is the way.', chikinId: lastID}); }); +app.post('/print', authenticateJWT, async (req, res) => { + const {chikinId} = req.body; + + const qr_url = `http://lafermedumalpas.fr/chikinz/${chikinId}`; + const chikin = await getChikin(db, chikinId); + const line0 = 'Poulet fermier bio'; + const line1 = `${chikin.weight.toFixed(2)} kg`; + + const pricePerKg = 12; + const price = chikin.weight * pricePerKg; + const line2 = `${pricePerKg.toFixed(2)} €/kg - ${price.toFixed(2)}`; + + const args = ['/Users/paul/scratch/printer/catprint.py', + '--template0', [qr_url, line0, line1, line2].join(';')]; + + const proc = child_process.spawn('python', args); + proc.stdout.on('data', data => console.log(`stdout: ${data}`)); + proc.stderr.on('data', data => console.log(`stderr: ${data}`)); + + res.json({message: 'This is the way.'}); +}); // catch errors diff --git a/package.json b/package.json index f48ff05..b998523 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "author": "Paul Mathieu ", "license": "MIT", "dependencies": { + "cors": "^2.8.5", "express": "^4.18.1", "express-async-errors": "^3.1.1", "jsonwebtoken": "^8.5.1", diff --git a/yarn.lock b/yarn.lock index 5bf9b12..9e6815d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -266,6 +266,14 @@ cookie@0.5.0: resolved "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz" integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== +cors@^2.8.5: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + debug@2.6.9: version "2.6.9" resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" @@ -980,7 +988,7 @@ npmlog@^6.0.0: gauge "^4.0.3" set-blocking "^2.0.0" -object-assign@^4.1.1: +object-assign@^4, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== @@ -1352,7 +1360,7 @@ utils-merge@1.0.1: resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== -vary@~1.1.2: +vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==