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`
|
||||
SET `invoiceInFk`=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`)
|
||||
VALUES
|
||||
|
|
|
@ -37,7 +37,7 @@ export default class Controller extends Section {
|
|||
|
||||
const validations = window.validations;
|
||||
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.newProperties = this.getInstance(log.newInstance, locale);
|
||||
|
|
|
@ -91,7 +91,10 @@ module.exports = Self => {
|
|||
case 'search':
|
||||
return /^\d+$/.test(value)
|
||||
? {'c.id': {inq: value}}
|
||||
: {'c.name': {like: `%${value}%`}};
|
||||
: {or: [
|
||||
{'c.name': {like: `%${value}%`}},
|
||||
{'c.socialName': {like: `%${value}%`}},
|
||||
]};
|
||||
case 'name':
|
||||
case 'salesPersonFk':
|
||||
case 'fi':
|
||||
|
|
|
@ -33,36 +33,36 @@ module.exports = Self => {
|
|||
|
||||
const stmt = new ParameterizedSQL(
|
||||
`SELECT
|
||||
t.id,
|
||||
t.packages,
|
||||
t.warehouseFk,
|
||||
t.nickname,
|
||||
t.clientFk,
|
||||
t.priority,
|
||||
t.addressFk,
|
||||
st.code AS ticketStateCode,
|
||||
st.name AS ticketStateName,
|
||||
wh.name AS warehouseName,
|
||||
tob.description AS ticketObservation,
|
||||
a.street,
|
||||
a.postalCode,
|
||||
a.city,
|
||||
am.name AS agencyModeName,
|
||||
u.nickname AS userNickname,
|
||||
vn.ticketTotalVolume(t.id) AS volume,
|
||||
tob.description
|
||||
FROM route r
|
||||
JOIN ticket t ON t.routeFk = r.id
|
||||
LEFT JOIN ticketState ts ON ts.ticketFk = t.id
|
||||
LEFT JOIN state st ON st.id = ts.stateFk
|
||||
LEFT JOIN warehouse wh ON wh.id = t.warehouseFk
|
||||
LEFT JOIN ticketObservation tob ON tob.ticketFk = t.id
|
||||
LEFT JOIN observationType ot ON tob.observationTypeFk = ot.id
|
||||
AND ot.code = 'delivery'
|
||||
LEFT JOIN address a ON a.id = t.addressFk
|
||||
LEFT JOIN agencyMode am ON am.id = t.agencyModeFk
|
||||
LEFT JOIN account.user u ON u.id = r.workerFk
|
||||
LEFT JOIN vehicle v ON v.id = r.vehicleFk`
|
||||
t.id,
|
||||
t.packages,
|
||||
t.warehouseFk,
|
||||
t.nickname,
|
||||
t.clientFk,
|
||||
t.priority,
|
||||
t.addressFk,
|
||||
st.code AS ticketStateCode,
|
||||
st.name AS ticketStateName,
|
||||
wh.name AS warehouseName,
|
||||
tob.description AS ticketObservation,
|
||||
a.street,
|
||||
a.postalCode,
|
||||
a.city,
|
||||
am.name AS agencyModeName,
|
||||
u.nickname AS userNickname,
|
||||
vn.ticketTotalVolume(t.id) AS volume,
|
||||
tob.description
|
||||
FROM vn.route r
|
||||
JOIN ticket t ON t.routeFk = r.id
|
||||
LEFT JOIN ticketState ts ON ts.ticketFk = t.id
|
||||
LEFT JOIN state st ON st.id = ts.stateFk
|
||||
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
|
||||
AND tob.observationTypeFk = ot.id
|
||||
LEFT JOIN address a ON a.id = t.addressFk
|
||||
LEFT JOIN agencyMode am ON am.id = t.agencyModeFk
|
||||
LEFT JOIN account.user u ON u.id = r.workerFk
|
||||
LEFT JOIN vehicle v ON v.id = r.vehicleFk`
|
||||
);
|
||||
|
||||
if (!filter.where) filter.where = {};
|
||||
|
|
|
@ -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,
|
||||
d.isTeleworking
|
||||
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 business b ON b.id = tb.businessFk
|
||||
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: always;
|
||||
}
|
||||
|
||||
.ellipsize {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
html {
|
||||
font-family: "Roboto";
|
||||
margin-top: -7px;
|
||||
margin-top: -6px;
|
||||
}
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
|
@ -9,7 +9,7 @@ html {
|
|||
}
|
||||
#vertical {
|
||||
writing-mode: vertical-rl;
|
||||
height: 226px;
|
||||
height: 240px;
|
||||
margin-left: -13px;
|
||||
}
|
||||
.outline {
|
||||
|
@ -18,6 +18,7 @@ html {
|
|||
}
|
||||
#nickname {
|
||||
font-size: 22px;
|
||||
max-width: 50px;
|
||||
}
|
||||
#agencyDescripton {
|
||||
font-size: 32px;
|
||||
|
|
|
@ -1,35 +1,36 @@
|
|||
<report-body v-bind="$props">
|
||||
<template v-slot:header>
|
||||
<span></span>
|
||||
</template>
|
||||
<table v-for="labelData in labelsData">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td rowspan="6"><span id="vertical">{{labelData.levelV}}</span></td>
|
||||
<td id="ticketFk">{{labelData.ticketFk}} ⬸ {{labelData.clientFk}}</td>
|
||||
<td colspan="2" id="shipped">{{labelData.shipped}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="3"><div v-html="getBarcode(labelData.ticketFk)" id="barcode"></div></td>
|
||||
<td class="outline">{{labelData.workerCode}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="outline">{{labelData.labelCount}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="outline">{{labelData.size}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><div id="agencyDescripton">{{labelData.agencyDescription}}</div></td>
|
||||
<td id="bold">{{labelData.lineCount}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="nickname">{{labelData.nickName}}</td>
|
||||
<td id="bold">{{labelData.agencyHour}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<template v-slot:footer>
|
||||
<span></span>
|
||||
</template>
|
||||
</report-body>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<table v-for="labelData in labelsData" style="break-before: page">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td rowspan="6"><span id="vertical" class="ellipsize">
|
||||
{{labelData.collectionFk ? `${labelData.collectionFk} ~ ${labelData.wagon}-${labelData.level}` : '-'.repeat(23)}}
|
||||
</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>
|
||||
<td rowspan="3"><div v-html="getBarcode(labelData.ticketFk)" id="barcode"></div></td>
|
||||
<td class="outline">{{labelData.workerCode ? labelData.workerCode : '---'}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="outline">{{labelData.labelCount ? labelData.labelCount : 0}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="outline">{{labelData.code == 'plant' ? labelData.size + 'cm' : labelData.volume + 'm³'}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><div id="agencyDescripton" class="ellipsize">{{labelData.agencyDescription}}</div></td>
|
||||
<td id="bold">{{labelData.lineCount ? labelData.lineCount : 0}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="nickname" class="ellipsize">{{labelData.nickName ? labelData.nickName : '---'}}</td>
|
||||
<td id="bold">{{labelData.shipped ? labelData.shippedHour : labelData.zoneHour}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
|
@ -40,7 +40,7 @@ module.exports = {
|
|||
format: 'code128',
|
||||
displayValue: false,
|
||||
width: 3.8,
|
||||
height: 110,
|
||||
height: 115,
|
||||
});
|
||||
return xmlSerializer.serializeToString(svgNode);
|
||||
},
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
"width": "10.4cm",
|
||||
"height": "4.8cm",
|
||||
"margin": {
|
||||
"top": "0cm",
|
||||
"right": "0.5cm",
|
||||
"top": "0.3cm",
|
||||
"right": "0.6cm",
|
||||
"bottom": "0cm",
|
||||
"left": "0cm"
|
||||
},
|
||||
|
|
|
@ -1,21 +1,23 @@
|
|||
SELECT c.itemPackingTypeFk,
|
||||
CONCAT(tc.collectionFk, ' ', LEFT(cc.code, 4)) color,
|
||||
CONCAT(tc.collectionFk, ' ', SUBSTRING('ABCDEFGH',tc.wagon, 1), '-', tc.`level`) levelV,
|
||||
tc.ticketFk,
|
||||
LEFT(COALESCE(et.description, zo.name, am.name),12) agencyDescription,
|
||||
SELECT tc.collectionFk,
|
||||
SUBSTRING('ABCDEFGH', tc.wagon, 1) wagon,
|
||||
tc.`level`,
|
||||
t.id ticketFk,
|
||||
COALESCE(et.description, zo.name, am.name) agencyDescription,
|
||||
am.name,
|
||||
t.clientFk,
|
||||
CONCAT(CAST(SUM(sv.volume) AS DECIMAL(5, 2)), 'm³') m3 ,
|
||||
CAST(IF(ic.code = 'plant', CONCAT(MAX(i.`size`),' cm'), COUNT(*)) AS CHAR) size,
|
||||
CAST(SUM(sv.volume) AS DECIMAL(5, 2)) volume,
|
||||
MAX(i.`size`) `size`,
|
||||
ic.code,
|
||||
w.code workerCode,
|
||||
tt.labelCount,
|
||||
IF(HOUR(t.shipped), TIME_FORMAT(t.shipped, '%H:%i'), TIME_FORMAT(zo.`hour`, '%H:%i')) agencyHour,
|
||||
TIME_FORMAT(t.shipped, '%H:%i') shippedHour,
|
||||
TIME_FORMAT(zo.`hour`, '%H:%i') zoneHour,
|
||||
DATE_FORMAT(t.shipped, '%d/%m/%y') shipped,
|
||||
COUNT(*) lineCount,
|
||||
t.nickName
|
||||
t.nickName,
|
||||
tt.labelCount,
|
||||
COUNT(*) lineCount
|
||||
FROM vn.ticket t
|
||||
JOIN vn.ticketCollection tc ON tc.ticketFk = t.id
|
||||
JOIN vn.collection c ON c.id = tc.collectionFk
|
||||
LEFT JOIN vn.ticketCollection tc ON tc.ticketFk = t.id
|
||||
LEFT JOIN vn.collection c ON c.id = tc.collectionFk
|
||||
LEFT JOIN vn.collectionColors cc ON cc.shelve = tc.`level`
|
||||
AND cc.wagon = tc.wagon
|
||||
AND cc.trainFk = c.trainFk
|
||||
|
@ -24,12 +26,12 @@ SELECT c.itemPackingTypeFk,
|
|||
JOIN vn.item i ON i.id = s.itemFk
|
||||
JOIN vn.itemType it ON it.id = i.typeFk
|
||||
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
|
||||
LEFT JOIN vn.ticketTrolley tt ON tt.ticket = t.id
|
||||
LEFT JOIN vn.`zone` zo ON t.zoneFk = zo.id
|
||||
LEFT JOIN vn.routesMonitor rm ON rm.routeFk = t.routeFk
|
||||
LEFT JOIN vn.expeditionTruck et ON et.id = rm.expeditionTruckFk
|
||||
WHERE tc.ticketFk IN (?)
|
||||
WHERE t.id IN (?)
|
||||
GROUP BY t.id
|
||||
ORDER BY cc.`code`;
|
Loading…
Reference in New Issue