From bf2d7541a5c956ba48a7f9a8c31553f36ce74418 Mon Sep 17 00:00:00 2001 From: guillermo Date: Mon, 21 Oct 2024 14:57:55 +0200 Subject: [PATCH] feat: refs #7266 Item label QR --- db/dump/.dump/data.sql | 2 +- loopback/locale/es.json | 4 +- .../item/{labelPdf.js => itemLabelQr.js} | 27 ++--- modules/item/back/models/item.js | 2 +- .../assets/css/import.js | 0 .../item-label-qr/assets/css/style.css | 87 ++++++++++++++ .../reports/item-label-qr/item-label-qr.html | 112 ++++++++++++++++++ .../reports/item-label-qr/item-label-qr.js | 43 +++++++ .../reports/item-label-qr/locale/es.yml | 1 + .../options.json | 2 +- .../reports/item-label-qr/sql/item.sql | 42 +++++++ .../reports/item-label/assets/css/style.css | 37 ------ .../reports/item-label/item-label.html | 37 ------ .../reports/item-label/item-label.js | 58 --------- .../reports/item-label/locale/es.yml | 1 - .../templates/reports/item-label/sql/item.sql | 14 --- .../reports/item-label/sql/itemTags.sql | 4 - 17 files changed, 298 insertions(+), 175 deletions(-) rename modules/item/back/methods/item/{labelPdf.js => itemLabelQr.js} (62%) rename print/templates/reports/{item-label => item-label-qr}/assets/css/import.js (100%) create mode 100644 print/templates/reports/item-label-qr/assets/css/style.css create mode 100644 print/templates/reports/item-label-qr/item-label-qr.html create mode 100755 print/templates/reports/item-label-qr/item-label-qr.js create mode 100644 print/templates/reports/item-label-qr/locale/es.yml rename print/templates/reports/{item-label => item-label-qr}/options.json (86%) create mode 100644 print/templates/reports/item-label-qr/sql/item.sql delete mode 100644 print/templates/reports/item-label/assets/css/style.css delete mode 100644 print/templates/reports/item-label/item-label.html delete mode 100755 print/templates/reports/item-label/item-label.js delete mode 100644 print/templates/reports/item-label/locale/es.yml delete mode 100644 print/templates/reports/item-label/sql/item.sql delete mode 100644 print/templates/reports/item-label/sql/itemTags.sql diff --git a/db/dump/.dump/data.sql b/db/dump/.dump/data.sql index ca254055b..315bfe7c5 100644 --- a/db/dump/.dump/data.sql +++ b/db/dump/.dump/data.sql @@ -1723,7 +1723,7 @@ INSERT INTO `ACL` VALUES (378,'OsTicket','osTicketReportEmail','WRITE','ALLOW',' INSERT INTO `ACL` VALUES (379,'Item','buyerWasteEmail','WRITE','ALLOW','ROLE','system',NULL); INSERT INTO `ACL` VALUES (380,'Claim','claimPickupPdf','READ','ALLOW','ROLE','employee',NULL); INSERT INTO `ACL` VALUES (381,'Claim','claimPickupEmail','WRITE','ALLOW','ROLE','claimManager',NULL); -INSERT INTO `ACL` VALUES (382,'Item','labelPdf','READ','ALLOW','ROLE','employee',NULL); +INSERT INTO `ACL` VALUES (382,'Item','itemLabelQr','READ','ALLOW','ROLE','employee',NULL); INSERT INTO `ACL` VALUES (383,'Sector','*','READ','ALLOW','ROLE','employee',NULL); INSERT INTO `ACL` VALUES (384,'Sector','*','WRITE','ALLOW','ROLE','employee',NULL); INSERT INTO `ACL` VALUES (385,'Route','driverRoutePdf','READ','ALLOW','ROLE','employee',NULL); diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 6d50f634e..8e758d1ab 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -383,5 +383,5 @@ "No valid travel thermograph found": "No se encontró un termógrafo válido", "The quantity claimed cannot be greater than the quantity of the line": "La cantidad reclamada no puede ser mayor que la cantidad de la línea", "type cannot be blank": "Se debe rellenar el tipo", - "There are tickets for this area, delete them first": "Hay tickets para esta sección, borralos primero" -} + "There are tickets for this area, delete them first": "Hay tickets para esta sección, borralos primero" +} \ No newline at end of file diff --git a/modules/item/back/methods/item/labelPdf.js b/modules/item/back/methods/item/itemLabelQr.js similarity index 62% rename from modules/item/back/methods/item/labelPdf.js rename to modules/item/back/methods/item/itemLabelQr.js index d7a50397e..8d92d51e8 100644 --- a/modules/item/back/methods/item/labelPdf.js +++ b/modules/item/back/methods/item/itemLabelQr.js @@ -1,5 +1,5 @@ module.exports = Self => { - Self.remoteMethodCtx('labelPdf', { + Self.remoteMethodCtx('itemLabelQr', { description: 'Returns the item label pdf', accessType: 'READ', accepts: [ @@ -11,26 +11,15 @@ module.exports = Self => { http: {source: 'path'} }, { - arg: 'recipientId', + arg: 'copies', type: 'number', - description: 'The recipient id', required: false - }, - { - arg: 'warehouseId', + }, { + arg: 'userId', type: 'number', - description: 'The warehouse id', + description: 'The user id from accessToken', + http: ctx => ctx.req.accessToken.userId, required: true - }, - { - arg: 'labelNumber', - type: 'number', - required: false - }, - { - arg: 'totalLabels', - type: 'number', - required: false } ], returns: [ @@ -49,11 +38,11 @@ module.exports = Self => { } ], http: { - path: '/:id/label-pdf', + path: '/:id/item-label-qr', verb: 'GET' }, accessScopes: ['DEFAULT', 'read:multimedia'] }); - Self.labelPdf = (ctx, id) => Self.printReport(ctx, id, 'item-label'); + Self.itemLabelQr = (ctx, id) => Self.printReport(ctx, id, 'item-label-qr'); }; diff --git a/modules/item/back/models/item.js b/modules/item/back/models/item.js index e715ab431..4fb9af8fa 100644 --- a/modules/item/back/models/item.js +++ b/modules/item/back/models/item.js @@ -15,7 +15,7 @@ module.exports = Self => { require('../methods/item/getWasteByItem')(Self); require('../methods/item/createIntrastat')(Self); require('../methods/item/buyerWasteEmail')(Self); - require('../methods/item/labelPdf')(Self); + require('../methods/item/itemLabelQr')(Self); require('../methods/item/setVisibleDiscard')(Self); require('../methods/item/get')(Self); diff --git a/print/templates/reports/item-label/assets/css/import.js b/print/templates/reports/item-label-qr/assets/css/import.js similarity index 100% rename from print/templates/reports/item-label/assets/css/import.js rename to print/templates/reports/item-label-qr/assets/css/import.js diff --git a/print/templates/reports/item-label-qr/assets/css/style.css b/print/templates/reports/item-label-qr/assets/css/style.css new file mode 100644 index 000000000..b868f3966 --- /dev/null +++ b/print/templates/reports/item-label-qr/assets/css/style.css @@ -0,0 +1,87 @@ +html { + font-family: "Roboto", "Helvetica", "Arial", sans-serif; + margin-top: -7px; +} +.leftTable { + width: 47%; + font-size: 12px; + float: left; + text-align: center; +} +.leftTable img { + width: 110px; +} +.rightTable { + width: 53%; + font-size: 14px; + float: right; +} +.rightTable td { + border: 3px solid white; +} +.center { + text-align: center; +} +.cursive { + font-style: italic; +} +.bold { + font-weight: bold; +} +.black-bg { + background-color: black; + color: white; +} +.md-txt { + font-size: 20px; +} +.xl-txt { + font-size: 36px; +} +.cell { + border: 2px solid black; + box-sizing: content-box; + width: 100%; + height: 30px; + display: flex; + justify-content: center; + align-items: center; +} +.padding { + padding: 7px; +} +.md-height { + height: 60px; + max-height: 60px; +} +.xs-width { + width: 60px; + max-width: 60px; +} +.sm-width { + width: 140px; + max-width: 140px; +} +.md-width { + width: 200px; + max-width: 200px; +} +.lg-width { + width: 270px; + max-width: 270px; +} +.overflow-multiline { + max-height: inherit; + display: -webkit-box; + overflow: hidden; + word-wrap: break-word; + line-clamp: 2; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; +} +.overflow-line { + width: inherit; + max-width: inherit; + overflow: hidden; + white-space: nowrap; +} \ No newline at end of file diff --git a/print/templates/reports/item-label-qr/item-label-qr.html b/print/templates/reports/item-label-qr/item-label-qr.html new file mode 100644 index 000000000..3b61e1542 --- /dev/null +++ b/print/templates/reports/item-label-qr/item-label-qr.html @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + +
+ + + +
+ {{item.buyFk}} +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ {{item.itemFk}} +
+
+
+ {{item.item}} +
+
+
+ {{item.size}} +
+
+
+ Color: {{item.inkFk}} +
+
+
+ {{item.packing}} +
+
+
+ {{item.stems}} +
+
+
+ Origen: {{item.origin}} +
+
+
+ Productor: {{item.producer}} +
+
+
+ Comprador: {{item.buyerName}} +
+
+
+ F: {{date}} +
+
+
+ {{`${item.labelNum} / ${totalPages}`}} +
+
+
+ Entrada: {{item.entryFk}} +
+
+
+ {{item.comment}} +
+
+ + \ No newline at end of file diff --git a/print/templates/reports/item-label-qr/item-label-qr.js b/print/templates/reports/item-label-qr/item-label-qr.js new file mode 100755 index 000000000..99744b0bd --- /dev/null +++ b/print/templates/reports/item-label-qr/item-label-qr.js @@ -0,0 +1,43 @@ +const UserError = require('vn-loopback/util/user-error'); +const moment = require('moment'); +const qrcode = require('qrcode'); + +module.exports = { + name: 'item-label-qr', + async serverPrefetch() { + this.items = await this.rawSqlFromDef('item', [this.copies || 1, this.id]); + if (!this.items.length) throw new UserError(`Empty data source`); + this.qr = await this.getQr(this.items[0].buyFk); + this.vnDate = Date.vnNew(); + this.date = moment(this.vnDate).format('YY/DD'); + this.totalPages = this.items.length; + }, + methods: { + getQr(data) { + data = { + company: 'vnl', + user: this.userId, + created: this.vnDate, + table: 'buy', + id: data + }; + return qrcode.toDataURL(JSON.stringify(data), { + margin: 0, + errorCorrectionLevel: 'H' + }); + } + }, + props: { + id: { + type: Number, + required: true, + description: 'The item id' + }, + copies: { + type: Number + }, + userId: { + type: Number + } + } +}; diff --git a/print/templates/reports/item-label-qr/locale/es.yml b/print/templates/reports/item-label-qr/locale/es.yml new file mode 100644 index 000000000..81dbc1877 --- /dev/null +++ b/print/templates/reports/item-label-qr/locale/es.yml @@ -0,0 +1 @@ +reportName: Etiqueta de artículo QR \ No newline at end of file diff --git a/print/templates/reports/item-label/options.json b/print/templates/reports/item-label-qr/options.json similarity index 86% rename from print/templates/reports/item-label/options.json rename to print/templates/reports/item-label-qr/options.json index 98c5788b1..5a3c3b1eb 100644 --- a/print/templates/reports/item-label/options.json +++ b/print/templates/reports/item-label-qr/options.json @@ -2,7 +2,7 @@ "width": "10.4cm", "height": "4.8cm", "margin": { - "top": "0cm", + "top": "0.17cm", "right": "0cm", "bottom": "0cm", "left": "0cm" diff --git a/print/templates/reports/item-label-qr/sql/item.sql b/print/templates/reports/item-label-qr/sql/item.sql new file mode 100644 index 000000000..11ee60d1a --- /dev/null +++ b/print/templates/reports/item-label-qr/sql/item.sql @@ -0,0 +1,42 @@ +WITH RECURSIVE numbers AS ( + SELECT 1 n + UNION ALL + SELECT n + 1 + FROM numbers + WHERE n < ? +) +SELECT ROW_NUMBER() OVER() labelNum, + b.id buyFk, + b.itemFk, + b.quantity, + b.packing, + b.isPickedOff, + b.entryFk, + e.sub, + o.code origin, + COALESCE(p.`name`, p.id, '') producer, + i.name item, + i.`size`, + i.category, + i.stems, + i.inkFk, + IFNULL(CONCAT(ig.longName, ' ', ig.`size`, ' ', ig.subName), i.comment) comment, + i.typeFk, + i.isLaid, + w.code buyerName, + w.code, + s.company_name companyName, + t.shipped + FROM vn.buy b + JOIN vn.item i ON i.id = b.itemFk + LEFT JOIN vn.item ig ON ig.id = b.itemOriginalFk + LEFT JOIN edi.ekt e ON e.id = b.ektFk + JOIN vn.origin o ON o.id = i.originFk + LEFT JOIN vn.producer p ON p.id = i.producerFk + JOIN vn.itemType it ON it.id = i.typeFk + JOIN vn.worker w ON w.id = it.workerFk + LEFT JOIN edi.supplier s ON s.supplier_id = e.pro + JOIN vn.entry e2 ON e2.id = b.entryFk + JOIN vn.travel t ON t.id = e2.travelFk + JOIN numbers num + WHERE b.id = ? \ No newline at end of file diff --git a/print/templates/reports/item-label/assets/css/style.css b/print/templates/reports/item-label/assets/css/style.css deleted file mode 100644 index 0dea5a9e4..000000000 --- a/print/templates/reports/item-label/assets/css/style.css +++ /dev/null @@ -1,37 +0,0 @@ -html { - font-family: "Roboto", "Helvetica", "Arial", sans-serif; - font-size: 12px; -} -table { - width: 50%; - font-size: 12px; - float: right; -} -td { - border: 3px solid white; -} -.center { - text-align: center; -} -.cursive { - font-style: italic; -} -.bold { - font-weight: bold; -} -.black { - background-color: black; - color: white; -} -.md { - font-size: 18px; -} -.xl { - font-size: 36px; -} -.border-black { - border: 2px solid #000000; -} -.regular-with { - width: 60px; -} \ No newline at end of file diff --git a/print/templates/reports/item-label/item-label.html b/print/templates/reports/item-label/item-label.html deleted file mode 100644 index e2526fc6b..000000000 --- a/print/templates/reports/item-label/item-label.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1
EUC Cinerea60
Color: LIV150
Origen: VCL
Productor: L'Arenal
Comprador: ATJF:42/11 / 50
Entrada: 358799
E622/2
- - \ No newline at end of file diff --git a/print/templates/reports/item-label/item-label.js b/print/templates/reports/item-label/item-label.js deleted file mode 100755 index c5b9cdfd7..000000000 --- a/print/templates/reports/item-label/item-label.js +++ /dev/null @@ -1,58 +0,0 @@ -const vnReport = require('../../../core/mixins/vn-report.js'); -const qrcode = require('qrcode'); - -module.exports = { - name: 'item-label', - mixins: [vnReport], - async serverPrefetch() { - this.item = await this.findOneFromDef('item', [this.id, this.warehouseId]); - this.checkMainEntity(this.item); - this.tags = await this.fetchItemTags(this.id); - this.barcode = await this.getBarcodeBase64(this.id); - }, - - computed: { - labelPage() { - const labelNumber = this.labelNumber ? this.labelNumber : 1; - const totalLabels = this.totalLabels ? this.totalLabels : 1; - - return `${labelNumber}/${totalLabels}`; - } - }, - methods: { - fetchItemTags(id) { - return this.rawSqlFromDef('itemTags', [id]).then(rows => { - const tags = {}; - rows.forEach(row => tags[row.code] = row.value); - - return tags; - }); - }, - getBarcodeBase64(id) { - const data = String(id); - - return qrcode.toDataURL(data, {margin: 0}); - }, - packing() { - const stems = this.item.stems ? this.item.stems : 1; - return `${this.item.packing}x${stems}`; - } - }, - props: { - id: { - type: Number, - required: true, - description: 'The item id' - }, - warehouseId: { - type: Number, - required: true - }, - labelNumber: { - type: Number - }, - totalLabels: { - type: Number - } - } -}; diff --git a/print/templates/reports/item-label/locale/es.yml b/print/templates/reports/item-label/locale/es.yml deleted file mode 100644 index 278946f3e..000000000 --- a/print/templates/reports/item-label/locale/es.yml +++ /dev/null @@ -1 +0,0 @@ -reportName: Etiqueta \ No newline at end of file diff --git a/print/templates/reports/item-label/sql/item.sql b/print/templates/reports/item-label/sql/item.sql deleted file mode 100644 index 46aacc2fa..000000000 --- a/print/templates/reports/item-label/sql/item.sql +++ /dev/null @@ -1,14 +0,0 @@ -SELECT - i.id, - i.name, - i.stems, - i.size, - b.packing, - p.name as 'producer' -FROM vn.item i - JOIN cache.last_buy clb ON clb.item_id = i.id - JOIN vn.buy b ON b.id = clb.buy_id - JOIN vn.entry e ON e.id = b.entryFk - JOIN vn.producer p ON p.id = i.producerFk - -WHERE i.id = ? AND clb.warehouse_id = ? \ No newline at end of file diff --git a/print/templates/reports/item-label/sql/itemTags.sql b/print/templates/reports/item-label/sql/itemTags.sql deleted file mode 100644 index 3c20098a6..000000000 --- a/print/templates/reports/item-label/sql/itemTags.sql +++ /dev/null @@ -1,4 +0,0 @@ -SELECT t.code, t.name, it.value -FROM vn.itemTag it - JOIN vn.tag t ON t.id = it.tagFk -WHERE it.itemFk = ? \ No newline at end of file