231801_test_to_master #1519
|
@ -0,0 +1,3 @@
|
||||||
|
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
|
||||||
|
VALUES
|
||||||
|
('Receipt', 'receiptEmail', '*', 'ALLOW', 'ROLE', 'salesAssistant');
|
|
@ -17,6 +17,10 @@ class Controller extends Descriptor {
|
||||||
}
|
}
|
||||||
|
|
||||||
sendPickupOrder() {
|
sendPickupOrder() {
|
||||||
|
if (!this.claim.client.email) {
|
||||||
|
this.vnApp.showError(this.$t('The client does not have an email'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
return this.vnEmail.send(`Claims/${this.claim.id}/claim-pickup-email`, {
|
return this.vnEmail.send(`Claims/${this.claim.id}/claim-pickup-email`, {
|
||||||
recipient: this.claim.client.email,
|
recipient: this.claim.client.email,
|
||||||
recipientId: this.claim.clientFk
|
recipientId: this.claim.clientFk
|
||||||
|
|
|
@ -20,3 +20,4 @@ Photos: Fotos
|
||||||
Go to the claim: Ir a la reclamación
|
Go to the claim: Ir a la reclamación
|
||||||
Sale tracking: Líneas preparadas
|
Sale tracking: Líneas preparadas
|
||||||
Ticket tracking: Estados del ticket
|
Ticket tracking: Estados del ticket
|
||||||
|
The client does not have an email: El cliente no tiene email
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
const {Email} = require('vn-print');
|
||||||
|
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethodCtx('receiptEmail', {
|
||||||
|
description: 'Returns the receipt pdf',
|
||||||
|
accepts: [
|
||||||
|
{
|
||||||
|
arg: 'id',
|
||||||
|
type: 'number',
|
||||||
|
required: true,
|
||||||
|
description: 'The claim id',
|
||||||
|
http: {source: 'path'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'recipient',
|
||||||
|
type: 'string',
|
||||||
|
description: 'The recipient email',
|
||||||
|
required: true,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
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/receipt-email',
|
||||||
|
verb: 'POST'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.receiptEmail = async(ctx, id) => {
|
||||||
|
const args = Object.assign({}, ctx.args);
|
||||||
|
const params = {
|
||||||
|
recipient: args.recipient,
|
||||||
|
lang: ctx.req.getLocale()
|
||||||
|
};
|
||||||
|
|
||||||
|
delete args.ctx;
|
||||||
|
for (const param in args)
|
||||||
|
params[param] = args[param];
|
||||||
|
|
||||||
|
const email = new Email('receipt', params);
|
||||||
|
|
||||||
|
return email.send();
|
||||||
|
};
|
||||||
|
};
|
|
@ -1,12 +1,12 @@
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
Self.remoteMethodCtx('receiptPdf', {
|
Self.remoteMethodCtx('receiptPdf', {
|
||||||
description: 'Returns the receipt pdf',
|
description: 'Send the receipt pdf to client',
|
||||||
accepts: [
|
accepts: [
|
||||||
{
|
{
|
||||||
arg: 'id',
|
arg: 'id',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
required: true,
|
required: true,
|
||||||
description: 'The claim id',
|
description: 'The receipt id',
|
||||||
http: {source: 'path'}
|
http: {source: 'path'}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,6 +5,7 @@ module.exports = function(Self) {
|
||||||
require('../methods/receipt/balanceCompensationEmail')(Self);
|
require('../methods/receipt/balanceCompensationEmail')(Self);
|
||||||
require('../methods/receipt/balanceCompensationPdf')(Self);
|
require('../methods/receipt/balanceCompensationPdf')(Self);
|
||||||
require('../methods/receipt/receiptPdf')(Self);
|
require('../methods/receipt/receiptPdf')(Self);
|
||||||
|
require('../methods/receipt/receiptEmail')(Self);
|
||||||
|
|
||||||
Self.validateBinded('amountPaid', isNotZero, {
|
Self.validateBinded('amountPaid', isNotZero, {
|
||||||
message: 'Amount cannot be zero',
|
message: 'Amount cannot be zero',
|
||||||
|
|
|
@ -84,6 +84,10 @@
|
||||||
label="View receipt"
|
label="View receipt"
|
||||||
ng-model="$ctrl.viewReceipt">
|
ng-model="$ctrl.viewReceipt">
|
||||||
</vn-check>
|
</vn-check>
|
||||||
|
<vn-check
|
||||||
|
label="Send email"
|
||||||
|
ng-model="$ctrl.sendEmail">
|
||||||
|
</vn-check>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
</tpl-body>
|
</tpl-body>
|
||||||
<tpl-buttons>
|
<tpl-buttons>
|
||||||
|
|
|
@ -2,9 +2,10 @@ import ngModule from '../../module';
|
||||||
import Dialog from 'core/components/dialog';
|
import Dialog from 'core/components/dialog';
|
||||||
|
|
||||||
class Controller extends Dialog {
|
class Controller extends Dialog {
|
||||||
constructor($element, $, $transclude, vnReport) {
|
constructor($element, $, $transclude, vnReport, vnEmail) {
|
||||||
super($element, $, $transclude);
|
super($element, $, $transclude);
|
||||||
this.vnReport = vnReport;
|
this.vnReport = vnReport;
|
||||||
|
this.vnEmail = vnEmail;
|
||||||
this.receipt = {};
|
this.receipt = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +24,18 @@ class Controller extends Dialog {
|
||||||
|
|
||||||
set clientFk(value) {
|
set clientFk(value) {
|
||||||
this.receipt.clientFk = value;
|
this.receipt.clientFk = value;
|
||||||
|
|
||||||
|
const filter = {
|
||||||
|
fields: ['email'],
|
||||||
|
where: {
|
||||||
|
id: value
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.$http.get(`Clients/findOne`, {filter})
|
||||||
|
.then(res => {
|
||||||
|
this.receipt.email = res.data.email;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
get clientFk() {
|
get clientFk() {
|
||||||
|
@ -154,10 +167,13 @@ class Controller extends Dialog {
|
||||||
return super.responseHandler(response);
|
return super.responseHandler(response);
|
||||||
|
|
||||||
const exceededAmount = this.receipt.amountPaid > this.maxAmount;
|
const exceededAmount = this.receipt.amountPaid > this.maxAmount;
|
||||||
|
const isCash = this.bankSelection.accountingType.code == 'cash';
|
||||||
if (this.bankSelection.accountingType.code == 'cash' && exceededAmount)
|
if (isCash && exceededAmount)
|
||||||
return this.vnApp.showError(this.$t('Amount exceeded', {maxAmount: this.maxAmount}));
|
return this.vnApp.showError(this.$t('Amount exceeded', {maxAmount: this.maxAmount}));
|
||||||
|
|
||||||
|
if (isCash && this.sendEmail && !this.receipt.email)
|
||||||
|
return this.vnApp.showError(this.$t('There is no assigned email for this client'));
|
||||||
|
|
||||||
let receiptId;
|
let receiptId;
|
||||||
return this.$http.post(`Clients/${this.clientFk}/createReceipt`, this.receipt)
|
return this.$http.post(`Clients/${this.clientFk}/createReceipt`, this.receipt)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
|
@ -165,6 +181,13 @@ class Controller extends Dialog {
|
||||||
super.responseHandler(response);
|
super.responseHandler(response);
|
||||||
})
|
})
|
||||||
.then(() => this.vnApp.showSuccess(this.$t('Data saved!')))
|
.then(() => this.vnApp.showSuccess(this.$t('Data saved!')))
|
||||||
|
.then(() => {
|
||||||
|
if (!this.sendEmail || !isCash) return;
|
||||||
|
const params = {
|
||||||
|
recipient: this.receipt.email
|
||||||
|
};
|
||||||
|
this.vnEmail.send(`Receipts/${receiptId}/receipt-email`, params);
|
||||||
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
if (this.viewReceipt)
|
if (this.viewReceipt)
|
||||||
this.vnReport.show(`Receipts/${receiptId}/receipt-pdf`);
|
this.vnReport.show(`Receipts/${receiptId}/receipt-pdf`);
|
||||||
|
@ -178,7 +201,7 @@ class Controller extends Dialog {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller.$inject = ['$element', '$scope', '$transclude', 'vnReport'];
|
Controller.$inject = ['$element', '$scope', '$transclude', 'vnReport', 'vnEmail'];
|
||||||
|
|
||||||
ngModule.vnComponent('vnClientBalanceCreate', {
|
ngModule.vnComponent('vnClientBalanceCreate', {
|
||||||
slotTemplate: require('./index.html'),
|
slotTemplate: require('./index.html'),
|
||||||
|
|
|
@ -192,19 +192,19 @@
|
||||||
{{::buy.entryFk}}
|
{{::buy.entryFk}}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td number>{{::buy.buyingValue | currency: 'EUR':2}}</td>
|
<td number>{{::buy.buyingValue | currency: 'EUR':3}}</td>
|
||||||
<td number>{{::buy.freightValue | currency: 'EUR':2}}</td>
|
<td number>{{::buy.freightValue | currency: 'EUR':3}}</td>
|
||||||
<td number>{{::buy.comissionValue | currency: 'EUR':2}}</td>
|
<td number>{{::buy.comissionValue | currency: 'EUR':3}}</td>
|
||||||
<td number>{{::buy.packageValue | currency: 'EUR':2}}</td>
|
<td number>{{::buy.packageValue | currency: 'EUR':3}}</td>
|
||||||
<td>
|
<td>
|
||||||
<vn-check
|
<vn-check
|
||||||
disabled="true"
|
disabled="true"
|
||||||
ng-model="::buy.isIgnored">
|
ng-model="::buy.isIgnored">
|
||||||
</vn-check>
|
</vn-check>
|
||||||
</td>
|
</td>
|
||||||
<td number>{{::buy.price2 | currency: 'EUR':2}}</td>
|
<td number>{{::buy.price2 | currency: 'EUR':3}}</td>
|
||||||
<td number>{{::buy.price3 | currency: 'EUR':2}}</td>
|
<td number>{{::buy.price3 | currency: 'EUR':3}}</td>
|
||||||
<td number>{{::buy.minPrice | currency: 'EUR':2}}</td>
|
<td number>{{::buy.minPrice | currency: 'EUR':3}}</td>
|
||||||
<td>{{::buy.ektFk | dashIfEmpty}}</td>
|
<td>{{::buy.ektFk | dashIfEmpty}}</td>
|
||||||
<td>{{::buy.weight}}</td>
|
<td>{{::buy.weight}}</td>
|
||||||
<td>{{::buy.packageFk}}</td>
|
<td>{{::buy.packageFk}}</td>
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
<vn-autocomplete
|
<vn-autocomplete
|
||||||
vn-one
|
vn-one
|
||||||
ng-model="filter.requesterFk"
|
ng-model="filter.requesterFk"
|
||||||
url="Workers/activeWithRole"
|
url="Workers/activeWithInheritedRole"
|
||||||
search-function="{firstName: $search}"
|
search-function="{firstName: $search}"
|
||||||
value-field="id"
|
value-field="id"
|
||||||
where="{role: 'salesPerson'}"
|
where="{role: 'salesPerson'}"
|
||||||
|
|
|
@ -100,7 +100,7 @@ module.exports = Self => {
|
||||||
dmsTypeId: dmsType.id,
|
dmsTypeId: dmsType.id,
|
||||||
reference: '',
|
reference: '',
|
||||||
description: `Firma del cliente - Ruta ${ticket.route().id}`,
|
description: `Firma del cliente - Ruta ${ticket.route().id}`,
|
||||||
hasFile: true
|
hasFile: false
|
||||||
};
|
};
|
||||||
dms = await models.Dms.uploadFile(ctxUploadFile, myOptions);
|
dms = await models.Dms.uploadFile(ctxUploadFile, myOptions);
|
||||||
gestDocCreated = true;
|
gestDocCreated = true;
|
||||||
|
|
|
@ -326,8 +326,13 @@ class Controller extends Section {
|
||||||
|
|
||||||
return this.$http.post(`Docuwares/${this.id}/upload`, {fileCabinet: 'deliveryNote'})
|
return this.$http.post(`Docuwares/${this.id}/upload`, {fileCabinet: 'deliveryNote'})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.vnApp.showSuccess(this.$t('PDF sent!'));
|
this.$.balanceCreate.amountPaid = this.ticket.totalWithVat;
|
||||||
|
this.$.balanceCreate.clientFk = this.ticket.clientFk;
|
||||||
|
this.$.balanceCreate.description = 'Albaran: ';
|
||||||
|
this.$.balanceCreate.description += this.ticket.id;
|
||||||
|
|
||||||
this.$.balanceCreate.show();
|
this.$.balanceCreate.show();
|
||||||
|
this.vnApp.showSuccess(this.$t('PDF sent!'));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,11 @@
|
||||||
|
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/email.css`])
|
||||||
|
.mergeStyles();
|
|
@ -0,0 +1,6 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"filename": "receipt.pdf",
|
||||||
|
"component": "receipt"
|
||||||
|
}
|
||||||
|
]
|
|
@ -0,0 +1,5 @@
|
||||||
|
subject: Recibo
|
||||||
|
title: Recibo
|
||||||
|
dear: Estimado cliente
|
||||||
|
description: Ya está disponible el recibo <strong>{0}</strong>. <br/>
|
||||||
|
Puedes descargarlo haciendo clic en el adjunto de este correo.
|
|
@ -0,0 +1,9 @@
|
||||||
|
<email-body v-bind="$props">
|
||||||
|
<div class="grid-row">
|
||||||
|
<div class="grid-block vn-pa-ml">
|
||||||
|
<h1>{{ $t('title') }}</h1>
|
||||||
|
<p>{{$t('dear')}},</p>
|
||||||
|
<p v-html="$t('description', [id])"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</email-body>
|
|
@ -0,0 +1,15 @@
|
||||||
|
const Component = require(`vn-print/core/component`);
|
||||||
|
const emailBody = new Component('email-body');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'receipt',
|
||||||
|
components: {
|
||||||
|
'email-body': emailBody.build(),
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
id: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
Loading…
Reference in New Issue