Merge pull request 'refactor(invoice): Show generate PDF option if it was never generated before' (#744) from 3162-invoice_generate into dev
gitea/salix/pipeline/head This commit looks good Details

Reviewed-on: #744
This commit is contained in:
Joan Sanchez 2021-10-01 12:53:42 +00:00
commit 892282b182
16 changed files with 64 additions and 26 deletions

View File

@ -0,0 +1 @@
UPDATE salix.ACL t SET t.principalId = 'employee' WHERE t.id = 269;

View File

@ -489,11 +489,11 @@ INSERT INTO `vn`.`invoiceOutSerial` (`code`, `description`, `isTaxed`, `taxAreaF
INSERT INTO `vn`.`invoiceOut`(`id`, `serial`, `amount`, `issued`,`clientFk`, `created`, `companyFk`, `dued`, `booked`, `bankFk`, `hasPdf`) INSERT INTO `vn`.`invoiceOut`(`id`, `serial`, `amount`, `issued`,`clientFk`, `created`, `companyFk`, `dued`, `booked`, `bankFk`, `hasPdf`)
VALUES VALUES
(1, 'T', 1014.24, CURDATE(), 1101, CURDATE(), 442, CURDATE(), CURDATE(), 1, 1), (1, 'T', 1014.24, CURDATE(), 1101, CURDATE(), 442, CURDATE(), CURDATE(), 1, 0),
(2, 'T', 121.36, CURDATE(), 1102, CURDATE(), 442, CURDATE(), CURDATE(), 1, 1), (2, 'T', 121.36, CURDATE(), 1102, CURDATE(), 442, CURDATE(), CURDATE(), 1, 0),
(3, 'T', 8.88, CURDATE(), 1103, CURDATE(), 442, CURDATE(), CURDATE(), 1, 1), (3, 'T', 8.88, CURDATE(), 1103, CURDATE(), 442, CURDATE(), CURDATE(), 1, 0),
(4, 'T', 8.88, CURDATE(), 1103, CURDATE(), 442, CURDATE(), CURDATE(), 1, 1), (4, 'T', 8.88, CURDATE(), 1103, CURDATE(), 442, CURDATE(), CURDATE(), 1, 0),
(5, 'A', 8.88, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1103, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 442, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 1); (5, 'A', 8.88, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1103, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 442, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 0);
UPDATE `vn`.`invoiceOut` SET ref = 'T1111111' WHERE id = 1; UPDATE `vn`.`invoiceOut` SET ref = 'T1111111' WHERE id = 1;
UPDATE `vn`.`invoiceOut` SET ref = 'T2222222' WHERE id = 2; UPDATE `vn`.`invoiceOut` SET ref = 'T2222222' WHERE id = 2;

View File

@ -29,7 +29,7 @@ module.exports = Self => {
const models = Self.app.models; const models = Self.app.models;
const headers = ctx.req.headers; const headers = ctx.req.headers;
const origin = headers.origin; const origin = headers.origin;
const authorization = ctx.req.accessToken.id; const auth = ctx.req.accessToken;
if (process.env.NODE_ENV == 'test') if (process.env.NODE_ENV == 'test')
throw new UserError(`Action not allowed on the test environment`); throw new UserError(`Action not allowed on the test environment`);
@ -48,13 +48,18 @@ module.exports = Self => {
let fileSrc; let fileSrc;
try { try {
const invoiceOut = await Self.findById(id, null, myOptions); const invoiceOut = await Self.findById(id, null, myOptions);
const hasInvoicing = await models.Account.hasRole(auth.userId, 'invoicing', myOptions);
if (invoiceOut.hasPdf && !hasInvoicing)
throw new UserError(`You don't have enough privileges`);
await invoiceOut.updateAttributes({ await invoiceOut.updateAttributes({
hasPdf: true hasPdf: true
}, myOptions); }, myOptions);
const response = got.stream(`${origin}/api/report/invoice`, { const response = got.stream(`${origin}/api/report/invoice`, {
query: { query: {
authorization: authorization, authorization: auth.id,
invoiceId: id invoiceId: id
} }
}); });

View File

@ -61,9 +61,12 @@ describe('InvoiceOut filter()', () => {
} }
}; };
const invoiceOut = await models.InvoiceOut.findById(1, null, options);
await invoiceOut.updateAttribute('hasPdf', true, options);
const result = await models.InvoiceOut.filter(ctx, {}, options); const result = await models.InvoiceOut.filter(ctx, {}, options);
expect(result.length).toEqual(5); expect(result.length).toEqual(1);
await tx.rollback(); await tx.rollback();
} catch (e) { } catch (e) {

View File

@ -1,5 +1,8 @@
<vn-portal slot="menu"> <vn-portal slot="menu">
<vn-invoice-out-descriptor invoice-out="$ctrl.invoiceOut"></vn-invoice-out-descriptor> <vn-invoice-out-descriptor
invoice-out="$ctrl.invoiceOut"
card-reload="$ctrl.reload()">
</vn-invoice-out-descriptor>
<vn-left-menu source="card"></vn-left-menu> <vn-left-menu source="card"></vn-left-menu>
</vn-portal> </vn-portal>
<ui-view></ui-view> <ui-view></ui-view>

View File

@ -10,7 +10,8 @@ class Controller extends ModuleCard {
'issued', 'issued',
'amount', 'amount',
'clientFk', 'clientFk',
'companyFk' 'companyFk',
'hasPdf'
], ],
include: [ include: [
{ {

View File

@ -33,11 +33,10 @@
</vn-item> </vn-item>
<vn-item <vn-item
ng-click="createInvoicePdfConfirmation.show()" ng-click="createInvoicePdfConfirmation.show()"
vn-acl="invoicing" ng-show="$ctrl.hasInvoicing || !$ctrl.invoiceOut.hasPdf"
vn-acl-action="remove"
name="regenerateInvoice" name="regenerateInvoice"
translate> translate>
Regenerate invoice PDF {{!$ctrl.invoiceOut.hasPdf ? 'Generate PDF invoice': 'Regenerate PDF invoice'}}
</vn-item> </vn-item>
</slot-menu> </slot-menu>
<slot-body> <slot-body>
@ -101,8 +100,8 @@
<vn-confirm <vn-confirm
vn-id="createInvoicePdfConfirmation" vn-id="createInvoicePdfConfirmation"
on-accept="$ctrl.createInvoicePdf()" on-accept="$ctrl.createInvoicePdf()"
question="Are you sure you want to regenerate the invoice PDF document?" question="Are you sure you want to generate/regenerate the PDF invoice?"
message="You are going to regenerate the invoice PDF document"> message="Generate PDF invoice document">
</vn-confirm> </vn-confirm>
<!-- Send invoice confirmation popup --> <!-- Send invoice confirmation popup -->

View File

@ -10,6 +10,10 @@ class Controller extends Descriptor {
this.entity = value; this.entity = value;
} }
get hasInvoicing() {
return this.aclService.hasAny(['invoicing']);
}
deleteInvoiceOut() { deleteInvoiceOut() {
return this.$http.post(`InvoiceOuts/${this.id}/delete`) return this.$http.post(`InvoiceOuts/${this.id}/delete`)
.then(() => this.$state.go('invoiceOut.index')) .then(() => this.$state.go('invoiceOut.index'))
@ -25,6 +29,7 @@ class Controller extends Descriptor {
createInvoicePdf() { createInvoicePdf() {
const invoiceId = this.invoiceOut.id; const invoiceId = this.invoiceOut.id;
return this.$http.post(`InvoiceOuts/${invoiceId}/createPdf`) return this.$http.post(`InvoiceOuts/${invoiceId}/createPdf`)
.then(() => this.reload())
.then(() => { .then(() => {
const snackbarMessage = this.$t( const snackbarMessage = this.$t(
`The invoice PDF document has been regenerated`); `The invoice PDF document has been regenerated`);
@ -60,6 +65,17 @@ class Controller extends Descriptor {
.then(res => this.entity = res.data); .then(res => this.entity = res.data);
} }
reload() {
return this.loadData().then(() => {
if (this.cardReload)
this.cardReload();
});
}
cardReload() {
// Prevents error when not defined
}
sendInvoice($data) { sendInvoice($data) {
return this.vnEmail.send('invoice', { return this.vnEmail.send('invoice', {
recipientId: this.invoiceOut.client.id, recipientId: this.invoiceOut.client.id,
@ -73,6 +89,7 @@ ngModule.vnComponent('vnInvoiceOutDescriptor', {
template: require('./index.html'), template: require('./index.html'),
controller: Controller, controller: Controller,
bindings: { bindings: {
invoiceOut: '<' invoiceOut: '<',
cardReload: '&'
} }
}); });

View File

@ -18,6 +18,7 @@ describe('vnInvoiceOutDescriptor', () => {
controller.invoiceOut = invoiceOut; controller.invoiceOut = invoiceOut;
$httpBackend.whenGET(`InvoiceOuts/${invoiceOut.id}`).respond();
$httpBackend.expectPOST(`InvoiceOuts/${invoiceOut.id}/createPdf`).respond(); $httpBackend.expectPOST(`InvoiceOuts/${invoiceOut.id}/createPdf`).respond();
controller.createInvoicePdf(); controller.createInvoicePdf();
$httpBackend.flush(); $httpBackend.flush();

View File

@ -12,5 +12,6 @@ Are you sure you want to clone this invoice?: Estas seguro de clonar esta factur
Book invoice: Asentar factura Book invoice: Asentar factura
InvoiceOut booked: Factura asentada InvoiceOut booked: Factura asentada
Are you sure you want to book this invoice?: Estas seguro de querer asentar esta factura? Are you sure you want to book this invoice?: Estas seguro de querer asentar esta factura?
Regenerate invoice PDF: Regenerar PDF factura Generate PDF invoice: Generar PDF factura
Regenerate PDF invoice: Regenerar PDF factura
The invoice PDF document has been regenerated: El documento PDF de la factura ha sido regenerado The invoice PDF document has been regenerated: El documento PDF de la factura ha sido regenerado

View File

@ -1,5 +1,8 @@
<vn-portal slot="menu"> <vn-portal slot="menu">
<vn-ticket-descriptor ticket="$ctrl.ticket" card-reload="$ctrl.reload()"></vn-ticket-descriptor> <vn-ticket-descriptor
ticket="$ctrl.ticket"
card-reload="$ctrl.reload()">
</vn-ticket-descriptor>
<vn-left-menu source="card"></vn-left-menu> <vn-left-menu source="card"></vn-left-menu>
</vn-portal> </vn-portal>
<ui-view></ui-view> <ui-view></ui-view>

View File

@ -80,12 +80,10 @@
</vn-item> </vn-item>
<vn-item <vn-item
ng-click="createInvoicePdfConfirmation.show()" ng-click="createInvoicePdfConfirmation.show()"
ng-show="$ctrl.isInvoiced" ng-show="$ctrl.isInvoiced && ($ctrl.hasInvoicing || !$ctrl.ticket.invoiceOut.hasPdf)"
vn-acl="invoicing"
vn-acl-action="remove"
name="regenerateInvoice" name="regenerateInvoice"
translate> translate>
Regenerate invoice PDF {{!$ctrl.ticket.invoiceOut.hasPdf ? 'Generate PDF invoice': 'Regenerate PDF invoice'}}
</vn-item> </vn-item>
<vn-item <vn-item
ng-click="recalculateComponentsConfirmation.show()" ng-click="recalculateComponentsConfirmation.show()"
@ -210,8 +208,8 @@
<vn-confirm <vn-confirm
vn-id="createInvoicePdfConfirmation" vn-id="createInvoicePdfConfirmation"
on-accept="$ctrl.createInvoicePdf()" on-accept="$ctrl.createInvoicePdf()"
question="Are you sure you want to regenerate the invoice PDF document?" question="Are you sure you want to generate/regenerate the PDF invoice?"
message="You are going to regenerate the invoice PDF document"> message="Generate PDF invoice document">
</vn-confirm> </vn-confirm>
<!-- Recalculate components confirmation dialog --> <!-- Recalculate components confirmation dialog -->

View File

@ -226,6 +226,7 @@ class Controller extends Section {
createInvoicePdf() { createInvoicePdf() {
const invoiceId = this.ticket.invoiceOut.id; const invoiceId = this.ticket.invoiceOut.id;
return this.$http.post(`InvoiceOuts/${invoiceId}/createPdf`) return this.$http.post(`InvoiceOuts/${invoiceId}/createPdf`)
.then(() => this.reload())
.then(() => { .then(() => {
const snackbarMessage = this.$t( const snackbarMessage = this.$t(
`The invoice PDF document has been regenerated`); `The invoice PDF document has been regenerated`);

View File

@ -153,6 +153,7 @@ describe('Ticket Component vnTicketDescriptorMenu', () => {
it('should make a query and show a success snackbar', () => { it('should make a query and show a success snackbar', () => {
jest.spyOn(controller.vnApp, 'showSuccess'); jest.spyOn(controller.vnApp, 'showSuccess');
$httpBackend.whenGET(`Tickets/16`).respond();
$httpBackend.expectPOST(`InvoiceOuts/${ticket.invoiceOut.id}/createPdf`).respond(); $httpBackend.expectPOST(`InvoiceOuts/${ticket.invoiceOut.id}/createPdf`).respond();
controller.createInvoicePdf(); controller.createInvoicePdf();
$httpBackend.flush(); $httpBackend.flush();

View File

@ -18,6 +18,10 @@ class Controller extends Descriptor {
super.entity = value; super.entity = value;
} }
get hasInvoicing() {
return this.aclService.hasAny(['invoicing']);
}
loadData() { loadData() {
const filter = { const filter = {
include: [ include: [

View File

@ -21,8 +21,8 @@ Regenerate invoice PDF: Regenerar PDF factura
The invoice PDF document has been regenerated: El documento PDF de la factura ha sido regenerado The invoice PDF document has been regenerated: El documento PDF de la factura ha sido regenerado
You are going to invoice this ticket: Vas a facturar este ticket You are going to invoice this ticket: Vas a facturar este ticket
Are you sure you want to invoice this ticket?: ¿Seguro que quieres facturar este ticket? Are you sure you want to invoice this ticket?: ¿Seguro que quieres facturar este ticket?
You are going to regenerate the invoice PDF document: Vas a regenerar el documento PDF de la factura Generate PDF invoice document: Generar PDF de la factura
Are you sure you want to regenerate the invoice PDF document?: ¿Seguro que quieres regenerar el documento PDF de la factura? Are you sure you want to generate/regenerate the PDF invoice?: ¿Seguro que quieres generar/regenerar el PDF de la factura?
Shipped hour updated: Hora de envio modificada Shipped hour updated: Hora de envio modificada
Deleted ticket: Ticket eliminado Deleted ticket: Ticket eliminado
Recalculate components: Recalcular componentes Recalculate components: Recalcular componentes