feat: refs #7266 First commit #3129

Merged
guillermo merged 9 commits from 7266-itemLabels into dev 2024-10-24 09:42:51 +00:00
32 changed files with 713 additions and 221 deletions

View File

@ -1723,7 +1723,6 @@ 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 (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);

View File

@ -0,0 +1,31 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost` FUNCTION `vn`.`buy_getUltimate`(
vItemFk INT,
vWarehouseFk INT,
guillermo marked this conversation as resolved Outdated

en estos casos sempre posem INT perque a este nivell costa mes temps mirar el camp de la taula que el benefici que portaria d'optimizacio que fos small

en estos casos sempre posem INT perque a este nivell costa mes temps mirar el camp de la taula que el benefici que portaria d'optimizacio que fos small

Ho he ficat mes que res per a respetar el tipo de dato del proc buy_getUltimate, que es smallint, pero ho canvie en els 2 puestos.

Ho he ficat mes que res per a respetar el tipo de dato del proc buy_getUltimate, que es smallint, pero ho canvie en els 2 puestos.
vDated DATE
)
RETURNS int(11)
DETERMINISTIC
BEGIN
/**
* Calcula las últimas compras realizadas hasta una fecha.
*
* @param vItemFk Id del artículo
* @param vWarehouseFk Id del almacén
* @param vDated Compras hasta fecha
* @return Id de compra
*/
DECLARE vBuyFk INT;
CALL buy_getUltimate(vItemFk, vWarehouseFk, vDated);
SELECT buyFk INTO vBuyFk
FROM tmp.buyUltimate;
DROP TEMPORARY TABLE IF EXISTS
tmp.buyUltimate,
tmp.buyUltimateFromInterval;
RETURN vBuyFk;
END$$
DELIMITER ;

View File

@ -1,7 +1,7 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`buy_getUltimate`(
vItemFk INT,
vWarehouseFk SMALLINT,
vWarehouseFk INT,
vDated DATE
)
BEGIN

View File

@ -0,0 +1,3 @@
DELETE FROM salix.ACL
WHERE property = 'labelPdf'
AND model = 'Item';

View File

@ -384,5 +384,6 @@
"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",
"There is no company associated with that warehouse": "No hay ninguna empresa asociada a ese almacén"
}

View File

@ -1,6 +1,6 @@
module.exports = Self => {
Self.remoteMethodCtx('labelPdf', {
description: 'Returns the item label pdf',
Self.remoteMethodCtx('labelBarcodePdf', {
description: 'Returns the item label pdf with barcode',
accessType: 'READ',
accepts: [
{
@ -9,28 +9,24 @@ module.exports = Self => {
required: true,
description: 'The item id',
http: {source: 'path'}
},
{
arg: 'recipientId',
type: 'number',
description: 'The recipient id',
required: false
},
{
}, {
arg: 'warehouseId',
type: 'number',
description: 'The warehouse id',
required: true
},
{
arg: 'labelNumber',
}, {
arg: 'packing',
type: 'number',
required: false
},
{
arg: 'totalLabels',
}, {
arg: 'copies',
type: 'number',
required: false
}, {
arg: 'userId',
type: 'number',
description: 'The user id from accessToken',
http: ctx => ctx.req.accessToken.userId,
required: true
}
],
returns: [
@ -49,11 +45,11 @@ module.exports = Self => {
}
],
http: {
path: '/:id/label-pdf',
path: '/:id/label-barcode-pdf',
verb: 'GET'
},
accessScopes: ['DEFAULT', 'read:multimedia']
});
Self.labelPdf = (ctx, id) => Self.printReport(ctx, id, 'item-label');
Self.labelBarcodePdf = (ctx, id) => Self.printReport(ctx, id, 'item-label-barcode');
};

View File

@ -0,0 +1,55 @@
module.exports = Self => {
Self.remoteMethodCtx('labelQrPdf', {
description: 'Returns the item label pdf with qr',
accessType: 'READ',
accepts: [
{
arg: 'id',
type: 'number',
required: true,
description: 'The item id',
http: {source: 'path'}
}, {
arg: 'warehouseId',
type: 'number',
required: true
}, {
arg: 'packing',
type: 'number',
required: false
}, {
arg: 'copies',
type: 'number',
required: false
}, {
arg: 'userId',
type: 'number',
description: 'The user id from accessToken',
http: ctx => ctx.req.accessToken.userId,
required: true
}
],
returns: [
{
arg: 'body',
type: 'file',
root: true
}, {
arg: 'Content-Type',
type: 'String',
http: {target: 'header'}
}, {
arg: 'Content-Disposition',
type: 'String',
http: {target: 'header'}
}
],
http: {
path: '/:id/label-qr-pdf',
verb: 'GET'
},
accessScopes: ['DEFAULT', 'read:multimedia']
});
Self.labelQrPdf = (ctx, id) => Self.printReport(ctx, id, 'item-label-qr');
};

View File

@ -15,7 +15,8 @@ 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/labelBarcodePdf')(Self);
require('../methods/item/labelQrPdf')(Self);
require('../methods/item/setVisibleDiscard')(Self);
require('../methods/item/get')(Self);

View File

@ -0,0 +1,84 @@
html {
font-family: "Roboto", "Helvetica", "Arial", sans-serif;
margin-top: -9px;
margin-left: -6px;
}
table {
width: 100%;
font-size: 14px;
}
td {
border: 6px solid white;
}
.center {
text-align: center;
}
.right {
text-align: right;
}
.cursive {
font-style: italic;
}
.bold {
font-weight: bold;
}
.black-bg {
background-color: black;
color: white;
}
.xs-txt {
font-size: 18px;
}
.md-txt {
font-size: 26px;
}
.xl-txt {
font-size: 50px;
}
.cell {
border: 2px solid black;
box-sizing: content-box;
width: 100%;
height: 30px;
display: flex;
justify-content: center;
align-items: center;
}
.padding {
padding: 7px;
}
.xs-height {
height: 50px;
max-height: 50px;
}
.md-height {
height: 75px;
max-height: 75px;
}
.sm-width {
width: 60px;
max-width: 60px;
}
.md-width {
width: 125px;
max-width: 125px;
}
.lg-width {
width: 380px;
max-width: 380px;
}
.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;
}

View File

@ -0,0 +1,91 @@
<!DOCTYPE html>
<html>
<body table v-for="item in items" style="break-before: page">
<table>
<tr>
<td class="md-txt bold center black-bg lg-width md-height">
<div class="overflow-multiline">
{{item.item}}
</div>
</td>
<td colspan="2" class="xl-txt bold center black-bg md-height md-width">
<div class="overflow-line">
{{item.size}}
</div>
</td>
</tr>
<tr>
<td class="right lg-width">
<div class="overflow-line">
{{
(item.longName && item.size && item.subName)
? `${item.longName} ${item.size} ${item.subName}`
: item.comment
}}
</div>
</td>
<td class="center sm-width">
<div class="overflow-line">
{{item.producerName || item.producerFk}}
</div>
</td>
<td class="center sm-width">
<div class="overflow-line">
{{item.inkFk}}
</div>
</td>
</tr>
<tr>
<td class="md-txt xl-width bold center">
<div class="overflow-line">
{{item.itemFk}}
</div>
</td>
<td colspan="2" class="md-txt md-width center">
<div class="overflow-line">
{{`${(packing || item.packing)} x ${item.stems || ''}`}}
</div>
</td>
</tr>
<tr>
<td rowspan="2" class="center">
<div v-html="getBarcode(item.buyFk)"></div>
</td>
<td colspan="2" class="center md-width xs-height xs-txt">
<div class="overflow-line">
{{item.entryFk}}
</div>
</td>
</tr>
<tr>
<td class="center xs-txt sm-width">
<div class="overflow-line">
{{item.buyerName}}
</div>
</td>
<td class="center xs-txt sm-width">
<div class="overflow-line">
{{item.origin}}
</div>
</td>
</tr>
<tr>
<td class="center xl-width">
<div class="overflow-line">
{{item.buyFk}}
</div>
</td>
<td class="xs-txt sm-width center">
<div class="overflow-line">
{{date}}
</div>
</td>
<td class="xs-txt sm-width cursive center bold">
<div class="overflow-line">
{{`${item.labelNum}/${item.quantity / (packing || item.packing)}`}}
</div>
</td>
</tr>
</table>
</body>
</html>

View File

@ -0,0 +1,58 @@
const UserError = require('vn-loopback/util/user-error');
const {DOMImplementation, XMLSerializer} = require('xmldom');
const moment = require('moment');
const jsbarcode = require('jsbarcode');
module.exports = {
name: 'item-label-qr',
async serverPrefetch() {
this.company = await this.findOneFromDef('company', [this.warehouseId]);
if (!this.company)
throw new UserError(`There is no company associated with that warehouse`);
this.date = Date.vnNew();
this.lastBuy = await this.findOneFromDef('lastBuy', [
this.id,
this.warehouseId,
this.date
]);
this.items = await this.rawSqlFromDef('item', [this.copies || 1, this.lastBuy.id]);
if (!this.items.length) throw new UserError(`Empty data source`);
this.date = moment(this.date).format('WW/E');
},
methods: {
getBarcode(data) {
const document = new DOMImplementation().createDocument('http://www.w3.org/1999/xhtml', 'html', null);
const svgNode = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
jsbarcode(svgNode, data, {
xmlDocument: document,
format: 'code128',
displayValue: false,
width: 3.8,
height: 85,
margin: 0
});
return new XMLSerializer().serializeToString(svgNode);
}
},
props: {
id: {
type: Number,
required: true,
description: 'The item id'
},
warehouseId: {
type: Number
},
packing: {
type: Number
},
copies: {
type: Number
},
userId: {
type: Number
}
}
};

View File

@ -0,0 +1 @@
reportName: Etiqueta de artículo barcode

View File

@ -0,0 +1,11 @@
{
"width": "10.4cm",
"height": "4.9cm",
"margin": {
"top": "0.17cm",
"right": "0.745cm",
"bottom": "0cm",
"left": "0cm"
},
"printBackground": true
}

View File

@ -0,0 +1,5 @@
SELECT co.code
FROM warehouse w
JOIN address a ON a.id = w.addressFk
JOIN company co ON co.clientFk = a.clientFk
guillermo marked this conversation as resolved Outdated

no cal client, directament de address a company

no cal client, directament de address a company
WHERE w.id = ?

View File

@ -0,0 +1,34 @@
WITH RECURSIVE numbers AS (
SELECT 1 n
UNION ALL
SELECT n + 1
FROM numbers
WHERE n < ?
)
SELECT ROW_NUMBER() OVER() labelNum,
b.itemFk,
i.name item,
b.id buyFk,
b.quantity,
b.packing,
b.entryFk,
o.code origin,
p.`name` producerName,
p.id producerFk,
guillermo marked this conversation as resolved Outdated

no es elegant tornar '', lo correcte seria un IFNULL i despues tu en el report, si et tornen null fas el que cregues

no es elegant tornar '', lo correcte seria un IFNULL i despues tu en el report, si et tornen null fas el que cregues

Veritat, com he agarrat la consulta directament de access no me fijat

Veritat, com he agarrat la consulta directament de access no me fijat
i.`size`,
i.category,
i.stems,
i.inkFk,
ig.longName,
ig.subName,
guillermo marked this conversation as resolved Outdated

açò si no et costa molt lo mateix, back deuria tornar els camps, i front juntarlos (opcional)

açò si no et costa molt lo mateix, back deuria tornar els camps, i front juntarlos (opcional)
i.comment,
w.code buyerName
FROM vn.buy b
JOIN vn.item i ON i.id = b.itemFk
LEFT JOIN vn.item ig ON ig.id = b.itemOriginalFk
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
JOIN numbers num
WHERE b.id = ?

View File

@ -0,0 +1 @@
SELECT buy_getUltimate(?, ?, ?) id

View File

@ -0,0 +1,12 @@
const Stylesheet = require(`vn-print/core/stylesheet`);
const path = require('path');
const vnPrintPath = path.resolve('print');
module.exports = new Stylesheet([
`${vnPrintPath}/common/css/spacing.css`,
`${vnPrintPath}/common/css/misc.css`,
`${vnPrintPath}/common/css/layout.css`,
`${vnPrintPath}/common/css/report.css`,
`${__dirname}/style.css`])
.mergeStyles();

View File

@ -0,0 +1,89 @@
html {
font-family: "Roboto", "Helvetica", "Arial", sans-serif;
margin-top: -7px;
margin-left: -6px;
}
.leftTable {
width: 47%;
font-size: 12px;
float: left;
text-align: center;
}
.leftTable img {
margin-top: 3px;
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: 68px;
max-height: 68px;
}
.xs-width {
width: 60px;
max-width: 60px;
}
.sm-width {
width: 130px;
max-width: 130px;
}
.md-width {
width: 190px;
max-width: 190px;
}
.lg-width {
width: 240px;
max-width: 240px;
}
.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;
}

View File

@ -0,0 +1,116 @@
<!DOCTYPE html>
<html>
<body v-for="item in items" style="break-before: page">
<table class="leftTable">
<tr>
<td>
<img v-bind:src="qr"/>
</td>
<td>
<img v-bind:src="qr"/>
</td>
</tr>
<tr>
<td colspan="2">
{{item.buyFk}}
</td>
</tr>
<tr>
<td>
<img v-bind:src="qr"/>
</td>
<td>
<img v-bind:src="qr"/>
</td>
</tr>
</table>
<table class="rightTable">
<tr>
<td colspan="3" class="lg-width black-bg center bold xl-txt padding">
<div class="overflow-line">
{{item.itemFk}}
</div>
</td>
</tr>
<tr>
<td colspan="2" class="black-bg center bold md-txt md-width md-height">
<div class="overflow-multiline">
{{item.item}}
</div>
</td>
<td class="xs-width black-bg center bold xl-txt">
<div class="overflow-line">
{{item.size}}
</div>
</td>
</tr>
<tr>
<td class="sm-width">
<div class="overflow-line">
<i>Color:</i> <b>{{item.inkFk}}</b>
</div>
</td>
<td rowspan="2" class="xs-width center md-txt">
<div class="overflow-line cell">
{{packing || item.packing}}
</div>
</td>
<td rowspan="2" class="xs-width center md-txt">
<div class="overflow-line cell">
{{item.stems}}
</div>
</td>
</tr>
<tr>
<td class="sm-width">
<div class="overflow-line">
<i>Origen:</i> {{item.origin}}
</div>
</td>
</tr>
<tr>
<td colspan="2" class="md-width">
<div class="overflow-line">
<i>Productor:</i> {{item.producerName || item.producerFk}}
</div>
</td>
<td></td>
</tr>
<tr>
<td class="sm-width">
<div class="overflow-line">
<i>Comprador:</i> {{item.buyerName}}
</div>
</td>
<td rowspan="2" class="xs-width">
<div class="overflow-line">
<i>F:</i> {{date}}
</div>
</td>
<td rowspan="2" class="xs-width center cursive bold md-txt">
<div class="overflow-line">
{{`${item.labelNum}/${item.quantity / (packing || item.packing)}`}}
</div>
</td>
</tr>
<tr>
<td class="sm-width">
<div class="overflow-line">
<i>Entrada:</i> {{item.entryFk}}
</div>
</td>
</tr>
<tr>
<td colspan="3" class="lg-width center cursive bold">
<div class="overflow-line">
{{
(item.longName && item.size && item.subName)
? `${item.longName} ${item.size} ${item.subName}`
: item.comment
}}
</div>
</td>
</tr>
</table>
</body>
</html>

View File

@ -0,0 +1,57 @@
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.company = await this.findOneFromDef('company', [this.warehouseId]);
if (!this.company)
throw new UserError(`There is no company associated with that warehouse`);
this.date = Date.vnNew();
this.lastBuy = await this.findOneFromDef('lastBuy', [
this.id,
this.warehouseId,
this.date
]);
this.items = await this.rawSqlFromDef('item', [this.copies || 1, this.lastBuy.id]);
if (!this.items.length) throw new UserError(`Empty data source`);
this.qr = await this.getQr(this.items[0].buyFk);
this.date = moment(this.date).format('WW/E');
},
methods: {
getQr(data) {
data = {
company: this.company,
user: this.userId,
created: this.date,
table: 'buy',
id: data
};
return qrcode.toDataURL(JSON.stringify(data), {
margin: 0,
errorCorrectionLevel: 'L'
});
}
},
props: {
id: {
type: Number,
required: true,
description: 'The item id'
},
warehouseId: {
type: Number
},
packing: {
type: Number
},
copies: {
type: Number
},
userId: {
type: Number
}
}
};

View File

@ -0,0 +1 @@
reportName: Etiqueta de artículo QR

View File

@ -1,9 +1,9 @@
{
"width": "10.4cm",
"height": "4.8cm",
"height": "4.9cm",
"margin": {
"top": "0cm",
"right": "0cm",
"top": "0.17cm",
"right": "0.6cm",
"bottom": "0cm",
"left": "0cm"
},

View File

@ -0,0 +1,5 @@
SELECT co.code
FROM warehouse w
JOIN address a ON a.id = w.addressFk
JOIN company co ON co.clientFk = a.clientFk
guillermo marked this conversation as resolved Outdated

esta en varios llocs, ací lleva el client

esta en varios llocs, ací lleva el client
WHERE w.id = ?

View File

@ -0,0 +1,34 @@
WITH RECURSIVE numbers AS (
SELECT 1 n
UNION ALL
SELECT n + 1
FROM numbers
WHERE n < ?
)
SELECT ROW_NUMBER() OVER() labelNum,
b.itemFk,
i.name item,
b.id buyFk,
b.quantity,
b.packing,
b.entryFk,
o.code origin,
p.`name` producerName,
p.id producerFk,
i.`size`,
i.category,
i.stems,
i.inkFk,
ig.longName,
ig.subName,
i.comment,
w.code buyerName
FROM vn.buy b
JOIN vn.item i ON i.id = b.itemFk
LEFT JOIN vn.item ig ON ig.id = b.itemOriginalFk
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
JOIN numbers num
WHERE b.id = ?

View File

@ -0,0 +1 @@
SELECT buy_getUltimate(?, ?, ?) id

View File

@ -1,88 +0,0 @@
* {
box-sizing: border-box;
}
.label {
font-size: 1.2em;
}
.barcode {
float: left;
width: 40%;
}
.barcode h1 {
text-align: center;
font-size: 1.8em;
margin: 0 0 10px 0
}
.barcode .image {
text-align: center
}
.barcode .image img {
width: 170px
}
.data {
float: left;
width: 60%;
}
.data .header {
background-color: #000;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
margin-bottom: 25px;
text-align: right;
font-size: 1.2em;
padding: 0.2em;
color: #FFF
}
.data .color,
.data .producer {
text-transform: uppercase;
text-align: right;
font-size: 1.5em;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.data .producer {
text-justify: inter-character;
}
.data .details {
border-top: 4px solid #000;
padding-top: 2px;
}
.data .details .package {
padding-right: 5px;
float: left;
width: 50%;
}
.package .packing,
.package .dated,
.package .labelNumber {
text-align: right
}
.package .packing {
font-size: 1.8em;
font-weight: 400
}
.data .details .size {
background-color: #000;
text-align: center;
font-size: 3em;
padding: 0.2em 0;
float: left;
width: 50%;
color: #FFF
}

View File

@ -1,29 +0,0 @@
<report-body v-bind="$props">
<template v-slot:header>
<span></span>
</template>
<div class="label">
<div class="barcode">
<h1>{{item.id}}</h1>
<div class="image">
<img v-bind:src="barcode" />
</div>
</div>
<div class="data">
<div class="header">{{item.name}}</div>
<div class="color">{{tags.color}}</div>
<div class="producer">{{tags.producer}}</div>
<div class="details">
<div class="package">
<div class="packing">{{packing()}}</div>
<div class="dated">{{formatDate(new Date(), '%W/%d')}}</div>
<div class="labelNumber">{{labelPage}}</div>
</div>
<div class="size">{{item.size}}</div>
</div>
</div>
</div>
<template v-slot:footer>
<span></span>
</template>
</report-body>

View File

@ -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
}
}
};

View File

@ -1 +0,0 @@
reportName: Etiqueta

View File

@ -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 = ?

View File

@ -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 = ?