Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 4649-bookEntriesIncorrectly_notification

This commit is contained in:
Vicent Llopis 2022-11-30 08:03:16 +01:00
commit f056c26b0d
13 changed files with 286 additions and 93 deletions

View File

@ -2564,10 +2564,6 @@ UPDATE `vn`.`route`
UPDATE `vn`.`route` UPDATE `vn`.`route`
SET `invoiceInFk`=2 SET `invoiceInFk`=2
WHERE `id`=2; WHERE `id`=2;
INSERT INTO `bs`.`salesPerson` (`workerFk`, `year`, `month`)
VALUES
(18, YEAR(util.VN_CURDATE()), MONTH(util.VN_CURDATE())),
(19, YEAR(util.VN_CURDATE()), MONTH(util.VN_CURDATE()));
INSERT INTO `bs`.`sale` (`saleFk`, `amount`, `dated`, `typeFk`, `clientFk`) INSERT INTO `bs`.`sale` (`saleFk`, `amount`, `dated`, `typeFk`, `clientFk`)
VALUES VALUES

View File

@ -37,7 +37,7 @@ export default class Controller extends Section {
const validations = window.validations; const validations = window.validations;
value.forEach(log => { value.forEach(log => {
const locale = validations[log.changedModel].locale ? validations[log.changedModel].locale : {}; const locale = validations[log.changedModel] && validations[log.changedModel].locale ? validations[log.changedModel].locale : {};
log.oldProperties = this.getInstance(log.oldInstance, locale); log.oldProperties = this.getInstance(log.oldInstance, locale);
log.newProperties = this.getInstance(log.newInstance, locale); log.newProperties = this.getInstance(log.newInstance, locale);

View File

@ -91,7 +91,10 @@ module.exports = Self => {
case 'search': case 'search':
return /^\d+$/.test(value) return /^\d+$/.test(value)
? {'c.id': {inq: value}} ? {'c.id': {inq: value}}
: {'c.name': {like: `%${value}%`}}; : {or: [
{'c.name': {like: `%${value}%`}},
{'c.socialName': {like: `%${value}%`}},
]};
case 'name': case 'name':
case 'salesPersonFk': case 'salesPersonFk':
case 'fi': case 'fi':

View File

@ -33,36 +33,36 @@ module.exports = Self => {
const stmt = new ParameterizedSQL( const stmt = new ParameterizedSQL(
`SELECT `SELECT
t.id, t.id,
t.packages, t.packages,
t.warehouseFk, t.warehouseFk,
t.nickname, t.nickname,
t.clientFk, t.clientFk,
t.priority, t.priority,
t.addressFk, t.addressFk,
st.code AS ticketStateCode, st.code AS ticketStateCode,
st.name AS ticketStateName, st.name AS ticketStateName,
wh.name AS warehouseName, wh.name AS warehouseName,
tob.description AS ticketObservation, tob.description AS ticketObservation,
a.street, a.street,
a.postalCode, a.postalCode,
a.city, a.city,
am.name AS agencyModeName, am.name AS agencyModeName,
u.nickname AS userNickname, u.nickname AS userNickname,
vn.ticketTotalVolume(t.id) AS volume, vn.ticketTotalVolume(t.id) AS volume,
tob.description tob.description
FROM route r FROM vn.route r
JOIN ticket t ON t.routeFk = r.id JOIN ticket t ON t.routeFk = r.id
LEFT JOIN ticketState ts ON ts.ticketFk = t.id LEFT JOIN ticketState ts ON ts.ticketFk = t.id
LEFT JOIN state st ON st.id = ts.stateFk LEFT JOIN state st ON st.id = ts.stateFk
LEFT JOIN warehouse wh ON wh.id = t.warehouseFk LEFT JOIN warehouse wh ON wh.id = t.warehouseFk
LEFT JOIN ticketObservation tob ON tob.ticketFk = t.id LEFT JOIN observationType ot ON ot.code = 'delivery'
LEFT JOIN observationType ot ON tob.observationTypeFk = ot.id LEFT JOIN ticketObservation tob ON tob.ticketFk = t.id
AND ot.code = 'delivery' AND tob.observationTypeFk = ot.id
LEFT JOIN address a ON a.id = t.addressFk LEFT JOIN address a ON a.id = t.addressFk
LEFT JOIN agencyMode am ON am.id = t.agencyModeFk LEFT JOIN agencyMode am ON am.id = t.agencyModeFk
LEFT JOIN account.user u ON u.id = r.workerFk LEFT JOIN account.user u ON u.id = r.workerFk
LEFT JOIN vehicle v ON v.id = r.vehicleFk` LEFT JOIN vehicle v ON v.id = r.vehicleFk`
); );
if (!filter.where) filter.where = {}; if (!filter.where) filter.where = {};

View File

@ -0,0 +1,181 @@
const Imap = require('imap');
module.exports = Self => {
Self.remoteMethod('checkInbox', {
description: 'Check an email inbox and process it',
accessType: 'READ',
returns:
{
arg: 'body',
type: 'file',
root: true
},
http: {
path: `/checkInbox`,
verb: 'POST'
}
});
Self.checkInbox = async() => {
let imapConfig = await Self.app.models.WorkerTimeControlParams.findOne();
let imap = new Imap({
user: imapConfig.mailUser,
password: imapConfig.mailPass,
host: imapConfig.mailHost,
port: 993,
tls: true
});
let isEmailOk;
let uid;
let emailBody;
function openInbox(cb) {
imap.openBox('INBOX', true, cb);
}
imap.once('ready', function() {
openInbox(function(err, box) {
if (err) throw err;
const totalMessages = box.messages.total;
if (totalMessages == 0)
imap.end();
let f = imap.seq.fetch('1:*', {
bodies: ['HEADER.FIELDS (FROM SUBJECT)', '1'],
struct: true
});
f.on('message', function(msg, seqno) {
isEmailOk = false;
msg.on('body', function(stream, info) {
let buffer = '';
let bufferCopy = '';
stream.on('data', function(chunk) {
buffer = chunk.toString('utf8');
if (info.which === '1' && bufferCopy.length == 0)
bufferCopy = buffer.replace(/\s/g, ' ');
});
stream.on('end', function() {
if (bufferCopy.length > 0) {
emailBody = bufferCopy.toUpperCase().trim();
const bodyPositionOK = emailBody.match(/\bOK\b/i);
if (bodyPositionOK != null && (bodyPositionOK.index == 0 || bodyPositionOK.index == 122))
isEmailOk = true;
else
isEmailOk = false;
}
});
msg.once('attributes', function(attrs) {
uid = attrs.uid;
});
msg.once('end', function() {
if (info.which === 'HEADER.FIELDS (FROM SUBJECT)') {
if (isEmailOk) {
imap.move(uid, 'exito', function(err) {
});
emailConfirm(buffer);
} else {
imap.move(uid, 'error', function(err) {
});
emailReply(buffer, emailBody);
}
}
});
});
});
f.once('end', function() {
imap.end();
});
});
});
imap.connect();
return 'Leer emails de gestion horaria';
};
async function emailConfirm(buffer) {
const now = new Date();
const from = JSON.stringify(Imap.parseHeader(buffer).from);
const subject = JSON.stringify(Imap.parseHeader(buffer).subject);
const timeControlDate = await getEmailDate(subject);
const week = timeControlDate[0];
const year = timeControlDate[1];
const user = await getUser(from);
let workerMail;
if (user.id != null) {
workerMail = await Self.app.models.WorkerTimeControlMail.findOne({
where: {
week: week,
year: year,
workerFk: user.id
}
});
}
if (workerMail != null) {
await workerMail.updateAttributes({
updated: now,
state: 'CONFIRMED'
});
}
}
async function emailReply(buffer, emailBody) {
const now = new Date();
const from = JSON.stringify(Imap.parseHeader(buffer).from);
const subject = JSON.stringify(Imap.parseHeader(buffer).subject);
const timeControlDate = await getEmailDate(subject);
const week = timeControlDate[0];
const year = timeControlDate[1];
const user = await getUser(from);
let workerMail;
if (user.id != null) {
workerMail = await Self.app.models.WorkerTimeControlMail.findOne({
where: {
week: week,
year: year,
workerFk: user.id
}
});
if (workerMail != null) {
await workerMail.updateAttributes({
updated: now,
state: 'REVISE',
reason: emailBody
});
} else
await sendMail(user, subject, emailBody);
}
}
async function getUser(workerEmail) {
const userEmail = workerEmail.match(/(?<=<)(.*?)(?=>)/);
let [user] = await Self.rawSql(`SELECT u.id,u.name FROM account.user u
LEFT JOIN account.mailForward m on m.account = u.id
WHERE forwardTo =? OR
CONCAT(u.name,'@verdnatura.es') = ?`,
[userEmail[0], userEmail[0]]);
return user;
}
async function getEmailDate(subject) {
const date = subject.match(/\d+/g);
return date;
}
async function sendMail(user, subject, emailBody) {
const sendTo = 'rrhh@verdnatura.es';
const emailSubject = subject + ' ' + user.name;
await Self.app.models.Mail.create({
receiver: sendTo,
subject: emailSubject,
body: emailBody
});
}
};

View File

@ -133,7 +133,7 @@ module.exports = Self => {
tb.permissionRate, tb.permissionRate,
d.isTeleworking d.isTeleworking
FROM tmp.timeBusinessCalculate tb FROM tmp.timeBusinessCalculate tb
JOIN user u ON u.id = tb.userFk JOIN account.user u ON u.id = tb.userFk
JOIN department d ON d.id = tb.departmentFk JOIN department d ON d.id = tb.departmentFk
JOIN business b ON b.id = tb.businessFk JOIN business b ON b.id = tb.businessFk
LEFT JOIN tmp.timeControlCalculate tc ON tc.userFk = tb.userFk AND tc.dated = tb.dated LEFT JOIN tmp.timeControlCalculate tc ON tc.userFk = tb.userFk AND tc.dated = tb.dated
@ -143,7 +143,7 @@ module.exports = Self => {
IF(tc.timeWorkDecimal > 0, FALSE, IF(tb.timeWorkDecimal > 0, TRUE, FALSE)), IF(tc.timeWorkDecimal > 0, FALSE, IF(tb.timeWorkDecimal > 0, TRUE, FALSE)),
TRUE))isTeleworkingWeek TRUE))isTeleworkingWeek
FROM tmp.timeBusinessCalculate tb FROM tmp.timeBusinessCalculate tb
LEFT JOIN tmp.timeControlCalculate tc ON tc.userFk = tb.userFk LEFT JOIN tmp.timeControlCalculate tc ON tc.userFk = tb.userFk
AND tc.dated = tb.dated AND tc.dated = tb.dated
GROUP BY tb.userFk GROUP BY tb.userFk
HAVING isTeleworkingWeek > 0 HAVING isTeleworkingWeek > 0

View File

@ -0,0 +1,3 @@
module.exports = Self => {
require('../methods/worker-time-control-mail/checkInbox')(Self);
};

View File

@ -49,4 +49,10 @@
.page-break-after { .page-break-after {
page-break-after: always; page-break-after: always;
}
.ellipsize {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
} }

View File

@ -1,6 +1,6 @@
html { html {
font-family: "Roboto"; font-family: "Roboto";
margin-top: -7px; margin-top: -6px;
} }
* { * {
box-sizing: border-box; box-sizing: border-box;
@ -9,7 +9,7 @@ html {
} }
#vertical { #vertical {
writing-mode: vertical-rl; writing-mode: vertical-rl;
height: 226px; height: 240px;
margin-left: -13px; margin-left: -13px;
} }
.outline { .outline {
@ -18,6 +18,7 @@ html {
} }
#nickname { #nickname {
font-size: 22px; font-size: 22px;
max-width: 50px;
} }
#agencyDescripton { #agencyDescripton {
font-size: 32px; font-size: 32px;

View File

@ -1,35 +1,36 @@
<report-body v-bind="$props"> <!DOCTYPE html>
<template v-slot:header> <html>
<span></span> <body>
</template> <table v-for="labelData in labelsData" style="break-before: page">
<table v-for="labelData in labelsData"> <tbody>
<tbody> <tr>
<tr> <td rowspan="6"><span id="vertical" class="ellipsize">
<td rowspan="6"><span id="vertical">{{labelData.levelV}}</span></td> {{labelData.collectionFk ? `${labelData.collectionFk} ~ ${labelData.wagon}-${labelData.level}` : '-'.repeat(23)}}
<td id="ticketFk">{{labelData.ticketFk}} ⬸ {{labelData.clientFk}}</td> </span></td>
<td colspan="2" id="shipped">{{labelData.shipped}}</td> <td id="ticketFk">
</tr> {{labelData.clientFk ? `${labelData.ticketFk} « ${labelData.clientFk}` : labelData.ticketFk}}
<tr> </td>
<td rowspan="3"><div v-html="getBarcode(labelData.ticketFk)" id="barcode"></div></td> <td colspan="2" id="shipped">{{labelData.shipped ? labelData.shipped : '---'}}</td>
<td class="outline">{{labelData.workerCode}}</td> </tr>
</tr> <tr>
<tr> <td rowspan="3"><div v-html="getBarcode(labelData.ticketFk)" id="barcode"></div></td>
<td class="outline">{{labelData.labelCount}}</td> <td class="outline">{{labelData.workerCode ? labelData.workerCode : '---'}}</td>
</tr> </tr>
<tr> <tr>
<td class="outline">{{labelData.size}}</td> <td class="outline">{{labelData.labelCount ? labelData.labelCount : 0}}</td>
</tr> </tr>
<tr> <tr>
<td><div id="agencyDescripton">{{labelData.agencyDescription}}</div></td> <td class="outline">{{labelData.code == 'plant' ? labelData.size + 'cm' : labelData.volume + 'm³'}}</td>
<td id="bold">{{labelData.lineCount}}</td> </tr>
</tr> <tr>
<tr> <td><div id="agencyDescripton" class="ellipsize">{{labelData.agencyDescription}}</div></td>
<td id="nickname">{{labelData.nickName}}</td> <td id="bold">{{labelData.lineCount ? labelData.lineCount : 0}}</td>
<td id="bold">{{labelData.agencyHour}}</td> </tr>
</tr> <tr>
</tbody> <td id="nickname" class="ellipsize">{{labelData.nickName ? labelData.nickName : '---'}}</td>
</table> <td id="bold">{{labelData.shipped ? labelData.shippedHour : labelData.zoneHour}}</td>
<template v-slot:footer> </tr>
<span></span> </tbody>
</template> </table>
</report-body> </body>
</html>

View File

@ -40,7 +40,7 @@ module.exports = {
format: 'code128', format: 'code128',
displayValue: false, displayValue: false,
width: 3.8, width: 3.8,
height: 110, height: 115,
}); });
return xmlSerializer.serializeToString(svgNode); return xmlSerializer.serializeToString(svgNode);
}, },

View File

@ -2,8 +2,8 @@
"width": "10.4cm", "width": "10.4cm",
"height": "4.8cm", "height": "4.8cm",
"margin": { "margin": {
"top": "0cm", "top": "0.3cm",
"right": "0.5cm", "right": "0.6cm",
"bottom": "0cm", "bottom": "0cm",
"left": "0cm" "left": "0cm"
}, },

View File

@ -1,21 +1,23 @@
SELECT c.itemPackingTypeFk, SELECT tc.collectionFk,
CONCAT(tc.collectionFk, ' ', LEFT(cc.code, 4)) color, SUBSTRING('ABCDEFGH', tc.wagon, 1) wagon,
CONCAT(tc.collectionFk, ' ', SUBSTRING('ABCDEFGH',tc.wagon, 1), '-', tc.`level`) levelV, tc.`level`,
tc.ticketFk, t.id ticketFk,
LEFT(COALESCE(et.description, zo.name, am.name),12) agencyDescription, COALESCE(et.description, zo.name, am.name) agencyDescription,
am.name, am.name,
t.clientFk, t.clientFk,
CONCAT(CAST(SUM(sv.volume) AS DECIMAL(5, 2)), '') m3 , CAST(SUM(sv.volume) AS DECIMAL(5, 2)) volume,
CAST(IF(ic.code = 'plant', CONCAT(MAX(i.`size`),' cm'), COUNT(*)) AS CHAR) size, MAX(i.`size`) `size`,
ic.code,
w.code workerCode, w.code workerCode,
tt.labelCount, TIME_FORMAT(t.shipped, '%H:%i') shippedHour,
IF(HOUR(t.shipped), TIME_FORMAT(t.shipped, '%H:%i'), TIME_FORMAT(zo.`hour`, '%H:%i')) agencyHour, TIME_FORMAT(zo.`hour`, '%H:%i') zoneHour,
DATE_FORMAT(t.shipped, '%d/%m/%y') shipped, DATE_FORMAT(t.shipped, '%d/%m/%y') shipped,
COUNT(*) lineCount, t.nickName,
t.nickName tt.labelCount,
COUNT(*) lineCount
FROM vn.ticket t FROM vn.ticket t
JOIN vn.ticketCollection tc ON tc.ticketFk = t.id LEFT JOIN vn.ticketCollection tc ON tc.ticketFk = t.id
JOIN vn.collection c ON c.id = tc.collectionFk LEFT JOIN vn.collection c ON c.id = tc.collectionFk
LEFT JOIN vn.collectionColors cc ON cc.shelve = tc.`level` LEFT JOIN vn.collectionColors cc ON cc.shelve = tc.`level`
AND cc.wagon = tc.wagon AND cc.wagon = tc.wagon
AND cc.trainFk = c.trainFk AND cc.trainFk = c.trainFk
@ -24,12 +26,12 @@ SELECT c.itemPackingTypeFk,
JOIN vn.item i ON i.id = s.itemFk JOIN vn.item i ON i.id = s.itemFk
JOIN vn.itemType it ON it.id = i.typeFk JOIN vn.itemType it ON it.id = i.typeFk
JOIN vn.itemCategory ic ON ic.id = it.categoryFk JOIN vn.itemCategory ic ON ic.id = it.categoryFk
JOIN vn.worker w ON w.id = c.workerFk LEFT JOIN vn.worker w ON w.id = c.workerFk
JOIN vn.agencyMode am ON am.id = t.agencyModeFk JOIN vn.agencyMode am ON am.id = t.agencyModeFk
LEFT JOIN vn.ticketTrolley tt ON tt.ticket = t.id LEFT JOIN vn.ticketTrolley tt ON tt.ticket = t.id
LEFT JOIN vn.`zone` zo ON t.zoneFk = zo.id LEFT JOIN vn.`zone` zo ON t.zoneFk = zo.id
LEFT JOIN vn.routesMonitor rm ON rm.routeFk = t.routeFk LEFT JOIN vn.routesMonitor rm ON rm.routeFk = t.routeFk
LEFT JOIN vn.expeditionTruck et ON et.id = rm.expeditionTruckFk LEFT JOIN vn.expeditionTruck et ON et.id = rm.expeditionTruckFk
WHERE tc.ticketFk IN (?) WHERE t.id IN (?)
GROUP BY t.id GROUP BY t.id
ORDER BY cc.`code`; ORDER BY cc.`code`;