5995-newCmr #1698
|
@ -0,0 +1,36 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethodCtx('cmr', {
|
||||||
|
description: 'Returns the cmr',
|
||||||
|
accessType: 'READ',
|
||||||
|
accepts: [
|
||||||
|
{
|
||||||
|
arg: 'id',
|
||||||
|
type: 'number',
|
||||||
|
required: true,
|
||||||
|
description: 'The cmr id',
|
||||||
|
http: {source: 'path'}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
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/cmr',
|
||||||
|
verb: 'GET'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.cmr = (ctx, id) => Self.printReport(ctx, id, 'cmr');
|
||||||
|
};
|
|
@ -14,6 +14,7 @@ module.exports = Self => {
|
||||||
require('../methods/route/driverRouteEmail')(Self);
|
require('../methods/route/driverRouteEmail')(Self);
|
||||||
require('../methods/route/sendSms')(Self);
|
require('../methods/route/sendSms')(Self);
|
||||||
require('../methods/route/downloadZip')(Self);
|
require('../methods/route/downloadZip')(Self);
|
||||||
|
require('../methods/route/cmr')(Self);
|
||||||
|
|
||||||
Self.validate('kmStart', validateDistance, {
|
Self.validate('kmStart', validateDistance, {
|
||||||
message: 'Distance must be lesser than 1000'
|
message: 'Distance must be lesser than 1000'
|
||||||
|
@ -28,5 +29,5 @@ module.exports = Self => {
|
||||||
const routeMaxKm = 1000;
|
const routeMaxKm = 1000;
|
||||||
if (routeTotalKm > routeMaxKm || this.kmStart > this.kmEnd)
|
if (routeTotalKm > routeMaxKm || this.kmStart > this.kmEnd)
|
||||||
err();
|
err();
|
||||||
}
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -120,7 +120,7 @@ module.exports = async function(ctx, Self, tickets, reqArgs = {}) {
|
||||||
await Self.rawSql(`
|
await Self.rawSql(`
|
||||||
INSERT INTO clientSample (clientFk, typeFk, companyFk) VALUES(?, ?, ?)
|
INSERT INTO clientSample (clientFk, typeFk, companyFk) VALUES(?, ?, ?)
|
||||||
`, [ticket.clientFk, sample.id, ticket.companyFk], {userId});
|
`, [ticket.clientFk, sample.id, ticket.companyFk], {userId});
|
||||||
}
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Domain not found
|
// Domain not found
|
||||||
if (error.responseCode == 450)
|
if (error.responseCode == 450)
|
||||||
|
|
|
@ -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,101 @@
|
||||||
|
html {
|
||||||
|
font-family: "Roboto", "Helvetica", "Arial", sans-serif;
|
||||||
|
margin: 10px;
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
.mainTable, .specialTable, .categoryTable {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
font-size: inherit;
|
||||||
|
}
|
||||||
|
.mainTable td {
|
||||||
|
width: 50%;
|
||||||
|
border: 1px solid black;
|
||||||
|
vertical-align: top;
|
||||||
|
padding: 15px;
|
||||||
|
font-size: inherit;
|
||||||
|
}
|
||||||
|
.signTable {
|
||||||
|
height: 12%;
|
||||||
|
}
|
||||||
|
.signTable td {
|
||||||
|
width: calc(100% / 3);
|
||||||
|
border: 1px solid black;
|
||||||
|
vertical-align: top;
|
||||||
|
font-size: inherit;
|
||||||
|
padding: 15px;
|
||||||
|
border-top: none;
|
||||||
|
}
|
||||||
|
#title {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 85px;
|
||||||
|
}
|
||||||
|
hr {
|
||||||
|
border: 1px solid #cccccc;
|
||||||
|
height: 0px;
|
||||||
|
border-radius: 25px;
|
||||||
|
}
|
||||||
|
#cellHeader {
|
||||||
|
border: 0px;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
#label, #merchandiseLabels {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
#merchandiseLabels {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
.imgSection {
|
||||||
|
text-align: center;
|
||||||
|
height: 200px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
object-fit: contain;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
#lineBreak {
|
||||||
|
white-space: pre-line;
|
||||||
|
}
|
||||||
|
.specialTable td {
|
||||||
|
border: 1px solid black;
|
||||||
|
vertical-align: top;
|
||||||
|
padding: 15px;
|
||||||
|
font-size: inherit;
|
||||||
|
border-top: none;
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
.specialTable #itemCategoryList {
|
||||||
|
width: 70%;
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
.categoryTable {
|
||||||
|
padding-bottom: none;
|
||||||
|
}
|
||||||
|
.categoryTable td {
|
||||||
|
vertical-align: top;
|
||||||
|
font-size: inherit;
|
||||||
|
border: none;
|
||||||
|
padding: 5px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.categoryTable #merchandiseLabels {
|
||||||
|
border-bottom: 4px solid #cccccc;
|
||||||
|
padding: none;
|
||||||
|
}
|
||||||
|
#merchandiseDetail {
|
||||||
|
font-weight: bold;
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
#merchandiseData {
|
||||||
|
font-weight: bold;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
#merchandiseLabels td {
|
||||||
|
padding-bottom: 11px;
|
||||||
|
max-width: 300px;
|
||||||
|
}
|
|
@ -0,0 +1,212 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<table class="mainTable">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<span id="label">1. Remitente / Expediteur / Sender</span>
|
||||||
|
<hr>
|
||||||
|
<b>{{data.senderName}}</b><br>
|
||||||
|
{{data.senderStreet}}<br>
|
||||||
|
{{data.senderPostCode}} {{data.senderCity}} {{(data.senderCountry) ? `(${data.senderCountry})` : null}}
|
||||||
|
</td>
|
||||||
|
<td id="cellHeader">
|
||||||
|
<span id="title">CMR</span><br>
|
||||||
|
{{data.cmrFk}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<span id="label">2. Consignatario / Destinataire / Consignee</span>
|
||||||
|
<hr>
|
||||||
|
<b>{{data.deliveryAddressFk}}<br>
|
||||||
|
{{data.deliveryName}}<br>
|
||||||
|
{{data.deliveryPhone || data.clientPhone}}
|
||||||
|
{{((data.deliveryPhone || data.clientPhone) && data.deliveryMobile) ? '/' : null}}
|
||||||
|
{{data.deliveryMobile}}</b>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span id="label">16. Transportista / Transporteur / Carrier</span>
|
||||||
|
<hr>
|
||||||
|
<b>{{data.carrierName}}</b><br>
|
||||||
|
{{data.carrierStreet}}<br>
|
||||||
|
{{data.carrierPostalCode}} {{data.carrierCity}} {{(data.carrierCountry) ? `(${data.carrierCountry})` : null}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<span id="label">
|
||||||
|
3. Lugar y fecha de entrega /
|
||||||
|
Lieu et date de livraison /
|
||||||
|
Place and date of delivery
|
||||||
|
</span>
|
||||||
|
<hr>
|
||||||
|
<b>{{data.deliveryStreet}}<br>
|
||||||
|
{{data.deliveryPostalCode}} {{data.deliveryCity}} {{(data.deliveryCountry) ? `(${data.deliveryCountry})` : null}}<br>
|
||||||
|
{{(data.ead) ? formatDate(data.ead, '%d/%m/%Y') : null}}</b>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span id="label">17. Porteadores sucesivos / Transporteurs succesifs / Succesive Carriers</span>
|
||||||
|
<hr>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<span id="label">
|
||||||
|
4. Lugar y fecha de carga /
|
||||||
|
Lieu et date del prise en charge de la merchandise /
|
||||||
|
Place and date of taking over the goods
|
||||||
|
</span>
|
||||||
|
<hr>
|
||||||
|
<b>{{data.loadStreet}}<br>
|
||||||
|
{{data.loadPostalCode}} {{data.loadCity}} {{(data.loadCountry) ? `(${data.loadCountry})` : null}}<br>
|
||||||
|
{{formatDate(data.created, '%d/%m/%Y')}}</b>
|
||||||
|
</td>
|
||||||
|
<td rowspan="2">
|
||||||
|
<span id="label">
|
||||||
|
18. Obervaciones del transportista /
|
||||||
|
Reserves et observations du transporteur /
|
||||||
|
Carrier's reservations and observations
|
||||||
|
</span>
|
||||||
|
<hr>
|
||||||
|
<b>{{data.truckPlate}}</b><br>
|
||||||
|
{{data.observations}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<span id="label">5. Documentos anexos / Documents annexes / Documents attached</span>
|
||||||
|
<hr>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<table class="specialTable">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<span id="label">
|
||||||
|
7 & 8. Número de bultos y clase de embalage /
|
||||||
|
Number of packages and packaging class /
|
||||||
|
Nombre de colis et classe d'emballage
|
||||||
|
</span>
|
||||||
|
<hr>
|
||||||
|
<div id="lineBreak">
|
||||||
|
<b>{{data.packagesList}}</b>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td id="itemCategoryList">
|
||||||
|
<table class="categoryTable">
|
||||||
|
<tr id="merchandiseLabels">
|
||||||
|
<td>6. Marcas y números / Brands and numbers / Marques et numéros</td>
|
||||||
|
<td>9. Naturaleza de la merc. / Nature of goods / Nature des marchandises</td>
|
||||||
|
<td>10. nº Estadístico / Statistical no. / n° statistique</td>
|
||||||
|
<td>11. Peso bruto / Gross weight / Poids brut (kg)</td>
|
||||||
|
<td>12. Volumen / Volume (m3)</td>
|
||||||
|
</tr>
|
||||||
|
<tr v-for="merchandise in merchandises" id="merchandiseData">
|
||||||
|
<td>{{merchandise.ticketFk}}</td>
|
||||||
|
<td>{{merchandise.name}}</td>
|
||||||
|
<td>N/A</td>
|
||||||
|
<td>{{merchandise.weight}}</td>
|
||||||
|
<td>{{merchandise.volume}}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<div v-if="!merchandises" id="merchandiseDetail">
|
||||||
|
{{data.merchandiseDetail}}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<table class="mainTable">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<span id="label">
|
||||||
|
13. Instrucciones del remitente /
|
||||||
|
Instrunstions de l'expèditeur / Sender
|
||||||
|
instruccions
|
||||||
|
</span>
|
||||||
|
<hr>
|
||||||
|
<b>{{data.senderInstruccions}}</b>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span id="label">
|
||||||
|
19. Estipulaciones particulares /
|
||||||
|
Conventions particulieres /
|
||||||
|
Special agreements
|
||||||
|
</span>
|
||||||
|
<hr>
|
||||||
|
<b>{{data.specialAgreements}}</b>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<span id="label">
|
||||||
|
14. Forma de pago /
|
||||||
|
Prescriptions d'affranchissement /
|
||||||
|
Instruction as to payment for carriage
|
||||||
|
</span>
|
||||||
|
<hr>
|
||||||
|
<b>{{data.paymentInstruccions}}</b>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span id="label">20. A pagar por / Être payé pour / To be paid by</span>
|
||||||
|
<hr>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<span id="label">21. Formalizado en / Etabile a / Estabilshed in</span>
|
||||||
|
<hr>
|
||||||
|
<b>{{data.loadStreet}}</b><br>
|
||||||
|
{{data.loadPostalCode}} {{data.loadCity}} {{(data.loadCountry) ? `(${data.loadCountry})` : null}} <br>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span id="label">15. Reembolso / Remboursement / Cash on delivery</span>
|
||||||
|
<hr>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<table class="signTable">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<span id="label">
|
||||||
|
22. Firma y sello del remitente /
|
||||||
|
Signature et timbre de l'expèditeur /
|
||||||
|
Signature and stamp of the sender
|
||||||
|
</span>
|
||||||
|
<hr>
|
||||||
|
<div class="imgSection">
|
||||||
|
<img :src="senderStamp"/>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span id="label">
|
||||||
|
23. Firma y sello del transportista /
|
||||||
|
Signature et timbre du transporteur /
|
||||||
|
Signature and stamp of the carrier
|
||||||
|
</span>
|
||||||
|
<hr>
|
||||||
|
<div class="imgSection">
|
||||||
|
<img :src="deliveryStamp"/>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span id="label">
|
||||||
|
24. Firma y sello del consignatario /
|
||||||
|
Signature et timbre du destinataire /
|
||||||
|
Signature and stamp of the consignee
|
||||||
|
</span>
|
||||||
|
<hr>
|
||||||
|
<div class="imgSection">
|
||||||
|
<img :src="signPath"/>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
|
@ -0,0 +1,45 @@
|
||||||
|
const config = require(`vn-print/core/config`);
|
||||||
|
const vnReport = require('../../../core/mixins/vn-report.js');
|
||||||
|
const md5 = require('md5');
|
||||||
|
const fs = require('fs-extra');
|
||||||
|
|
||||||
|
const prefixBase64 = 'data:image/png;base64,';
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'cmr',
|
||||||
|
mixins: [vnReport],
|
||||||
|
async serverPrefetch() {
|
||||||
|
this.data = await this.findOneFromDef('data', [this.id]);
|
||||||
|
if (this.data.ticketFk) {
|
||||||
|
this.merchandises = await this.rawSqlFromDef('merchandise', [this.data.ticketFk]);
|
||||||
|
this.signature = await this.findOneFromDef('signature', [this.data.ticketFk]);
|
||||||
|
} else
|
||||||
|
this.merchandises = null;
|
||||||
|
|
||||||
|
this.senderStamp = (this.data.senderStamp)
|
||||||
|
? `${prefixBase64} ${this.data.senderStamp.toString('base64')}`
|
||||||
|
: null;
|
||||||
|
this.deliveryStamp = (this.data.deliveryStamp)
|
||||||
|
? `${prefixBase64} ${this.data.deliveryStamp.toString('base64')}`
|
||||||
|
: null;
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
id: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
description: 'The cmr id'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
signPath() {
|
||||||
|
if (!this.signature) return;
|
||||||
|
|
||||||
|
const signatureName = this.signature.signature
|
||||||
|
const hash = md5(signatureName.toString()).substring(0, 3);
|
||||||
|
const file = `${config.storage.root}/${hash}/${signatureName}.png`;
|
||||||
|
if (!fs.existsSync(file)) return null;
|
||||||
|
|
||||||
|
return `${prefixBase64} ${Buffer.from(fs.readFileSync(file), 'utf8').toString('base64')}`;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1 @@
|
||||||
|
reportName: cmr
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"format": "A4"
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
SELECT c.id cmrFk,
|
||||||
|
t.id ticketFk,
|
||||||
|
c.truckPlate,
|
||||||
|
c.observations,
|
||||||
|
c.senderInstruccions,
|
||||||
|
c.paymentInstruccions,
|
||||||
|
c.specialAgreements,
|
||||||
|
c.created,
|
||||||
|
c.packagesList,
|
||||||
|
c.merchandiseDetail,
|
||||||
|
c.ead,
|
||||||
|
s.name carrierName,
|
||||||
|
s.street carrierStreet,
|
||||||
|
s.postCode carrierPostCode,
|
||||||
|
s.city carrierCity,
|
||||||
|
cou.country carrierCountry,
|
||||||
|
s2.name senderName,
|
||||||
|
s2.street senderStreet,
|
||||||
|
s2.postCode senderPostCode,
|
||||||
|
s2.city senderCity,
|
||||||
|
cou2.country senderCountry,
|
||||||
|
a.street deliveryStreet,
|
||||||
|
a.id deliveryAddressFk,
|
||||||
|
a.postalCode deliveryPostalCode,
|
||||||
|
a.city deliveryCity,
|
||||||
|
a.nickname deliveryName,
|
||||||
|
a.phone deliveryPhone,
|
||||||
|
a.mobile deliveryMobile,
|
||||||
|
cou3.country deliveryCountry,
|
||||||
|
cl.phone clientPhone,
|
||||||
|
a2.street loadStreet,
|
||||||
|
a2.postalCode loadPostalCode,
|
||||||
|
a2.city loadCity,
|
||||||
|
cou4.country loadCountry,
|
||||||
|
co.stamp senderStamp,
|
||||||
|
s.stamp deliveryStamp
|
||||||
|
FROM cmr c
|
||||||
|
LEFT JOIN supplier s ON s.id = c.supplierFk
|
||||||
|
LEFT JOIN country cou ON cou.id = s.countryFk
|
||||||
|
LEFT JOIN company co ON co.id = c.companyFk
|
||||||
|
LEFT JOIN supplierAccount sa ON sa.id = co.supplierAccountFk
|
||||||
|
LEFT JOIN supplier s2 ON s2.id = sa.supplierFk
|
||||||
|
LEFT JOIN country cou2 ON cou2.id = s2.countryFk
|
||||||
|
LEFT JOIN `address` a ON a.id = c.addressToFk
|
||||||
|
LEFT JOIN province p ON p.id = a.provinceFk
|
||||||
|
LEFT JOIN country cou3 ON cou3.id = p.countryFk
|
||||||
|
LEFT JOIN client cl ON cl.id = a.clientFk
|
||||||
|
LEFT JOIN `address` a2 ON a2.id = c.addressFromFk
|
||||||
|
LEFT JOIN province p2 ON p2.id = a2.provinceFk
|
||||||
|
LEFT JOIN country cou4 ON cou4.id = p2.countryFk
|
||||||
|
LEFT JOIN ticket t ON t.cmrFk = c.id
|
||||||
|
WHERE c.id = ?
|
|
@ -0,0 +1,11 @@
|
||||||
|
SELECT s.ticketFk,
|
||||||
|
ic.name,
|
||||||
|
CAST(SUM(sv.weight) AS DECIMAL(10,2)) `weight`,
|
||||||
|
CAST(SUM(sv.volume) AS DECIMAL(10,3)) volume
|
||||||
|
FROM sale s
|
||||||
|
JOIN saleVolume sv ON sv.saleFk = s.id
|
||||||
|
JOIN item i ON i.id = s.itemFk
|
||||||
|
JOIN itemType it ON it.id = i.typeFk
|
||||||
|
JOIN itemCategory ic ON ic.id = it.categoryFk
|
||||||
|
WHERE sv.ticketFk = ?
|
||||||
|
GROUP BY ic.id
|
|
@ -0,0 +1,5 @@
|
||||||
|
SELECT dc.id `signature`
|
||||||
|
FROM ticket t
|
||||||
|
JOIN ticketDms dt ON dt.ticketFk = t.id
|
||||||
|
LEFT JOIN dms dc ON dc.id = dt.dmsFk
|
||||||
|
WHERE t.id = ?
|
Loading…
Reference in New Issue