diff --git a/db/changes/10002-lent/00-invoiceOut.sql b/db/changes/10002-lent/00-invoiceOut.sql
new file mode 100644
index 000000000..ed58227ac
--- /dev/null
+++ b/db/changes/10002-lent/00-invoiceOut.sql
@@ -0,0 +1,9 @@
+ALTER TABLE `vn2008`.`Facturas`
+DROP FOREIGN KEY `invoice_bank_id`;
+ALTER TABLE `vn2008`.`Facturas`
+CHANGE COLUMN `Id_Banco` `Id_Banco` INT(11) NULL DEFAULT NULL ;
+ALTER TABLE `vn2008`.`Facturas`
+ADD CONSTRAINT `invoice_bank_id`
+ FOREIGN KEY (`Id_Banco`)
+ REFERENCES `vn2008`.`Bancos` (`Id_Banco`)
+ ON UPDATE CASCADE;
diff --git a/db/changes/10002-lent/00-invoiceOutMake.sql b/db/changes/10002-lent/00-invoiceOutMake.sql
new file mode 100644
index 000000000..13acbbbbc
--- /dev/null
+++ b/db/changes/10002-lent/00-invoiceOutMake.sql
@@ -0,0 +1,141 @@
+DROP procedure IF EXISTS `vn`.`invoiceOutMake`;
+
+DELIMITER $$
+$$
+CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`invoiceOutMake`(
+ vSerial VARCHAR(255),
+ vInvoiceDate DATETIME,
+ OUT vNewInvoiceId INT)
+BEGIN
+
+/* Creación de facturas emitidas.
+* REQUIERE previamente tabla ticketToInvoice.
+*
+* @param vSerial, vInvoiceDate, vCompany, vClient
+*
+* @return vNewInvoiceId
+*/
+
+ DECLARE vSpainCountryCode INT DEFAULT 1;
+ DECLARE vIsAnySaleToInvoice BOOL;
+ DECLARE vCountry TINYINT DEFAULT 1;
+ DECLARE vNewRef VARCHAR(255);
+ DECLARE vWorker INT DEFAULT vn.getWorker();
+ DECLARE vCompany INT;
+ DECLARE vClient INT;
+ DECLARE vCplusStandardInvoiceTypeFk INT DEFAULT 1;
+ DECLARE vCplusCorrectingInvoiceTypeFk INT DEFAULT 6;
+ DECLARE vCplusSimplifiedInvoiceTypeFk INT DEFAULT 2;
+ DECLARE vCorrectingSerial VARCHAR(1) DEFAULT 'R';
+ DECLARE vSimplifiedSerial VARCHAR(1) DEFAULT 'S';
+
+ SET vInvoiceDate = IFNULL(vInvoiceDate,CURDATE());
+
+ SELECT t.clientFk, t.companyFk
+ INTO vClient, vCompany
+ FROM ticketToInvoice tt
+ JOIN ticket t ON t.id = tt.id
+ LIMIT 1;
+
+ -- Elimina tickets sense moviments
+/* UPDATE ticket t
+ JOIN ticketToInvoice ti ON ti.id = t.id
+ LEFT JOIN sale s ON s.ticketFk = ti.id
+ LEFT JOIN expedition e ON e.ticketFk = t.id
+ LEFT JOIN ticketPackaging tp ON tp.ticketFk = t.id
+ SET t.shipped = '2000-02-01 00:00:00'
+ WHERE s.ticketFk IS NULL AND e.ticketFk IS NULL AND e.ticketFk IS NULL;
+*/
+ -- Eliminem de ticketToInvoice els tickets que no han de ser facturats
+ DELETE ti.*
+ FROM ticketToInvoice ti
+ JOIN ticket t ON t.id = ti.id
+ JOIN client c ON c.id = t.clientFk
+ WHERE YEAR(t.shipped) < 2001
+ OR c.isTaxDataChecked = FALSE;
+
+ SELECT SUM(quantity * price * (100 - discount)/100)
+ INTO vIsAnySaleToInvoice
+ FROM sale s
+ JOIN ticketToInvoice t on t.id = s.ticketFk;
+
+ IF vIsAnySaleToInvoice THEN
+
+ -- el trigger añade el siguiente Id_Factura correspondiente a la vSerial
+ -- el trigger añade el siguiente Id_Factura correspondiente a la vSerial
+ INSERT INTO invoiceOut
+ (
+ ref,
+ serial,
+ issued,
+ clientFk,
+ dued,
+ companyFk,
+ cplusInvoiceType477Fk
+ )
+ SELECT
+ 1,
+ vSerial,
+ vInvoiceDate,
+ vClient,
+ getDueDate(vInvoiceDate, dueDay),
+ vCompany,
+ IF(vSerial = vCorrectingSerial,
+ vCplusCorrectingInvoiceTypeFk,
+ IF(vSerial = vSimplifiedSerial,
+ vCplusSimplifiedInvoiceTypeFk,
+ vCplusStandardInvoiceTypeFk))
+ FROM client
+ WHERE id = vClient;
+
+
+ SET vNewInvoiceId = LAST_INSERT_ID();
+
+ SELECT ref
+ INTO vNewRef
+ FROM invoiceOut
+ WHERE id = vNewInvoiceId;
+
+ UPDATE ticket t
+ JOIN ticketToInvoice ti ON ti.id = t.id
+ SET t.refFk = vNewRef;
+
+ DROP TEMPORARY TABLE IF EXISTS tmp.updateInter;
+ CREATE TEMPORARY TABLE tmp.updateInter ENGINE = MEMORY
+ SELECT s.id,ti.id ticket_id,vWorker Id_Trabajador
+ FROM ticketToInvoice ti
+ LEFT JOIN vn.ticketState ts ON ti.id = ts.ticket
+ JOIN state s
+ WHERE IFNULL(ts.alertLevel,0) < 3 and s.`code` = vn.getAlert3State(ti.id);
+
+ INSERT INTO vncontrol.inter(state_id,Id_Ticket,Id_Trabajador)
+ SELECT * FROM tmp.updateInter;
+
+
+ INSERT INTO ticketLog (action, userFk,originFk, description)
+ SELECT 'UPDATE',account.userGetId(),ti.id, CONCAT('Crea factura ',vNewRef)
+ FROM ticketToInvoice ti;
+
+ CALL invoiceExpenceMake(vNewInvoiceId);
+ CALL invoiceTaxMake(vNewInvoiceId,vCountry);
+
+ UPDATE invoiceOut io
+ JOIN (
+ SELECT SUM(amount) AS total
+ FROM invoiceOutExpence
+ WHERE invoiceOutFk = vNewInvoiceId
+ ) base
+ JOIN (
+ SELECT SUM(vat) AS total
+ FROM invoiceOutTax
+ WHERE invoiceOutFk = vNewInvoiceId
+ ) vat
+ SET io.amount = base.total + vat.total
+ WHERE io.id = vNewInvoiceId;
+
+ END IF;
+
+ DROP TEMPORARY TABLE `ticketToInvoice`;
+END$$
+
+DELIMITER ;
diff --git a/db/changes/10002-lent/00-printQueue.sql b/db/changes/10002-lent/00-printQueue.sql
new file mode 100644
index 000000000..d2493458b
--- /dev/null
+++ b/db/changes/10002-lent/00-printQueue.sql
@@ -0,0 +1,17 @@
+ALTER TABLE `vn2008`.`Colas`
+DROP FOREIGN KEY `Colas_ibfk_1`,
+DROP FOREIGN KEY `Colas_ibfk_2`,
+DROP FOREIGN KEY `Colas_ibfk_3`,
+DROP FOREIGN KEY `Colas_ibfk_5`;
+ALTER TABLE `vn2008`.`Colas`
+CHANGE COLUMN `Id_Impresora` `Id_Impresora` TINYINT(3) UNSIGNED NULL DEFAULT NULL ,
+CHANGE COLUMN `Id_Prioridad` `Id_Prioridad` TINYINT(3) UNSIGNED NULL DEFAULT NULL ;
+ALTER TABLE `vn2008`.`Colas`
+ADD CONSTRAINT `Colas_ibfk_4`
+ FOREIGN KEY (`Id_Impresora`)
+ REFERENCES `vn2008`.`Impresoras` (`Id_Impresora`)
+ ON UPDATE CASCADE,
+ADD CONSTRAINT `Colas_ibfk_3`
+ FOREIGN KEY (`Id_Prioridad`)
+ REFERENCES `vn2008`.`Prioridades` (`Id_Prioridad`)
+ ON UPDATE CASCADE;
diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql
index 13233b69e..3b409aca3 100644
--- a/db/dump/fixtures.sql
+++ b/db/dump/fixtures.sql
@@ -973,6 +973,14 @@ INSERT INTO `vn2008`.`tblContadores`(`id`,`FechaInventario`)
VALUES
(1,DATE_ADD(CURDATE(),INTERVAL -1 MONTH));
+INSERT INTO `vn2008`.`Estados` (`Id_Estado`, `Estado`)
+ VALUES
+ ('1', 'En Espera');
+
+INSERT INTO `vn2008`.`Informes` (`Id_Informe`, `Informe`)
+ VALUES
+ ('30', 'Generar factura PDF');
+
INSERT INTO `vn`.`deliveryMethod`(`id`, `code`, `description`)
VALUES
( 1, 'AGENCY', 'Agencia'),
diff --git a/front/core/components/drop-down/style.scss b/front/core/components/drop-down/style.scss
index 43be76492..3fceb0212 100755
--- a/front/core/components/drop-down/style.scss
+++ b/front/core/components/drop-down/style.scss
@@ -48,7 +48,7 @@ vn-drop-down {
}
}
& > .list {
- max-height: 12.8em;
+ max-height: 20em;
overflow: auto;
ul {
diff --git a/modules/ticket/back/methods/ticket/makeInvoice.js b/modules/ticket/back/methods/ticket/makeInvoice.js
index b472cfa81..1bc514990 100644
--- a/modules/ticket/back/methods/ticket/makeInvoice.js
+++ b/modules/ticket/back/methods/ticket/makeInvoice.js
@@ -2,14 +2,14 @@ const UserError = require('vn-loopback/util/user-error');
module.exports = function(Self) {
Self.remoteMethodCtx('makeInvoice', {
- description: 'Change property isEqualizated in all client addresses',
+ description: 'Make out an invoice from a ticket id',
accessType: 'WRITE',
accepts: [
{
arg: 'id',
type: 'string',
required: true,
- description: 'Client id',
+ description: 'Ticket id',
http: {source: 'path'}
}
],
@@ -53,7 +53,7 @@ module.exports = function(Self) {
query = `CALL vn.invoiceOutMake(?, ?, @invoiceId);
SELECT @invoiceId AS invoiceId;`;
result = await Self.rawSql(query, [serial, null], options);
- let invoice = result[1].invoiceId;
+ let invoice = result[1][0].invoiceId;
if (serial != 'R' && invoice) {
query = `CALL vn.invoiceOutBooking(?)`;
@@ -62,9 +62,11 @@ module.exports = function(Self) {
let user = await Self.app.models.Worker.findOne({where: {userFk: userId}});
- query = `INSERT INTO vn2008.Colas(Id_Informe,Cola,Id_Trabajador) VALUES (?, ?, ?)`;
+ query = `INSERT INTO printServerQueue(reportFk, param1, workerFk) VALUES (?, ?, ?)`;
await Self.rawSql(query, [3, invoice, user.id], options);
await options.transaction.commit();
+
+ return {invoiceFk: invoice, serial};
} catch (e) {
options.transaction.rollback();
throw e;
diff --git a/modules/ticket/back/methods/ticket/specs/makeInvoice.spec.js b/modules/ticket/back/methods/ticket/specs/makeInvoice.spec.js
new file mode 100644
index 000000000..29bd29e50
--- /dev/null
+++ b/modules/ticket/back/methods/ticket/specs/makeInvoice.spec.js
@@ -0,0 +1,31 @@
+const app = require('vn-loopback/server/server');
+
+describe('ticket makeInvoice()', () => {
+ afterAll(async done => {
+ let ticket = await app.models.Ticket.findById(11);
+ ticket.updateAttributes({refFk: null});
+
+ done();
+ });
+
+ it('should invoice a ticket', async() => {
+ let ctx = {req: {accessToken: {userId: 9}}};
+ let ticketFk = 11;
+ let result = await app.models.Ticket.makeInvoice(ctx, ticketFk);
+
+ expect(result.invoiceFk).not.toBeNaN();
+ expect(result.serial).toEqual('T');
+ });
+
+ it('should not invoice an already invoiced ticket', async() => {
+ let ctx = {req: {accessToken: {userId: 9}}};
+ let ticketFk = 11;
+ let error;
+
+ await app.models.Ticket.makeInvoice(ctx, ticketFk).catch(e => {
+ error = e;
+ }).finally(() => {
+ expect(error.message).toEqual(`This ticket can't be invoiced`);
+ });
+ });
+});
diff --git a/modules/ticket/front/descriptor/index.html b/modules/ticket/front/descriptor/index.html
index dbe8f8c89..779ce7e53 100644
--- a/modules/ticket/front/descriptor/index.html
+++ b/modules/ticket/front/descriptor/index.html
@@ -179,6 +179,15 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/modules/ticket/front/descriptor/index.js b/modules/ticket/front/descriptor/index.js
index 5c7d81ab9..f61c94d23 100644
--- a/modules/ticket/front/descriptor/index.js
+++ b/modules/ticket/front/descriptor/index.js
@@ -1,21 +1,23 @@
import ngModule from '../module';
class Controller {
- constructor($state, $scope, $http, vnApp, $translate) {
+ constructor($state, $scope, $http, vnApp, $translate, aclService) {
this.$scope = $scope;
this.$state = $state;
this.$http = $http;
this.vnApp = vnApp;
this.$translate = $translate;
+ this.aclService = aclService;
this.moreOptions = [
- {callback: this.showAddTurnDialog, name: 'Add turn', show: true},
+ {callback: this.showAddTurnDialog, name: 'Add turn'},
{callback: this.showAddStowaway, name: 'Add stowaway', show: () => this.isTicketModule()},
{callback: this.showRemoveStowaway, name: 'Remove stowaway', show: () => this.shouldShowRemoveStowaway()},
- {callback: this.showDeliveryNote, name: 'Show Delivery Note', show: true},
- {callback: this.showDeleteTicketDialog, name: 'Delete ticket', show: true},
- {callback: this.showChangeShipped, name: 'Change shipped hour', show: true},
- {callback: this.showSMSDialog, name: 'Send SMS', show: true},
- {callback: this.openRptRoute, name: 'Show pallet report', show: true}
+ {callback: this.showInvoiceOutMakeDialog, name: 'Make invoice', acl: 'invoicing'},
+ {callback: this.showDeliveryNote, name: 'Show Delivery Note'},
+ {callback: this.showDeleteTicketDialog, name: 'Delete ticket'},
+ {callback: this.showChangeShipped, name: 'Change shipped hour'},
+ {callback: this.showSMSDialog, name: 'Send SMS'},
+ {callback: this.openRptRoute, name: 'Show pallet report'}
];
}
@@ -64,7 +66,12 @@ class Controller {
onMoreOpen() {
let options = this.moreOptions.filter(o => {
- return o.show === true || typeof o.show === 'function' && o.show();
+ const hasShowProperty = Object.hasOwnProperty.call(o, 'show');
+ const hasAclProperty = Object.hasOwnProperty.call(o, 'acl');
+ const hasAcl = !hasAclProperty || (hasAclProperty && this.aclService.hasAny([o.acl]));
+
+ return (!hasShowProperty || o.show === true ||
+ typeof o.show === 'function' && o.show()) && hasAcl;
});
this.$scope.moreButton.data = options;
}
@@ -180,9 +187,32 @@ class Controller {
};
this.$scope.sms.open();
}
+
+ /**
+ * Shows an invoice confirmation
+ */
+ showInvoiceOutMakeDialog() {
+ this.$scope.invoiceMakeConfirmation.show();
+ }
+
+ /**
+ * Makes an invoice
+ * from current ticket
+ *
+ * @param {String} response - Response result
+ */
+ invoiceMakeOut(response) {
+ if (response === 'ACCEPT') {
+ const query = `/ticket/api/Tickets/${this.ticket.id}/makeInvoice`;
+ this.$http.post(query).then(() => {
+ this.vnApp.showSuccess(this.$translate.instant('Ticket invoiced'));
+ this.$state.reload();
+ });
+ }
+ }
}
-Controller.$inject = ['$state', '$scope', '$http', 'vnApp', '$translate'];
+Controller.$inject = ['$state', '$scope', '$http', 'vnApp', '$translate', 'aclService'];
ngModule.component('vnTicketDescriptor', {
template: require('./index.html'),
diff --git a/modules/ticket/front/descriptor/index.spec.js b/modules/ticket/front/descriptor/index.spec.js
index 2c2359299..8e5a43f71 100644
--- a/modules/ticket/front/descriptor/index.spec.js
+++ b/modules/ticket/front/descriptor/index.spec.js
@@ -77,5 +77,20 @@ describe('Ticket Component vnTicketDescriptor', () => {
expect(window.open).toHaveBeenCalledWith(expectedPath);
});
});
+
+ describe('invoiceMakeOut(response)', () => {
+ it('should make a query and call $state.reload() method if the response is ACCEPT', () => {
+ spyOn(controller.$state, 'reload');
+ spyOn(controller.vnApp, 'showSuccess');
+
+ $httpBackend.when('POST', `/ticket/api/Tickets/2/makeInvoice`).respond();
+ $httpBackend.expect('POST', `/ticket/api/Tickets/2/makeInvoice`).respond();
+ controller.invoiceMakeOut('ACCEPT');
+ $httpBackend.flush();
+
+ expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Ticket invoiced');
+ expect(controller.$state.reload).toHaveBeenCalledWith();
+ });
+ });
});
diff --git a/modules/ticket/front/descriptor/locale/es.yml b/modules/ticket/front/descriptor/locale/es.yml
index 3ce9905cb..0e0d0bdd6 100644
--- a/modules/ticket/front/descriptor/locale/es.yml
+++ b/modules/ticket/front/descriptor/locale/es.yml
@@ -6,11 +6,15 @@ Stowaways to add: Polizones a añadir
Stowaways of the ticket: Polizones del ticket
Add stowaway: Añadir polizón
Remove stowaway: Borrar polizón
-Are you sure you want to delete this stowaway?: ¿Estas seguro de que quieres borrar este polizón?
+Are you sure you want to delete this stowaway?: ¿Seguro que quieres borrar este polizón?
Show Delivery Note: Ver albarán
Show pallet report: Mostrar hoja de pallet
Change shipped hour: Cambiar hora de envío
Shipped hour: Hora de envío
SMSPayment: >-
Verdnatura le comunica: Su pedido está pendiente de pago.
- Por favor, entre en la página web y efectue el pago con tarjeta. Muchas gracias.
\ No newline at end of file
+ Por favor, entre en la página web y efectue el pago con tarjeta. Muchas gracias.
+Ticket invoiced: Ticket facturado
+Make invoice: Facturar
+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?
\ No newline at end of file