feat: refs #7266 First commit #3129
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
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 ;
|
|
@ -1,7 +1,7 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`buy_getUltimate`(
|
||||
vItemFk INT,
|
||||
vWarehouseFk SMALLINT,
|
||||
vWarehouseFk INT,
|
||||
vDated DATE
|
||||
)
|
||||
BEGIN
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
DELETE FROM salix.ACL
|
||||
WHERE property = 'labelPdf'
|
||||
AND model = 'Item';
|
|
@ -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"
|
||||
}
|
|
@ -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');
|
||||
};
|
|
@ -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');
|
||||
};
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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>
|
|
@ -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
|
||||
}
|
||||
}
|
||||
};
|
|
@ -0,0 +1 @@
|
|||
reportName: Etiqueta de artículo barcode
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"width": "10.4cm",
|
||||
"height": "4.9cm",
|
||||
"margin": {
|
||||
"top": "0.17cm",
|
||||
"right": "0.745cm",
|
||||
"bottom": "0cm",
|
||||
"left": "0cm"
|
||||
},
|
||||
"printBackground": true
|
||||
}
|
|
@ -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
jgallego
commented
no cal client, directament de address a company no cal client, directament de address a company
|
||||
WHERE w.id = ?
|
|
@ -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
jgallego
commented
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
guillermo
commented
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
jgallego
commented
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 = ?
|
|
@ -0,0 +1 @@
|
|||
SELECT buy_getUltimate(?, ?, ?) id
|
|
@ -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();
|
|
@ -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;
|
||||
}
|
|
@ -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>
|
|
@ -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
|
||||
}
|
||||
}
|
||||
};
|
|
@ -0,0 +1 @@
|
|||
reportName: Etiqueta de artículo QR
|
|
@ -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"
|
||||
},
|
|
@ -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
jgallego
commented
esta en varios llocs, ací lleva el client esta en varios llocs, ací lleva el client
|
||||
WHERE w.id = ?
|
|
@ -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 = ?
|
|
@ -0,0 +1 @@
|
|||
SELECT buy_getUltimate(?, ?, ?) id
|
|
@ -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
|
||||
}
|
|
@ -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>
|
|
@ -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
|
||||
}
|
||||
}
|
||||
};
|
|
@ -1 +0,0 @@
|
|||
reportName: Etiqueta
|
|
@ -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 = ?
|
|
@ -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 = ?
|
Loading…
Reference in New Issue
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.