Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 4649-bookEntriesIncorrectly_notification
This commit is contained in:
commit
f056c26b0d
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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':
|
||||||
|
|
|
@ -51,14 +51,14 @@ module.exports = Self => {
|
||||||
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 observationType ot ON ot.code = 'delivery'
|
||||||
LEFT JOIN ticketObservation tob ON tob.ticketFk = t.id
|
LEFT JOIN ticketObservation tob ON tob.ticketFk = t.id
|
||||||
LEFT JOIN observationType ot ON tob.observationTypeFk = ot.id
|
AND tob.observationTypeFk = ot.id
|
||||||
AND ot.code = 'delivery'
|
|
||||||
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
|
||||||
|
|
|
@ -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
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
|
@ -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
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
require('../methods/worker-time-control-mail/checkInbox')(Self);
|
||||||
|
};
|
|
@ -50,3 +50,9 @@
|
||||||
.page-break-after {
|
.page-break-after {
|
||||||
page-break-after: always;
|
page-break-after: always;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ellipsize {
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -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">{{labelData.levelV}}</span></td>
|
<td rowspan="6"><span id="vertical" class="ellipsize">
|
||||||
<td id="ticketFk">{{labelData.ticketFk}} ⬸ {{labelData.clientFk}}</td>
|
{{labelData.collectionFk ? `${labelData.collectionFk} ~ ${labelData.wagon}-${labelData.level}` : '-'.repeat(23)}}
|
||||||
<td colspan="2" id="shipped">{{labelData.shipped}}</td>
|
</span></td>
|
||||||
|
<td id="ticketFk">
|
||||||
|
{{labelData.clientFk ? `${labelData.ticketFk} « ${labelData.clientFk}` : labelData.ticketFk}}
|
||||||
|
</td>
|
||||||
|
<td colspan="2" id="shipped">{{labelData.shipped ? labelData.shipped : '---'}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td rowspan="3"><div v-html="getBarcode(labelData.ticketFk)" id="barcode"></div></td>
|
<td rowspan="3"><div v-html="getBarcode(labelData.ticketFk)" id="barcode"></div></td>
|
||||||
<td class="outline">{{labelData.workerCode}}</td>
|
<td class="outline">{{labelData.workerCode ? labelData.workerCode : '---'}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="outline">{{labelData.labelCount}}</td>
|
<td class="outline">{{labelData.labelCount ? labelData.labelCount : 0}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="outline">{{labelData.size}}</td>
|
<td class="outline">{{labelData.code == 'plant' ? labelData.size + 'cm' : labelData.volume + 'm³'}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><div id="agencyDescripton">{{labelData.agencyDescription}}</div></td>
|
<td><div id="agencyDescripton" class="ellipsize">{{labelData.agencyDescription}}</div></td>
|
||||||
<td id="bold">{{labelData.lineCount}}</td>
|
<td id="bold">{{labelData.lineCount ? labelData.lineCount : 0}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td id="nickname">{{labelData.nickName}}</td>
|
<td id="nickname" class="ellipsize">{{labelData.nickName ? labelData.nickName : '---'}}</td>
|
||||||
<td id="bold">{{labelData.agencyHour}}</td>
|
<td id="bold">{{labelData.shipped ? labelData.shippedHour : labelData.zoneHour}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<template v-slot:footer>
|
</body>
|
||||||
<span></span>
|
</html>
|
||||||
</template>
|
|
||||||
</report-body>
|
|
|
@ -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);
|
||||||
},
|
},
|
||||||
|
|
|
@ -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"
|
||||||
},
|
},
|
||||||
|
|
|
@ -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)), 'm³') 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`;
|
Loading…
Reference in New Issue