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`)
VALUES
(1, 'T', 1014.24, CURDATE(), 1101, CURDATE(), 442, CURDATE(), CURDATE(), 1, 1),
(2, 'T', 121.36, CURDATE(), 1102, CURDATE(), 442, CURDATE(), CURDATE(), 1, 1),
(3, 'T', 8.88, CURDATE(), 1103, CURDATE(), 442, CURDATE(), CURDATE(), 1, 1),
(4, 'T', 8.88, CURDATE(), 1103, CURDATE(), 442, CURDATE(), CURDATE(), 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, 1);
(1, 'T', 1014.24, CURDATE(), 1101, CURDATE(), 442, CURDATE(), CURDATE(), 1, 0),
(2, 'T', 121.36, CURDATE(), 1102, CURDATE(), 442, CURDATE(), CURDATE(), 1, 0),
(3, 'T', 8.88, CURDATE(), 1103, CURDATE(), 442, CURDATE(), CURDATE(), 1, 0),
(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, 0);
UPDATE `vn`.`invoiceOut` SET ref = 'T1111111' WHERE id = 1;
UPDATE `vn`.`invoiceOut` SET ref = 'T2222222' WHERE id = 2;

View File

@ -29,7 +29,7 @@ module.exports = Self => {
const models = Self.app.models;
const headers = ctx.req.headers;
const origin = headers.origin;
const authorization = ctx.req.accessToken.id;
const auth = ctx.req.accessToken;
if (process.env.NODE_ENV == 'test')
throw new UserError(`Action not allowed on the test environment`);
@ -48,13 +48,18 @@ module.exports = Self => {
let fileSrc;
try {
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({
hasPdf: true
}, myOptions);
const response = got.stream(`${origin}/api/report/invoice`, {
query: {
authorization: authorization,
authorization: auth.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);
expect(result.length).toEqual(5);
expect(result.length).toEqual(1);
await tx.rollback();
} catch (e) {

View File

@ -1,5 +1,8 @@
<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-portal>
<ui-view></ui-view>

View File

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

View File

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

View File

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

View File

@ -18,6 +18,7 @@ describe('vnInvoiceOutDescriptor', () => {
controller.invoiceOut = invoiceOut;
$httpBackend.whenGET(`InvoiceOuts/${invoiceOut.id}`).respond();
$httpBackend.expectPOST(`InvoiceOuts/${invoiceOut.id}/createPdf`).respond();
controller.createInvoicePdf();
$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
InvoiceOut booked: Factura asentada
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

View File

@ -1,5 +1,8 @@
<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-portal>
<ui-view></ui-view>

View File

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

View File

@ -226,6 +226,7 @@ class Controller extends Section {
createInvoicePdf() {
const invoiceId = this.ticket.invoiceOut.id;
return this.$http.post(`InvoiceOuts/${invoiceId}/createPdf`)
.then(() => this.reload())
.then(() => {
const snackbarMessage = this.$t(
`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', () => {
jest.spyOn(controller.vnApp, 'showSuccess');
$httpBackend.whenGET(`Tickets/16`).respond();
$httpBackend.expectPOST(`InvoiceOuts/${ticket.invoiceOut.id}/createPdf`).respond();
controller.createInvoicePdf();
$httpBackend.flush();

View File

@ -18,6 +18,10 @@ class Controller extends Descriptor {
super.entity = value;
}
get hasInvoicing() {
return this.aclService.hasAny(['invoicing']);
}
loadData() {
const filter = {
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
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?
You are going to regenerate the invoice PDF document: Vas a regenerar el documento 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?
Generate PDF invoice document: Generar 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
Deleted ticket: Ticket eliminado
Recalculate components: Recalcular componentes