Merge branch 'dev' into 8657-app-status-pdf
gitea/salix/pipeline/pr-dev There was a failure building this commit
Details
gitea/salix/pipeline/pr-dev There was a failure building this commit
Details
This commit is contained in:
commit
b660c82ffa
|
@ -13,6 +13,11 @@ module.exports = Self => {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: 'Origin model from insert'
|
description: 'Origin model from insert'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
arg: 'description',
|
||||||
|
type: 'string',
|
||||||
|
description: 'Action description'
|
||||||
|
},
|
||||||
|
|
||||||
],
|
],
|
||||||
http: {
|
http: {
|
||||||
|
@ -21,7 +26,7 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.add = async(ctx, code, model, options) => {
|
Self.add = async(ctx, code, model, description, options) => {
|
||||||
const userId = ctx.req.accessToken.userId;
|
const userId = ctx.req.accessToken.userId;
|
||||||
const myOptions = {};
|
const myOptions = {};
|
||||||
|
|
||||||
|
@ -29,8 +34,8 @@ module.exports = Self => {
|
||||||
Object.assign(myOptions, options);
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
return await Self.rawSql(`
|
return await Self.rawSql(`
|
||||||
INSERT INTO workerActivity (workerFk, workerActivityTypeFk, model)
|
INSERT INTO workerActivity (workerFk, workerActivityTypeFk, model, description)
|
||||||
SELECT ?, ?, ?
|
SELECT ?, ?, ?, ?
|
||||||
FROM workerTimeControlConfig wtcc
|
FROM workerTimeControlConfig wtcc
|
||||||
LEFT JOIN (
|
LEFT JOIN (
|
||||||
SELECT wa.workerFk,
|
SELECT wa.workerFk,
|
||||||
|
@ -45,6 +50,6 @@ module.exports = Self => {
|
||||||
WHERE sub.workerFk IS NULL
|
WHERE sub.workerFk IS NULL
|
||||||
OR sub.code <> ?
|
OR sub.code <> ?
|
||||||
OR TIMESTAMPDIFF(SECOND, sub.created, util.VN_NOW()) > wtcc.dayBreak;`
|
OR TIMESTAMPDIFF(SECOND, sub.created, util.VN_NOW()) > wtcc.dayBreak;`
|
||||||
, [userId, code, model, userId, code], myOptions);
|
, [userId, code, model, description, userId, code], myOptions);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,7 +13,7 @@ describe('workerActivity insert()', () => {
|
||||||
{'code': 'TEST', 'description': 'TEST'}, options
|
{'code': 'TEST', 'description': 'TEST'}, options
|
||||||
);
|
);
|
||||||
|
|
||||||
await models.WorkerActivity.add(ctx, 'TEST', 'APP', options);
|
await models.WorkerActivity.add(ctx, 'TEST', 'APP', 'description', options);
|
||||||
|
|
||||||
count = await models.WorkerActivity.count(
|
count = await models.WorkerActivity.count(
|
||||||
{'workerFK': 1106}, options
|
{'workerFK': 1106}, options
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
-- Place your SQL code here
|
||||||
|
INSERT INTO salix.ACL (model,property,accessType,permission,principalType,principalId)
|
||||||
|
VALUES ('Worker','getWorkerBusiness','READ','ALLOW','ROLE','hr');
|
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
|
||||||
|
USE vn;
|
||||||
|
|
||||||
|
INSERT INTO vn.workerActivityType (code, description)
|
||||||
|
VALUES('SHELVING_CLEAN_START', 'SE INICIA LIMPIEZA CARRO'),
|
||||||
|
('SHELVING_CLEAN_STOP', 'SE FINALIZA LIMPIEZA CARRO');
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
const smtp = require('vn-print/core/smtp');
|
const smtp = require('vn-print/core/smtp');
|
||||||
const config = require('vn-print/core/config');
|
const config = require('vn-print/core/config');
|
||||||
|
const Email = require('vn-print/core/email');
|
||||||
|
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
Self.remoteMethodCtx('closeAll', {
|
Self.remoteMethodCtx('closeAll', {
|
||||||
|
@ -44,8 +45,7 @@ module.exports = Self => {
|
||||||
LIMIT 1`, [toDate, toDate], myOptions);
|
LIMIT 1`, [toDate, toDate], myOptions);
|
||||||
|
|
||||||
await Self.rawSql(`
|
await Self.rawSql(`
|
||||||
DROP TEMPORARY TABLE IF EXISTS tmp.ticket_close;
|
CREATE OR REPLACE TEMPORARY TABLE tmp.ticket_close
|
||||||
CREATE TEMPORARY TABLE tmp.ticket_close
|
|
||||||
ENGINE = MEMORY
|
ENGINE = MEMORY
|
||||||
WITH wTickets AS(
|
WITH wTickets AS(
|
||||||
SELECT t.id ticketFk
|
SELECT t.id ticketFk
|
||||||
|
@ -63,11 +63,12 @@ module.exports = Self => {
|
||||||
FROM wTicketsTracking wt
|
FROM wTicketsTracking wt
|
||||||
JOIN ticketTracking tt ON tt.id = wt.maxTracking
|
JOIN ticketTracking tt ON tt.id = wt.maxTracking
|
||||||
) SELECT tls.ticketFk,
|
) SELECT tls.ticketFk,
|
||||||
t.clientFk,
|
t.clientFk clientId,
|
||||||
c.name clientName,
|
c.name clientName,
|
||||||
c.email recipient,
|
c.email recipient,
|
||||||
|
c.isToBeMailed,
|
||||||
eu.email salesPersonEmail,
|
eu.email salesPersonEmail,
|
||||||
t.addressFk,
|
t.addressFk addressId,
|
||||||
c.hasDailyInvoice,
|
c.hasDailyInvoice,
|
||||||
c.hasToInvoiceByAddress,
|
c.hasToInvoiceByAddress,
|
||||||
t.totalWithVat,
|
t.totalWithVat,
|
||||||
|
@ -79,7 +80,7 @@ module.exports = Self => {
|
||||||
JOIN agencyMode am ON am.id = t.agencyModeFk
|
JOIN agencyMode am ON am.id = t.agencyModeFk
|
||||||
JOIN client c ON c.id = t.clientFk
|
JOIN client c ON c.id = t.clientFk
|
||||||
LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk
|
LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk
|
||||||
WHERE (al.code = 'PACKED' OR (am.code = 'refund' AND al.code <> 'delivered'));
|
WHERE al.code = 'PACKED' OR (am.code = 'refund' AND al.code <> 'delivered');
|
||||||
CALL ticket_close();
|
CALL ticket_close();
|
||||||
`, [dateFrom, dateTo], myOptions);
|
`, [dateFrom, dateTo], myOptions);
|
||||||
|
|
||||||
|
@ -98,21 +99,27 @@ module.exports = Self => {
|
||||||
AND tob.id IS NULL
|
AND tob.id IS NULL
|
||||||
AND t.routeFk`, [dateFrom, dateTo], myOptions);
|
AND t.routeFk`, [dateFrom, dateTo], myOptions);
|
||||||
|
|
||||||
const [clients] = await Self.rawSql(`
|
const clients = await Self.rawSql(`
|
||||||
SELECT clientFk clientId,
|
SELECT *,
|
||||||
clientName,
|
|
||||||
recipient,
|
|
||||||
salesPersonEmail,
|
|
||||||
addressFk addressId,
|
|
||||||
companyFk,
|
|
||||||
SUM(totalWithVat) total,
|
SUM(totalWithVat) total,
|
||||||
'quick' serialType
|
'quick' serialType
|
||||||
FROM tmp.ticket_close
|
FROM tmp.ticket_close
|
||||||
WHERE hasDailyInvoice
|
WHERE hasDailyInvoice
|
||||||
GROUP BY IF (hasToInvoiceByAddress, addressFk, clientFk), companyFk
|
GROUP BY IF (hasToInvoiceByAddress, addressId, clientId), companyFk
|
||||||
HAVING total > 0;
|
HAVING total > 0
|
||||||
|
`, [], myOptions);
|
||||||
|
|
||||||
|
const [ticketsToMail] = await Self.rawSql(`
|
||||||
|
SELECT *
|
||||||
|
FROM tmp.ticket_close
|
||||||
|
WHERE NOT hasDailyInvoice
|
||||||
|
AND isToBeMailed
|
||||||
|
AND salesPersonEmail IS NOT NULL
|
||||||
|
AND salesPersonEmail <> ''
|
||||||
|
AND recipient IS NOT NULL
|
||||||
|
AND recipient <> '';
|
||||||
DROP TEMPORARY TABLE tmp.ticket_close;
|
DROP TEMPORARY TABLE tmp.ticket_close;
|
||||||
`, [], myOptions);
|
`, [], myOptions);
|
||||||
|
|
||||||
if (tx)
|
if (tx)
|
||||||
await tx.commit();
|
await tx.commit();
|
||||||
|
@ -130,21 +137,23 @@ module.exports = Self => {
|
||||||
if (id)
|
if (id)
|
||||||
await Self.app.models.InvoiceOut.makePdfAndNotify(ctx, id, null, nestedTransaction);
|
await Self.app.models.InvoiceOut.makePdfAndNotify(ctx, id, null, nestedTransaction);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await Self.rawSql(`
|
await handleInvoicingError(error, client, failedClients);
|
||||||
INSERT INTO util.debug (variable, value)
|
}
|
||||||
VALUES ('invoicingTicketError', ?)
|
}
|
||||||
`, [client.clientId + ' - ' + error]);
|
|
||||||
|
|
||||||
if (error.responseCode == 450) {
|
for (const ticket of ticketsToMail) {
|
||||||
await invalidEmail(client);
|
const args = {
|
||||||
continue;
|
id: ticket.ticketFk,
|
||||||
}
|
recipientId: ticket.clientId,
|
||||||
|
recipient: ticket.recipient,
|
||||||
|
replyTo: ticket.salesPersonEmail,
|
||||||
|
};
|
||||||
|
|
||||||
failedClients.push({
|
try {
|
||||||
id: client.clientId,
|
const email = new Email('delivery-note-link', args);
|
||||||
address: client.addressId,
|
await email.send();
|
||||||
error
|
} catch (error) {
|
||||||
});
|
await handleInvoicingError(error, ticket, failedClients);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,4 +197,22 @@ module.exports = Self => {
|
||||||
html: body,
|
html: body,
|
||||||
}).catch(err => console.error(err));
|
}).catch(err => console.error(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleInvoicingError(error, entity, failedClients) {
|
||||||
|
await Self.rawSql(`
|
||||||
|
INSERT INTO util.debug (variable, value)
|
||||||
|
VALUES ('invoicingTicketError', ?)
|
||||||
|
`, [entity.clientId + ' - ' + error]);
|
||||||
|
|
||||||
|
if (error.responseCode == 450) {
|
||||||
|
await invalidEmail(entity);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
failedClients.push({
|
||||||
|
id: entity.clientId,
|
||||||
|
address: entity.addressId,
|
||||||
|
error
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,255 @@
|
||||||
|
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
||||||
|
const buildFilter = require('vn-loopback/util/filter').buildFilter;
|
||||||
|
const mergeFilters = require('vn-loopback/util/filter').mergeFilters;
|
||||||
|
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethodCtx('getWorkerBusiness', {
|
||||||
|
description: 'Returns an array of business from an specified worker',
|
||||||
|
accessType: 'READ',
|
||||||
|
accepts: [{
|
||||||
|
arg: 'id',
|
||||||
|
type: 'number',
|
||||||
|
required: true,
|
||||||
|
description: 'The worker id',
|
||||||
|
http: {source: 'path'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'filter',
|
||||||
|
type: 'object',
|
||||||
|
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'started',
|
||||||
|
type: 'date',
|
||||||
|
description: 'started',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'ended',
|
||||||
|
type: 'date',
|
||||||
|
description: 'ended',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'companyCodeFk',
|
||||||
|
type: 'string',
|
||||||
|
description: 'companyCodeFk',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'reasonEndFk',
|
||||||
|
type: 'number',
|
||||||
|
description: 'reasonEndFk',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'reasondEnd',
|
||||||
|
type: 'string',
|
||||||
|
description: 'reasondEnd',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'departmentFk',
|
||||||
|
type: 'number',
|
||||||
|
description: 'departmentFk',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'department',
|
||||||
|
type: 'string',
|
||||||
|
description: 'department',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'workerBusinessProfessionalCategoryFk',
|
||||||
|
type: 'number',
|
||||||
|
description: 'workerBusinessProfessionalCategoryFk',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'workerBusinessProfessionalCategory',
|
||||||
|
type: 'string',
|
||||||
|
description: 'workerBusinessProfessionalCategory',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'calendarTypeFk',
|
||||||
|
type: 'number',
|
||||||
|
description: 'calendarTypeFk',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'calendarType',
|
||||||
|
type: 'string',
|
||||||
|
description: 'calendarType',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'workcenterFk',
|
||||||
|
type: 'number',
|
||||||
|
description: 'workcenterFk',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'workCenter',
|
||||||
|
type: 'string',
|
||||||
|
description: 'workCenter',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'workerBusinessCategoryFk',
|
||||||
|
type: 'number',
|
||||||
|
description: 'WorkerBusinessCategoryFk',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'workerBusinessCategory',
|
||||||
|
type: 'string',
|
||||||
|
description: 'workerBusinessCategory',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'occupationCodeFk',
|
||||||
|
type: 'number',
|
||||||
|
description: 'occupationCodeFk',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'occupationCode',
|
||||||
|
type: 'string',
|
||||||
|
description: 'occupationCode',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'rate',
|
||||||
|
type: 'number',
|
||||||
|
description: 'rate',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'workerBusinessTypeFk',
|
||||||
|
type: 'number',
|
||||||
|
description: 'workerBusinessTypeFk',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'workerBusinessType',
|
||||||
|
type: 'string',
|
||||||
|
description: 'workerBusinessType',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'amount',
|
||||||
|
type: 'number',
|
||||||
|
description: 'amount',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'basicSalary',
|
||||||
|
type: 'number',
|
||||||
|
description: 'amount',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'notes',
|
||||||
|
type: 'string',
|
||||||
|
description: 'notes',
|
||||||
|
http: {source: 'query'}
|
||||||
|
}],
|
||||||
|
returns: {
|
||||||
|
type: ['object'],
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: '/:id/getWorkerBusiness',
|
||||||
|
verb: 'GET'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.getWorkerBusiness = async(ctx, id, filter, options) => {
|
||||||
|
const myOptions = {};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
let conn = Self.dataSource.connector;
|
||||||
|
let where = buildFilter(ctx.args, (param, value) => {
|
||||||
|
switch (param) {
|
||||||
|
case 'started':
|
||||||
|
case 'ended':
|
||||||
|
case 'companyCodeFk':
|
||||||
|
case 'reasonEndFk':
|
||||||
|
case 'reasondEnd':
|
||||||
|
case 'departmentFk':
|
||||||
|
case 'department':
|
||||||
|
case 'workerBusinessProfessionalCategoryFk':
|
||||||
|
case 'workerBusinessProfessionalCategory':
|
||||||
|
case 'calendarTypeFk':
|
||||||
|
case 'calendarType':
|
||||||
|
case 'workcenterFk':
|
||||||
|
case 'workCenter':
|
||||||
|
case 'workerBusinessCategoryFk':
|
||||||
|
case 'workerBusinessCategory':
|
||||||
|
case 'occupationCodeFk':
|
||||||
|
case 'occupationCode':
|
||||||
|
case 'rate':
|
||||||
|
case 'workerBusinessTypeFk':
|
||||||
|
case 'workerBusinessType':
|
||||||
|
case 'amount':
|
||||||
|
case 'basicSalary':
|
||||||
|
case 'notes':
|
||||||
|
}
|
||||||
|
});
|
||||||
|
where = {...where, ...{workerFk: id}};
|
||||||
|
filter = mergeFilters(filter, {where});
|
||||||
|
|
||||||
|
let stmts = [];
|
||||||
|
let stmt;
|
||||||
|
|
||||||
|
stmt = new ParameterizedSQL(
|
||||||
|
`SELECT * FROM(
|
||||||
|
SELECT b.id,
|
||||||
|
b.workerFk,
|
||||||
|
b.started,
|
||||||
|
b.ended,
|
||||||
|
b.companyCodeFk,
|
||||||
|
b.reasonEndFk,
|
||||||
|
bre.reason,
|
||||||
|
b.departmentFk,
|
||||||
|
d.name departmentName,
|
||||||
|
b.occupationCodeFk,
|
||||||
|
oc.name occupationName,
|
||||||
|
b.workerBusinessProfessionalCategoryFk,
|
||||||
|
pf.description professionalDescription,
|
||||||
|
b.calendarTypeFk,
|
||||||
|
ct.description calendarTypeDescription,
|
||||||
|
b.workcenterFk,
|
||||||
|
wc.name workCenterName,
|
||||||
|
b.workerBusinessCategoryFk,
|
||||||
|
py.description payrollDescription,
|
||||||
|
b.workerBusinessTypeFk,
|
||||||
|
wt.name workerBusinessTypeName,
|
||||||
|
b.amount,
|
||||||
|
b.basicSalary,
|
||||||
|
b.notes
|
||||||
|
FROM business b
|
||||||
|
LEFT JOIN businessReasonEnd bre ON bre.id = b.reasonEndFk
|
||||||
|
LEFT JOIN occupationCode oc ON oc.code = b.occupationCodeFk
|
||||||
|
LEFT JOIN department d ON d.id = b.departmentFk
|
||||||
|
LEFT JOIN professionalCategory pf ON pf.id = b.workerBusinessProfessionalCategoryFk
|
||||||
|
JOIN calendarType ct ON ct.id = b.calendarTypeFk
|
||||||
|
LEFT JOIN workCenter wc ON wc.id = b.workcenterFk
|
||||||
|
LEFT JOIN payrollCategories py ON py.id = b.workerBusinessCategoryFk
|
||||||
|
LEFT JOIN workerBusinessType wt ON wt.id = b.workerBusinessTypeFk
|
||||||
|
) sub
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
stmt.merge(conn.makeSuffix(filter));
|
||||||
|
stmts.push(stmt);
|
||||||
|
|
||||||
|
let sql = ParameterizedSQL.join(stmts, ';');
|
||||||
|
let result = await conn.executeStmt(sql, myOptions);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
};
|
|
@ -21,6 +21,7 @@ module.exports = Self => {
|
||||||
require('../methods/worker/setPassword')(Self);
|
require('../methods/worker/setPassword')(Self);
|
||||||
require('../methods/worker/getAvailablePda')(Self);
|
require('../methods/worker/getAvailablePda')(Self);
|
||||||
require('../methods/worker/myTeam')(Self);
|
require('../methods/worker/myTeam')(Self);
|
||||||
|
require('../methods/worker/getWorkerBusiness')(Self);
|
||||||
|
|
||||||
Self.canModifyAbsenceInPast = async(ctx, time) => {
|
Self.canModifyAbsenceInPast = async(ctx, time) => {
|
||||||
const hasPrivs = await Self.app.models.ACL.checkAccessAcl(ctx, 'Worker', 'canModifyAbsenceInPast', 'WRITE');
|
const hasPrivs = await Self.app.models.ACL.checkAccessAcl(ctx, 'Worker', 'canModifyAbsenceInPast', 'WRITE');
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
buttons:
|
||||||
|
webAcccess: Visita la nostra Web
|
||||||
|
info: Ajuda'ns a millorar
|
||||||
|
fiscalAddress: VERDNATURA LEVANTE SL, B97367486 C/ Fenollar, 2. 46680 ALGEMESÍ
|
||||||
|
· verdnatura.es · clientes@verdnatura.es
|
||||||
|
disclaimer: '- AVÍS - Aquest missatge és privat i confidencial, i ha de ser utilitzat
|
||||||
|
exclusivament per la persona destinatària del mateix. Si has rebut aquest missatge
|
||||||
|
per error, et preguem que ho comuniquis al remitent i esborres aquest missatge
|
||||||
|
i qualsevol document adjunt que pugui contenir. Verdnatura Levante SL no renuncia
|
||||||
|
a la confidencialitat ni a cap privilegi per causa de transmissió errònia o mal
|
||||||
|
funcionament. Igualment, no es fa responsable dels canvis, alteracions, errors
|
||||||
|
o omissions que es puguin fer al missatge un cop enviat.'
|
||||||
|
privacy: En compliment del que disposa la Llei Orgànica 15/1999, de Protecció de
|
||||||
|
Dades de Caràcter Personal, et comuniquem que les dades personals que facilitis
|
||||||
|
s'inclouran en fitxers automatitzats de VERDNATURA LEVANTE S.L., podent en tot
|
||||||
|
moment exercir els drets d'accés, rectificació, cancel·lació i oposició,
|
||||||
|
comunicant-ho per escrit al domicili social de l'entitat. La finalitat del
|
||||||
|
fitxer és la gestió administrativa, comptabilitat i facturació.
|
|
@ -0,0 +1,11 @@
|
||||||
|
subject: El teu albarà
|
||||||
|
title: El teu albarà
|
||||||
|
dear: Estimat client
|
||||||
|
description: Ja està disponible l'albarà corresponent a la comanda <strong>{0}</strong>. <br/>
|
||||||
|
Pots veure'l fent clic <a href="https://shop.verdnatura.es/#!form=ecomerce/ticket&ticket={0}">en aquest enllaç</a>.
|
||||||
|
copyLink: 'Com a alternativa, pots copiar el següent enllaç al teu navegador:'
|
||||||
|
poll: Si ho desitges, pots respondre a la nostra enquesta de satisfacció per
|
||||||
|
ajudar-nos a oferir un millor servei. La teva opinió és molt important per a nosaltres!
|
||||||
|
help: Qualsevol dubte que tinguis, no dubtis a consultar-nos, <strong>estem aquí
|
||||||
|
per atendre't!</strong>
|
||||||
|
conclusion: Gràcies per la teva atenció!
|
Loading…
Reference in New Issue