diff --git a/.vscode/settings.json b/.vscode/settings.json
index 36b7e21d8..03479d27a 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -16,6 +16,7 @@
},
"cSpell.words": [
"salix",
- "fdescribe"
+ "fdescribe",
+ "Loggable"
]
}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1907f46bd..69e93a309 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [2404.01] - 2024-01-25
+
+### Added
+### Changed
+### Fixed
+
+
## [2402.01] - 2024-01-11
### Added
diff --git a/back/methods/vn-user/privileges.js b/back/methods/vn-user/privileges.js
index 08cfaaae8..9f936c29b 100644
--- a/back/methods/vn-user/privileges.js
+++ b/back/methods/vn-user/privileges.js
@@ -68,7 +68,7 @@ module.exports = Self => {
userToUpdate.hasGrant = hasGrant;
if (roleFk) {
- const role = await models.Role.findById(roleFk, {fields: ['name']}, myOptions);
+ const role = await models.VnRole.findById(roleFk, {fields: ['name']}, myOptions);
const hasRole = await Self.hasRole(userId, role.name, myOptions);
if (!hasRole)
diff --git a/back/methods/vn-user/specs/privileges.spec.js b/back/methods/vn-user/specs/privileges.spec.js
index 3d25eecf9..04d9c09ff 100644
--- a/back/methods/vn-user/specs/privileges.spec.js
+++ b/back/methods/vn-user/specs/privileges.spec.js
@@ -70,7 +70,7 @@ describe('VnUser privileges()', () => {
const tx = await models.VnUser.beginTransaction({});
const options = {transaction: tx};
- const agency = await models.Role.findOne({
+ const agency = await models.VnRole.findOne({
where: {
name: 'agency'
}
diff --git a/back/model-config.json b/back/model-config.json
index ebc0e321b..27a94498c 100644
--- a/back/model-config.json
+++ b/back/model-config.json
@@ -139,9 +139,6 @@
"Warehouse": {
"dataSource": "vn"
},
- "VnUser": {
- "dataSource": "vn"
- },
"OsTicket": {
"dataSource": "osticket"
},
@@ -156,6 +153,12 @@
},
"ViaexpressConfig": {
"dataSource": "vn"
+ },
+ "VnUser": {
+ "dataSource": "vn"
+ },
+ "VnRole": {
+ "dataSource": "vn"
}
}
diff --git a/back/models/dms-type.json b/back/models/dms-type.json
index de3d564b4..8d7195132 100644
--- a/back/models/dms-type.json
+++ b/back/models/dms-type.json
@@ -29,12 +29,12 @@
"relations": {
"readRole": {
"type": "belongsTo",
- "model": "Role",
+ "model": "VnRole",
"foreignKey": "readRoleFk"
},
"writeRole": {
"type": "belongsTo",
- "model": "Role",
+ "model": "VnRole",
"foreignKey": "writeRoleFk"
}
},
diff --git a/back/models/image-collection.json b/back/models/image-collection.json
index 186ab0208..ae0e0adcd 100644
--- a/back/models/image-collection.json
+++ b/back/models/image-collection.json
@@ -46,12 +46,12 @@
},
"readRole": {
"type": "belongsTo",
- "model": "Role",
+ "model": "VnRole",
"foreignKey": "readRoleFk"
},
"writeRole": {
"type": "belongsTo",
- "model": "Role",
+ "model": "VnRole",
"foreignKey": "writeRoleFk"
}
},
@@ -64,4 +64,3 @@
}
]
}
-
\ No newline at end of file
diff --git a/back/models/notificationAcl.json b/back/models/notificationAcl.json
index a20187961..9ab85530f 100644
--- a/back/models/notificationAcl.json
+++ b/back/models/notificationAcl.json
@@ -24,8 +24,8 @@
},
"role": {
"type": "belongsTo",
- "model": "Role",
+ "model": "VnRole",
"foreignKey": "roleFk"
}
}
-}
\ No newline at end of file
+}
diff --git a/back/models/vn-role.json b/back/models/vn-role.json
new file mode 100644
index 000000000..c7d7e172b
--- /dev/null
+++ b/back/models/vn-role.json
@@ -0,0 +1,13 @@
+{
+ "name": "VnRole",
+ "base": "Role",
+ "validateUpsert": true,
+ "options": {
+ "mysql": {
+ "table": "account.role"
+ }
+ },
+ "mixins": {
+ "Loggable": true
+ }
+}
diff --git a/back/models/vn-user.json b/back/models/vn-user.json
index d0687098d..639603643 100644
--- a/back/models/vn-user.json
+++ b/back/models/vn-user.json
@@ -7,6 +7,9 @@
"table": "account.user"
}
},
+ "mixins": {
+ "Loggable": true
+ },
"resetPasswordTokenTTL": "604800",
"properties": {
"id": {
@@ -63,7 +66,7 @@
"relations": {
"role": {
"type": "belongsTo",
- "model": "Role",
+ "model": "VnRole",
"foreignKey": "roleFk"
},
"roles": {
diff --git a/db/changes/235001/00-updateACL_Role_VnRole.sql b/db/changes/235001/00-updateACL_Role_VnRole.sql
new file mode 100644
index 000000000..b08a44138
--- /dev/null
+++ b/db/changes/235001/00-updateACL_Role_VnRole.sql
@@ -0,0 +1,6 @@
+INSERT INTO salix.ACL (model,property,accessType,permission,principalType,principalId) VALUES
+ ('VnRole','*','READ','ALLOW','ROLE','employee'),
+ ('VnRole','*','WRITE','ALLOW','ROLE','it');
+
+DELETE FROM`salix`.`ACL` WHERE model='Role';
+
diff --git a/db/changes/240001/00-fixInvoiceCorrectionConstraintsName.sql b/db/changes/240001/00-fixInvoiceCorrectionConstraintsName.sql
new file mode 100644
index 000000000..426afea90
--- /dev/null
+++ b/db/changes/240001/00-fixInvoiceCorrectionConstraintsName.sql
@@ -0,0 +1,7 @@
+ALTER TABLE `vn`.`invoiceCorrection` DROP FOREIGN KEY `cplusInvoiceTyoeFk`;
+ALTER TABLE `vn`.`invoiceCorrection` DROP FOREIGN KEY `invoiceCorrectionType_Fk33`;
+ALTER TABLE `vn`.`invoiceCorrection` DROP FOREIGN KEY `invoiceCorrection_ibfk_1`;
+
+ALTER TABLE `vn`.`invoiceCorrection` ADD CONSTRAINT `siiTypeInvoiceOut_FK` FOREIGN KEY (`siiTypeInvoiceOutFk`) REFERENCES `vn`.`siiTypeInvoiceOut`(id) ON UPDATE CASCADE;
+ALTER TABLE `vn`.`invoiceCorrection` ADD CONSTRAINT `invoiceCorrectionType_FK` FOREIGN KEY (`invoiceCorrectionTypeFk`) REFERENCES `vn`.`invoiceCorrectionType`(id) ON UPDATE CASCADE;
+ALTER TABLE `vn`.`invoiceCorrection` ADD CONSTRAINT `cplusRectificationType_FK` FOREIGN KEY (`cplusRectificationTypeFk`) REFERENCES `vn`.`cplusRectificationType`(id) ON UPDATE CASCADE;
diff --git a/db/changes/240001/00-getTaxBases.sql b/db/changes/240001/00-getTaxBases.sql
new file mode 100644
index 000000000..8bd1b745a
--- /dev/null
+++ b/db/changes/240001/00-getTaxBases.sql
@@ -0,0 +1,33 @@
+DELIMITER $$
+$$
+CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`getTaxBases`()
+BEGIN
+/**
+* Calcula y devuelve en número de bases imponibles postivas y negativas
+* Requiere la tabla temporal tmp.ticketToInvoice(id)
+*
+* returns tmp.taxBases
+*/
+
+ CREATE OR REPLACE TEMPORARY TABLE tmp.ticket
+ (KEY (ticketFk))
+ ENGINE = MEMORY
+ SELECT id ticketFk
+ FROM tmp.ticketToInvoice;
+
+ CALL ticket_getTax(NULL);
+
+ DROP TEMPORARY TABLE IF EXISTS tmp.taxBases;
+ CREATE TEMPORARY TABLE tmp.taxBases
+ ENGINE = MEMORY
+ SELECT
+ SUM(taxableBase > 0) as positive,
+ SUM(taxableBase < 0) as negative
+ FROM(
+ SELECT SUM(taxableBase) taxableBase
+ FROM tmp.ticketTax
+ GROUP BY pgcFk
+ ) t;
+
+END$$
+DELIMITER ;
diff --git a/db/changes/240001/01-newHasAnyPositiveBase.sql b/db/changes/240001/01-newHasAnyPositiveBase.sql
new file mode 100644
index 000000000..c4edfaed0
--- /dev/null
+++ b/db/changes/240001/01-newHasAnyPositiveBase.sql
@@ -0,0 +1,30 @@
+DELIMITER $$
+$$
+CREATE OR REPLACE DEFINER=`root`@`localhost` FUNCTION `vn`.`hasAnyPositiveBase`() RETURNS tinyint(1)
+ DETERMINISTIC
+BEGIN
+
+/**
+* Calcula si existe alguna base imponible positiva
+* Requiere la tabla temporal tmp.ticketToInvoice(id) para getTaxBases()
+*
+* returns BOOLEAN
+*/
+
+ DECLARE hasAnyPositiveBase BOOLEAN;
+
+ CALL getTaxBases();
+
+ SELECT positive INTO hasAnyPositiveBase
+ FROM tmp.taxBases
+ LIMIT 1;
+
+ DROP TEMPORARY TABLE
+ tmp.ticketTax,
+ tmp.ticket,
+ tmp.taxBases;
+
+ RETURN hasAnyPositiveBase;
+
+END$$
+DELIMITER ;
diff --git a/db/changes/240001/01-refactorHasAnyNegativeBase.sql b/db/changes/240001/01-refactorHasAnyNegativeBase.sql
new file mode 100644
index 000000000..a3eb2d9c7
--- /dev/null
+++ b/db/changes/240001/01-refactorHasAnyNegativeBase.sql
@@ -0,0 +1,32 @@
+DELIMITER $$
+$$
+CREATE OR REPLACE DEFINER=`root`@`localhost` FUNCTION `vn`.`hasAnyNegativeBase`() RETURNS tinyint(1)
+ DETERMINISTIC
+BEGIN
+
+/**
+* Calcula si existe alguna base imponible negativa
+* Requiere la tabla temporal tmp.ticketToInvoice(id) para getTaxBases()
+*
+* returns BOOLEAN
+*/
+
+ DECLARE hasAnyNegativeBase BOOLEAN;
+
+ CALL getTaxBases();
+
+ SELECT negative INTO hasAnyNegativeBase
+ FROM tmp.taxBases
+ LIMIT 1;
+
+ DROP TEMPORARY TABLE
+ tmp.ticketTax,
+ tmp.ticket,
+ tmp.taxBases;
+
+ RETURN hasAnyNegativeBase;
+
+END$$
+DELIMITER ;
+
+
diff --git a/db/changes/240401/.gitkeep b/db/changes/240401/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql
index d1f6892fb..8fd1961bb 100644
--- a/db/dump/fixtures.sql
+++ b/db/dump/fixtures.sql
@@ -602,18 +602,19 @@ INSERT INTO `vn`.`taxArea` (`code`, `claveOperacionFactura`, `CodigoTransaccion`
INSERT INTO `vn`.`invoiceOutSerial` (`code`, `description`, `isTaxed`, `taxAreaFk`, `isCEE`, `type`)
VALUES
- ('A', 'Global nacional', 1, 'NATIONAL', 0, 'global'),
- ('T', 'Española rapida', 1, 'NATIONAL', 0, 'quick'),
- ('V', 'Intracomunitaria global', 0, 'CEE', 1, 'global'),
- ('M', 'Múltiple nacional', 1, 'NATIONAL', 0, 'quick'),
- ('E', 'Exportación rápida', 0, 'WORLD', 0, 'quick');
+ ('A', 'Global nacional', 1, 'NATIONAL', 0, 'global'),
+ ('T', 'Española rapida', 1, 'NATIONAL', 0, 'quick'),
+ ('V', 'Intracomunitaria global', 0, 'CEE', 1, 'global'),
+ ('M', 'Múltiple nacional', 1, 'NATIONAL', 0, 'quick'),
+ ('R', 'Rectificativa', 1, 'NATIONAL', 0, NULL),
+ ('E', 'Exportación rápida', 0, 'WORLD', 0, 'quick');
INSERT INTO `vn`.`invoiceOut`(`id`, `serial`, `amount`, `issued`,`clientFk`, `created`, `companyFk`, `dued`, `booked`, `bankFk`, `hasPdf`)
VALUES
(1, 'T', 1026.24, util.VN_CURDATE(), 1101, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0),
(2, 'T', 121.36, util.VN_CURDATE(), 1102, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0),
(3, 'T', 8.88, util.VN_CURDATE(), 1103, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0),
- (4, 'T', 8.88, util.VN_CURDATE(), 1103, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0),
+ (4, 'T', 8.88, util.VN_CURDATE(), 1104, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0),
(5, 'A', 8.88, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1103, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 442, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 0);
UPDATE `vn`.`invoiceOut` SET ref = 'T1111111' WHERE id = 1;
@@ -719,7 +720,7 @@ INSERT INTO `vn`.`route`(`id`, `time`, `workerFk`, `created`, `vehicleFk`, `agen
INSERT INTO `vn`.`ticket`(`id`, `priority`, `agencyModeFk`,`warehouseFk`,`routeFk`, `shipped`, `landed`, `clientFk`,`nickname`, `addressFk`, `refFk`, `isDeleted`, `zoneFk`, `zonePrice`, `zoneBonus`, `created`, `weight`)
VALUES
(1 , 3, 1, 1, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 1101, 'Bat cave', 121, NULL, 0, 1, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1),
- (2 , 1, 1, 1, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 1104, 'Stark tower', 124, NULL, 0, 1, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 2),
+ (2 , 1, 1, 1, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 1101, 'Bat cave', 1, NULL, 0, 1, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 2),
(3 , 1, 7, 1, 6, DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -2 MONTH), INTERVAL +1 DAY), 1104, 'Stark tower', 124, NULL, 0, 3, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH), NULL),
(4 , 3, 2, 1, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -3 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -3 MONTH), INTERVAL +1 DAY), 1104, 'Stark tower', 124, NULL, 0, 9, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -3 MONTH), NULL),
(5 , 3, 3, 3, 3, DATE_ADD(util.VN_CURDATE(), INTERVAL -4 MONTH), DATE_ADD(DATE_ADD(util.VN_CURDATE(),INTERVAL -4 MONTH), INTERVAL +1 DAY), 1104, 'Stark tower', 124, NULL, 0, 10, 5, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL -4 MONTH), NULL),
diff --git a/e2e/paths/05-ticket/18_index_payout.spec.js b/e2e/paths/05-ticket/18_index_payout.spec.js
index 7e5201d11..9c5518424 100644
--- a/e2e/paths/05-ticket/18_index_payout.spec.js
+++ b/e2e/paths/05-ticket/18_index_payout.spec.js
@@ -35,7 +35,7 @@ describe('Ticket index payout path', () => {
await page.waitToClick(selectors.ticketsIndex.openAdvancedSearchButton);
await page.write(selectors.ticketsIndex.advancedSearchClient, '1101');
await page.keyboard.press('Enter');
- await page.waitForNumberOfElements(selectors.ticketsIndex.anySearchResult, 9);
+ await page.waitForNumberOfElements(selectors.ticketsIndex.anySearchResult, 10);
await page.waitToClick(selectors.ticketsIndex.firstTicketCheckbox);
await page.waitToClick(selectors.ticketsIndex.secondTicketCheckbox);
diff --git a/e2e/paths/09-invoice-out/01_summary.spec.js b/e2e/paths/09-invoice-out/01_summary.spec.js
index 728f0130a..09ac66ffc 100644
--- a/e2e/paths/09-invoice-out/01_summary.spec.js
+++ b/e2e/paths/09-invoice-out/01_summary.spec.js
@@ -28,7 +28,6 @@ describe('InvoiceOut summary path', () => {
it('should contain the tax breakdown', async() => {
const firstTax = await page.waitToGetProperty(selectors.invoiceOutSummary.taxOne, 'innerText');
-
const secondTax = await page.waitToGetProperty(selectors.invoiceOutSummary.taxTwo, 'innerText');
expect(firstTax).toContain('10%');
@@ -37,10 +36,9 @@ describe('InvoiceOut summary path', () => {
it('should contain the tickets info', async() => {
const firstTicket = await page.waitToGetProperty(selectors.invoiceOutSummary.ticketOne, 'innerText');
-
const secondTicket = await page.waitToGetProperty(selectors.invoiceOutSummary.ticketTwo, 'innerText');
expect(firstTicket).toContain('Bat cave');
- expect(secondTicket).toContain('Stark tower');
+ expect(secondTicket).toContain('Bat cave');
});
});
diff --git a/front/core/directives/rule.js b/front/core/directives/rule.js
index f65efe176..34781c2aa 100644
--- a/front/core/directives/rule.js
+++ b/front/core/directives/rule.js
@@ -23,7 +23,6 @@ export function directive($translate, $window) {
let rule = $attrs.rule.split('.');
let modelName = rule.shift();
let fieldName = rule.shift();
-
let split = $attrs.ngModel.split('.');
if (!fieldName) fieldName = split.pop() || null;
if (!modelName) modelName = firstUpper(split.pop() || '');
diff --git a/loopback/common/mixins/loggable.js b/loopback/common/mixins/loggable.js
new file mode 100644
index 000000000..760fdf60a
--- /dev/null
+++ b/loopback/common/mixins/loggable.js
@@ -0,0 +1,12 @@
+const LoopBackContext = require('loopback-context');
+async function handleObserve(ctx) {
+ ctx.options.httpCtx = LoopBackContext.getCurrentContext();
+}
+module.exports = function(Self) {
+ let Mixin = {
+ 'before save': handleObserve,
+ 'before delete': handleObserve,
+ };
+ for (const [listener, handler] of Object.entries(Mixin))
+ Self.observe(listener, handler);
+};
diff --git a/loopback/common/models/loggable.js b/loopback/common/models/loggable.js
deleted file mode 100644
index 360c84566..000000000
--- a/loopback/common/models/loggable.js
+++ /dev/null
@@ -1,15 +0,0 @@
-const LoopBackContext = require('loopback-context');
-
-module.exports = function(Self) {
- Self.setup = function() {
- Self.super_.setup.call(this);
- };
-
- Self.observe('before save', async function(ctx) {
- ctx.options.httpCtx = LoopBackContext.getCurrentContext();
- });
-
- Self.observe('before delete', async function(ctx) {
- ctx.options.httpCtx = LoopBackContext.getCurrentContext();
- });
-};
diff --git a/loopback/common/models/loggable.json b/loopback/common/models/loggable.json
deleted file mode 100644
index 9101532a3..000000000
--- a/loopback/common/models/loggable.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "name": "Loggable",
- "base": "VnModel",
- "validateUpsert": true
-}
diff --git a/loopback/locale/en.json b/loopback/locale/en.json
index 508c17344..2c7dc6be1 100644
--- a/loopback/locale/en.json
+++ b/loopback/locale/en.json
@@ -45,6 +45,7 @@
"Extension format is invalid": "Extension format is invalid",
"NO_ZONE_FOR_THIS_PARAMETERS": "NO_ZONE_FOR_THIS_PARAMETERS",
"This client can't be invoiced": "This client can't be invoiced",
+ "You must provide the correction information to generate a corrective invoice": "You must provide the correction information to generate a corrective invoice",
"The introduced hour already exists": "The introduced hour already exists",
"Invalid parameters to create a new ticket": "Invalid parameters to create a new ticket",
"Concept cannot be blank": "Concept cannot be blank",
@@ -178,7 +179,8 @@
"The renew period has not been exceeded": "The renew period has not been exceeded",
"You can not use the same password": "You can not use the same password",
"Valid priorities": "Valid priorities: %d",
- "Negative basis of tickets": "Negative basis of tickets: {{ticketsIds}}",
+ "hasAnyNegativeBase": "Negative basis of tickets: {{ticketsIds}}",
+ "hasAnyPositiveBase": "Positive basis of tickets: {{ticketsIds}}",
"This ticket cannot be left empty.": "This ticket cannot be left empty. %s",
"Social name should be uppercase": "Social name should be uppercase",
"Street should be uppercase": "Street should be uppercase",
diff --git a/loopback/locale/es.json b/loopback/locale/es.json
index e2b90983b..25c76971d 100644
--- a/loopback/locale/es.json
+++ b/loopback/locale/es.json
@@ -72,6 +72,7 @@
"The secret can't be blank": "La contraseña no puede estar en blanco",
"We weren't able to send this SMS": "No hemos podido enviar el SMS",
"This client can't be invoiced": "Este cliente no puede ser facturado",
+ "You must provide the correction information to generate a corrective invoice": "Debes informar la información de corrección para generar una factura rectificativa",
"This ticket can't be invoiced": "Este ticket no puede ser facturado",
"You cannot add or modify services to an invoiced ticket": "No puedes añadir o modificar servicios a un ticket facturado",
"This ticket can not be modified": "Este ticket no puede ser modificado",
@@ -305,7 +306,8 @@
"Mail not sent": "Se ha producido un fallo al enviar la factura al cliente [{{clientId}}]({{{clientUrl}}}), por favor revisa la dirección de correo electrónico",
"The renew period has not been exceeded": "El periodo de renovación no ha sido superado",
"Valid priorities": "Prioridades válidas: %d",
- "Negative basis of tickets": "Base negativa para los tickets: {{ticketsIds}}",
+ "hasAnyNegativeBase": "Base negativa para los tickets: {{ticketsIds}}",
+ "hasAnyPositiveBase": "Base positivas para los tickets: {{ticketsIds}}",
"You cannot assign an alias that you are not assigned to": "No puede asignar un alias que no tenga asignado",
"This ticket cannot be left empty.": "Este ticket no se puede dejar vacío. %s",
"The company has not informed the supplier account for bank transfers": "La empresa no tiene informado la cuenta de proveedor para transferencias bancarias",
@@ -333,5 +335,6 @@
"This user does not have an assigned tablet": "Este usuario no tiene tablet asignada",
"Incorrect pin": "Pin incorrecto.",
"You already have the mailAlias": "Ya tienes este alias de correo",
- "The alias cant be modified": "Este alias de correo no puede ser modificado"
-}
\ No newline at end of file
+ "The alias cant be modified": "Este alias de correo no puede ser modificado",
+ "No tickets to invoice": "No hay tickets para facturar"
+}
diff --git a/loopback/server/model-config.json b/loopback/server/model-config.json
index 33ef3797d..56b5360e8 100644
--- a/loopback/server/model-config.json
+++ b/loopback/server/model-config.json
@@ -25,20 +25,19 @@
"FieldAcl": {
"dataSource": "vn"
},
- "Role": {
- "dataSource": "vn",
- "options": {
- "mysql": {
- "table": "salix.Role"
- }
- }
- },
"RoleMapping": {
"dataSource": "vn",
"options": {
"mysql": {
"table": "salix.RoleMapping"
}
+ },
+ "relations": {
+ "role": {
+ "type": "belongsTo",
+ "model": "VnRole",
+ "foreignKey": "roleId"
+ }
}
},
"Schema": {
diff --git a/modules/account/back/models/account.json b/modules/account/back/models/account.json
index 3c22521cb..6c2784696 100644
--- a/modules/account/back/models/account.json
+++ b/modules/account/back/models/account.json
@@ -1,49 +1,49 @@
{
- "name": "Account",
- "base": "VnModel",
- "options": {
- "mysql": {
- "table": "account.account"
- }
- },
- "properties": {
- "id": {
- "id": true
- }
- },
- "relations": {
- "user": {
- "type": "belongsTo",
- "model": "VnUser",
- "foreignKey": "id"
- },
- "aliases": {
- "type": "hasMany",
- "model": "MailAliasAccount",
- "foreignKey": "account"
- }
- },
- "acls": [
- {
- "property": "login",
- "accessType": "EXECUTE",
- "principalType": "ROLE",
- "principalId": "$everyone",
- "permission": "ALLOW"
+ "name": "Account",
+ "base": "VnModel",
+ "options": {
+ "mysql": {
+ "table": "account.account"
+ }
+ },
+ "properties": {
+ "id": {
+ "id": true
+ }
+ },
+ "relations": {
+ "user": {
+ "type": "belongsTo",
+ "model": "VnUser",
+ "foreignKey": "id"
},
- {
+ "aliases": {
+ "type": "hasMany",
+ "model": "MailAliasAccount",
+ "foreignKey": "account"
+ }
+ },
+ "acls": [
+ {
+ "property": "login",
+ "accessType": "EXECUTE",
+ "principalType": "ROLE",
+ "principalId": "$everyone",
+ "permission": "ALLOW"
+ },
+ {
"property": "logout",
- "accessType": "EXECUTE",
- "principalType": "ROLE",
- "principalId": "$authenticated",
- "permission": "ALLOW"
- },
- {
+ "accessType": "EXECUTE",
+ "principalType": "ROLE",
+ "principalId": "$authenticated",
+ "permission": "ALLOW"
+ },
+ {
"property": "changePassword",
- "accessType": "EXECUTE",
- "principalType": "ROLE",
- "principalId": "$everyone",
- "permission": "ALLOW"
- }
- ]
+ "accessType": "EXECUTE",
+ "principalType": "ROLE",
+ "principalId": "$everyone",
+ "permission": "ALLOW"
+ }
+ ]
}
diff --git a/modules/account/back/models/ldap-config.js b/modules/account/back/models/ldap-config.js
index b557d243c..89f0add48 100644
--- a/modules/account/back/models/ldap-config.js
+++ b/modules/account/back/models/ldap-config.js
@@ -239,7 +239,7 @@ module.exports = Self => {
// Prepare data
- let roles = await $.Role.find({
+ let roles = await $.VnRole.find({
fields: ['id', 'name', 'description']
});
let roleRoles = await $.RoleRole.find({
diff --git a/modules/account/back/models/role-inherit.json b/modules/account/back/models/role-inherit.json
index 4b69ffdc2..a89f47b77 100644
--- a/modules/account/back/models/role-inherit.json
+++ b/modules/account/back/models/role-inherit.json
@@ -15,12 +15,12 @@
"relations": {
"owner": {
"type": "belongsTo",
- "model": "Role",
+ "model": "VnRole",
"foreignKey": "role"
},
"inherits": {
"type": "belongsTo",
- "model": "Role",
+ "model": "VnRole",
"foreignKey": "inheritsFrom"
}
}
diff --git a/modules/account/back/models/role-role.json b/modules/account/back/models/role-role.json
index 77df7a920..e59351c59 100644
--- a/modules/account/back/models/role-role.json
+++ b/modules/account/back/models/role-role.json
@@ -14,12 +14,12 @@
"relations": {
"owner": {
"type": "belongsTo",
- "model": "Role",
+ "model": "VnRole",
"foreignKey": "role"
},
"inherits": {
"type": "belongsTo",
- "model": "Role",
+ "model": "VnRole",
"foreignKey": "inheritsFrom"
}
}
diff --git a/modules/account/front/acl/create/index.html b/modules/account/front/acl/create/index.html
index 7f4fa9e46..14332f737 100644
--- a/modules/account/front/acl/create/index.html
+++ b/modules/account/front/acl/create/index.html
@@ -15,7 +15,7 @@
@@ -32,7 +32,7 @@
diff --git a/modules/account/front/acl/search-panel/index.html b/modules/account/front/acl/search-panel/index.html
index b83b9c255..a3efab440 100644
--- a/modules/account/front/acl/search-panel/index.html
+++ b/modules/account/front/acl/search-panel/index.html
@@ -4,7 +4,7 @@
-
\ No newline at end of file
+
diff --git a/modules/account/front/create/index.html b/modules/account/front/create/index.html
index acc07d346..70a518885 100644
--- a/modules/account/front/create/index.html
+++ b/modules/account/front/create/index.html
@@ -30,7 +30,7 @@
+ url="VnRoles">
diff --git a/modules/account/front/role/basic-data/index.html b/modules/account/front/role/basic-data/index.html
index 749927186..846f8b455 100644
--- a/modules/account/front/role/basic-data/index.html
+++ b/modules/account/front/role/basic-data/index.html
@@ -1,25 +1,27 @@
\ No newline at end of file
+
diff --git a/modules/account/front/role/card/index.js b/modules/account/front/role/card/index.js
index 6f888211d..3c7c758ef 100644
--- a/modules/account/front/role/card/index.js
+++ b/modules/account/front/role/card/index.js
@@ -3,7 +3,7 @@ import ModuleCard from 'salix/components/module-card';
class Controller extends ModuleCard {
reload() {
- this.$http.get(`Roles/${this.$params.id}`)
+ this.$http.get(`VnRoles/${this.$params.id}`)
.then(res => this.role = res.data);
}
}
diff --git a/modules/account/front/role/card/index.spec.js b/modules/account/front/role/card/index.spec.js
index f39840e5f..f02c08f28 100644
--- a/modules/account/front/role/card/index.spec.js
+++ b/modules/account/front/role/card/index.spec.js
@@ -1,6 +1,6 @@
import './index';
-describe('component vnRoleCard', () => {
+fdescribe('component vnRoleCard', () => {
let controller;
let $httpBackend;
@@ -15,7 +15,7 @@ describe('component vnRoleCard', () => {
it('should reload the controller data', () => {
controller.$params.id = 1;
- $httpBackend.expectGET('Roles/1').respond('foo');
+ $httpBackend.expectGET('VnRoles/1').respond('foo');
controller.reload();
$httpBackend.flush();
diff --git a/modules/account/front/role/create/index.html b/modules/account/front/role/create/index.html
index 02900d580..77d6fc2c1 100644
--- a/modules/account/front/role/create/index.html
+++ b/modules/account/front/role/create/index.html
@@ -1,6 +1,6 @@
@@ -12,15 +12,15 @@
+ rule="VnRole.description">
diff --git a/modules/account/front/role/descriptor/index.html b/modules/account/front/role/descriptor/index.html
index 4cd4ac822..d8bf4857a 100644
--- a/modules/account/front/role/descriptor/index.html
+++ b/modules/account/front/role/descriptor/index.html
@@ -24,4 +24,4 @@
on-accept="$ctrl.onDelete()"
question="Are you sure you want to continue?"
message="Role will be removed">
-
\ No newline at end of file
+
diff --git a/modules/account/front/role/descriptor/index.js b/modules/account/front/role/descriptor/index.js
index a1b578133..17b585cb7 100644
--- a/modules/account/front/role/descriptor/index.js
+++ b/modules/account/front/role/descriptor/index.js
@@ -11,7 +11,7 @@ class Controller extends Descriptor {
}
onDelete() {
- return this.$http.delete(`Roles/${this.id}`)
+ return this.$http.delete(`VnRoles/${this.id}`)
.then(() => this.$state.go('account.role'))
.then(() => this.vnApp.showSuccess(this.$t('Role removed')));
}
diff --git a/modules/account/front/role/descriptor/index.spec.js b/modules/account/front/role/descriptor/index.spec.js
index e2761c639..eafb96727 100644
--- a/modules/account/front/role/descriptor/index.spec.js
+++ b/modules/account/front/role/descriptor/index.spec.js
@@ -1,6 +1,6 @@
import './index';
-describe('component vnRoleDescriptor', () => {
+fdescribe('component vnRoleDescriptor', () => {
let controller;
let $httpBackend;
@@ -18,7 +18,7 @@ describe('component vnRoleDescriptor', () => {
controller.$state.go = jest.fn();
jest.spyOn(controller.vnApp, 'showSuccess');
- $httpBackend.expectDELETE('Roles/1').respond();
+ $httpBackend.expectDELETE('VnRoles/1').respond();
controller.onDelete();
$httpBackend.flush();
diff --git a/modules/account/front/role/main/index.html b/modules/account/front/role/main/index.html
index 9d7e6e053..cfef28e57 100644
--- a/modules/account/front/role/main/index.html
+++ b/modules/account/front/role/main/index.html
@@ -1,6 +1,6 @@
@@ -15,4 +15,4 @@
-
\ No newline at end of file
+
diff --git a/modules/account/front/role/subroles/index.html b/modules/account/front/role/subroles/index.html
index bc554b9f9..eba1002b0 100644
--- a/modules/account/front/role/subroles/index.html
+++ b/modules/account/front/role/subroles/index.html
@@ -33,14 +33,14 @@
ng-click="$ctrl.onAddClick()"
fixed-bottom-right>
-
@@ -49,7 +49,7 @@
- this.$.summary = res.data);
}
diff --git a/modules/account/front/search-panel/index.html b/modules/account/front/search-panel/index.html
index f80b537aa..a539d9657 100644
--- a/modules/account/front/search-panel/index.html
+++ b/modules/account/front/search-panel/index.html
@@ -19,7 +19,7 @@
vn-one
label="Role"
ng-model="filter.roleFk"
- url="Roles"
+ url="VnRoles"
value-field="id"
show-field="name">
@@ -28,4 +28,4 @@
-
\ No newline at end of file
+
diff --git a/modules/claim/back/models/claim-beginning.json b/modules/claim/back/models/claim-beginning.json
index d355881e8..d224586da 100644
--- a/modules/claim/back/models/claim-beginning.json
+++ b/modules/claim/back/models/claim-beginning.json
@@ -1,6 +1,9 @@
{
"name": "ClaimBeginning",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "claimBeginning"
diff --git a/modules/claim/back/models/claim-development.json b/modules/claim/back/models/claim-development.json
index b0f352f50..732955660 100644
--- a/modules/claim/back/models/claim-development.json
+++ b/modules/claim/back/models/claim-development.json
@@ -1,6 +1,9 @@
{
"name": "ClaimDevelopment",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "claimDevelopment"
diff --git a/modules/claim/back/models/claim-dms.json b/modules/claim/back/models/claim-dms.json
index 26c90fd69..ed12c925b 100644
--- a/modules/claim/back/models/claim-dms.json
+++ b/modules/claim/back/models/claim-dms.json
@@ -1,6 +1,9 @@
{
"name": "ClaimDms",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "claimDms"
diff --git a/modules/claim/back/models/claim-end.json b/modules/claim/back/models/claim-end.json
index 9f12ff93a..ef5477f50 100644
--- a/modules/claim/back/models/claim-end.json
+++ b/modules/claim/back/models/claim-end.json
@@ -1,6 +1,9 @@
{
"name": "ClaimEnd",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "claimEnd"
diff --git a/modules/claim/back/models/claim-observation.json b/modules/claim/back/models/claim-observation.json
index 2d418b76e..1e4cb6a0f 100644
--- a/modules/claim/back/models/claim-observation.json
+++ b/modules/claim/back/models/claim-observation.json
@@ -1,6 +1,9 @@
{
"name": "ClaimObservation",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "claimObservation"
diff --git a/modules/claim/back/models/claim-state.json b/modules/claim/back/models/claim-state.json
index f5bde4168..c50fdebdf 100644
--- a/modules/claim/back/models/claim-state.json
+++ b/modules/claim/back/models/claim-state.json
@@ -1,6 +1,9 @@
{
"name": "ClaimState",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "claimState"
@@ -32,7 +35,7 @@
"relations": {
"writeRole": {
"type": "belongsTo",
- "model": "Role",
+ "model": "VnRole",
"foreignKey": "roleFk"
}
},
diff --git a/modules/claim/back/models/claim.json b/modules/claim/back/models/claim.json
index a7db1f3e1..b85b9e073 100644
--- a/modules/claim/back/models/claim.json
+++ b/modules/claim/back/models/claim.json
@@ -1,6 +1,9 @@
{
"name": "Claim",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "claim"
diff --git a/modules/client/back/methods/client/canBeInvoiced.js b/modules/client/back/methods/client/canBeInvoiced.js
index 843e9549f..cdb865500 100644
--- a/modules/client/back/methods/client/canBeInvoiced.js
+++ b/modules/client/back/methods/client/canBeInvoiced.js
@@ -1,7 +1,7 @@
const UserError = require('vn-loopback/util/user-error');
module.exports = function(Self) {
- Self.remoteMethodCtx('canBeInvoiced', {
+ Self.remoteMethod('canBeInvoiced', {
description: 'Change property isEqualizated in all client addresses',
accessType: 'READ',
accepts: [
diff --git a/modules/client/back/methods/client/specs/consumption.spec.js b/modules/client/back/methods/client/specs/consumption.spec.js
index 47a495d79..85dbb7422 100644
--- a/modules/client/back/methods/client/specs/consumption.spec.js
+++ b/modules/client/back/methods/client/specs/consumption.spec.js
@@ -16,7 +16,7 @@ describe('client consumption() filter', () => {
};
const result = await models.Client.consumption(ctx, filter, options);
- expect(result.length).toEqual(10);
+ expect(result.length).toEqual(11);
await tx.rollback();
} catch (e) {
@@ -49,7 +49,7 @@ describe('client consumption() filter', () => {
const thirdRow = result[2];
expect(result.length).toEqual(3);
- expect(firstRow.quantity).toEqual(10);
+ expect(firstRow.quantity).toEqual(11);
expect(secondRow.quantity).toEqual(15);
expect(thirdRow.quantity).toEqual(20);
diff --git a/modules/client/back/models/address.json b/modules/client/back/models/address.json
index 5f962677d..e8bf8d8a0 100644
--- a/modules/client/back/models/address.json
+++ b/modules/client/back/models/address.json
@@ -1,7 +1,10 @@
{
"name": "Address",
"description": "Client addresses",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "address"
diff --git a/modules/client/back/models/client-contact.json b/modules/client/back/models/client-contact.json
index 3f71ab79e..55cc9d436 100644
--- a/modules/client/back/models/client-contact.json
+++ b/modules/client/back/models/client-contact.json
@@ -1,7 +1,10 @@
{
"name": "ClientContact",
"description": "Client phone contacts",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "clientContact"
diff --git a/modules/client/back/models/client-dms.json b/modules/client/back/models/client-dms.json
index 14b19498e..6dbcd0140 100644
--- a/modules/client/back/models/client-dms.json
+++ b/modules/client/back/models/client-dms.json
@@ -1,6 +1,9 @@
{
"name": "ClientDms",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "clientDms"
diff --git a/modules/client/back/models/client-informa.json b/modules/client/back/models/client-informa.json
index 0c652484e..5e536faff 100644
--- a/modules/client/back/models/client-informa.json
+++ b/modules/client/back/models/client-informa.json
@@ -1,6 +1,9 @@
{
"name": "ClientInforma",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"log": {
"model":"ClientLog",
"relation": "client",
diff --git a/modules/client/back/models/client-observation.json b/modules/client/back/models/client-observation.json
index 95d00d374..b204ebeb4 100644
--- a/modules/client/back/models/client-observation.json
+++ b/modules/client/back/models/client-observation.json
@@ -1,7 +1,10 @@
{
"name": "ClientObservation",
"description": "Client notes",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "clientObservation"
diff --git a/modules/client/back/models/client-sample.json b/modules/client/back/models/client-sample.json
index a32f308ab..4cd55d9df 100644
--- a/modules/client/back/models/client-sample.json
+++ b/modules/client/back/models/client-sample.json
@@ -1,6 +1,9 @@
{
"name": "ClientSample",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "clientSample"
diff --git a/modules/client/back/models/client.json b/modules/client/back/models/client.json
index f32915bb5..bfde05162 100644
--- a/modules/client/back/models/client.json
+++ b/modules/client/back/models/client.json
@@ -1,6 +1,9 @@
{
"name": "Client",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "client"
diff --git a/modules/client/back/models/greuge.json b/modules/client/back/models/greuge.json
index 884cbd34e..f57744f8a 100644
--- a/modules/client/back/models/greuge.json
+++ b/modules/client/back/models/greuge.json
@@ -1,6 +1,9 @@
{
"name": "Greuge",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "greuge"
diff --git a/modules/client/back/models/recovery.json b/modules/client/back/models/recovery.json
index 5ea89197d..89ec54494 100644
--- a/modules/client/back/models/recovery.json
+++ b/modules/client/back/models/recovery.json
@@ -1,6 +1,9 @@
{
"name": "Recovery",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "recovery"
diff --git a/modules/client/back/models/role-credit-limit.json b/modules/client/back/models/role-credit-limit.json
index 4ea28b1a4..e36180dfc 100644
--- a/modules/client/back/models/role-credit-limit.json
+++ b/modules/client/back/models/role-credit-limit.json
@@ -19,8 +19,8 @@
"relations": {
"role": {
"type": "belongsTo",
- "model": "Role",
+ "model": "VnRole",
"foreignKey": "roleFk"
}
}
-}
\ No newline at end of file
+}
diff --git a/modules/entry/back/models/buy.json b/modules/entry/back/models/buy.json
index 30379eaf6..fa804f4d8 100644
--- a/modules/entry/back/models/buy.json
+++ b/modules/entry/back/models/buy.json
@@ -1,6 +1,9 @@
{
"name": "Buy",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "buy"
diff --git a/modules/entry/back/models/entry-observation.json b/modules/entry/back/models/entry-observation.json
index cdf0c5e6e..6a1592037 100644
--- a/modules/entry/back/models/entry-observation.json
+++ b/modules/entry/back/models/entry-observation.json
@@ -1,6 +1,9 @@
{
"name": "EntryObservation",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "entryObservation"
diff --git a/modules/entry/back/models/entry.json b/modules/entry/back/models/entry.json
index a7508b4e8..0f3e389b6 100644
--- a/modules/entry/back/models/entry.json
+++ b/modules/entry/back/models/entry.json
@@ -1,6 +1,9 @@
{
"name": "Entry",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "entry"
diff --git a/modules/invoiceIn/back/models/invoice-in-tax.json b/modules/invoiceIn/back/models/invoice-in-tax.json
index 5bfbbe2a8..53b5548b6 100644
--- a/modules/invoiceIn/back/models/invoice-in-tax.json
+++ b/modules/invoiceIn/back/models/invoice-in-tax.json
@@ -1,6 +1,9 @@
{
"name": "InvoiceInTax",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "invoiceInTax"
diff --git a/modules/invoiceIn/back/models/invoice-in.json b/modules/invoiceIn/back/models/invoice-in.json
index 5be55c851..59c179e76 100644
--- a/modules/invoiceIn/back/models/invoice-in.json
+++ b/modules/invoiceIn/back/models/invoice-in.json
@@ -1,6 +1,9 @@
{
"name": "InvoiceIn",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "invoiceIn"
diff --git a/modules/invoiceOut/back/methods/invoiceOut/createManualInvoice.js b/modules/invoiceOut/back/methods/invoiceOut/createManualInvoice.js
index 18e6903d6..043dfbead 100644
--- a/modules/invoiceOut/back/methods/invoiceOut/createManualInvoice.js
+++ b/modules/invoiceOut/back/methods/invoiceOut/createManualInvoice.js
@@ -85,7 +85,7 @@ module.exports = Self => {
throw new UserError(`A ticket with an amount of zero can't be invoiced`);
// Validates ticket nagative base
- const hasNegativeBase = await getNegativeBase(ticketId, myOptions);
+ const hasNegativeBase = await getNegativeBase(maxShipped, clientId, companyId, myOptions);
if (hasNegativeBase && company.code == 'VNL')
throw new UserError(`A ticket with a negative base can't be invoiced`);
} else {
@@ -162,10 +162,13 @@ module.exports = Self => {
return result.invoiceable;
}
- async function getNegativeBase(ticketId, options) {
+ async function getNegativeBase(maxShipped, clientId, companyId, options) {
const models = Self.app.models;
- const query = 'SELECT vn.hasSomeNegativeBase(?) AS base';
- const [result] = await models.InvoiceOut.rawSql(query, [ticketId], options);
+ await models.InvoiceOut.rawSql('CALL invoiceOut_exportationFromClient(?,?,?)',
+ [maxShipped, clientId, companyId], options
+ );
+ const query = 'SELECT vn.hasAnyNegativeBase() AS base';
+ const [result] = await models.InvoiceOut.rawSql(query, [], options);
return result.base;
}
diff --git a/modules/invoiceOut/back/methods/invoiceOut/invoiceClient.js b/modules/invoiceOut/back/methods/invoiceOut/invoiceClient.js
index fa22dab1e..530b02353 100644
--- a/modules/invoiceOut/back/methods/invoiceOut/invoiceClient.js
+++ b/modules/invoiceOut/back/methods/invoiceOut/invoiceClient.js
@@ -80,6 +80,7 @@ module.exports = Self => {
invoiceType,
args.companyFk,
args.invoiceDate,
+ null,
options
);
diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js
index 800a4ea83..11575999a 100644
--- a/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js
+++ b/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js
@@ -2,7 +2,7 @@
const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context');
-describe('InvoiceOut tranferInvoice()', () => {
+describe('InvoiceOut transferInvoice()', () => {
const activeCtx = {
accessToken: {userId: 5},
http: {
@@ -23,20 +23,29 @@ describe('InvoiceOut tranferInvoice()', () => {
const tx = await models.InvoiceOut.beginTransaction({});
const options = {transaction: tx};
const args = {
- id: '1',
- ref: 'T4444444',
+ id: '4',
+ refFk: 'T4444444',
newClientFk: 1,
- cplusRectificationId: 1,
- siiTypeInvoiceOutId: 1,
- invoiceCorrectionTypeId: 1
+ cplusRectificationTypeFk: 1,
+ siiTypeInvoiceOutFk: 1,
+ invoiceCorrectionTypeFk: 1
};
ctx.args = args;
try {
+ const {clientFk: oldClient} = await models.InvoiceOut.findById(args.id, {fields: ['clientFk']});
+ const invoicesBefore = await models.InvoiceOut.find({}, options);
const result = await models.InvoiceOut.transferInvoice(
ctx,
options);
+ const invoicesAfter = await models.InvoiceOut.find({}, options);
+ const rectificativeInvoice = invoicesAfter[invoicesAfter.length - 2];
+ const newInvoice = invoicesAfter[invoicesAfter.length - 1];
expect(result).toBeDefined();
+ expect(invoicesAfter.length - invoicesBefore.length).toEqual(2);
+ expect(rectificativeInvoice.clientFk).toEqual(oldClient);
+ expect(newInvoice.clientFk).toEqual(args.newClientFk);
+
await tx.rollback();
} catch (e) {
await tx.rollback();
@@ -49,20 +58,44 @@ describe('InvoiceOut tranferInvoice()', () => {
const options = {transaction: tx};
const args = {
id: '1',
- ref: 'T1111111',
+ refFk: 'T1111111',
newClientFk: 1101,
- cplusRectificationId: 1,
- siiTypeInvoiceOutId: 1,
- invoiceCorrectionTypeId: 1
+ cplusRectificationTypeFk: 1,
+ siiTypeInvoiceOutFk: 1,
+ invoiceCorrectionTypeFk: 1
};
ctx.args = args;
try {
await models.InvoiceOut.transferInvoice(
ctx,
options);
+ await tx.rollback();
} catch (e) {
expect(e.message).toBe(`Select a different client`);
await tx.rollback();
}
});
+
+ it('should throw an UserError when it is refund', async() => {
+ const tx = await models.InvoiceOut.beginTransaction({});
+ const options = {transaction: tx};
+ const args = {
+ id: '1',
+ refFk: 'T1111111',
+ newClientFk: 1102,
+ cplusRectificationTypeFk: 1,
+ siiTypeInvoiceOutFk: 1,
+ invoiceCorrectionTypeFk: 1
+ };
+ ctx.args = args;
+ try {
+ await models.InvoiceOut.transferInvoice(
+ ctx,
+ options);
+ await tx.rollback();
+ } catch (e) {
+ expect(e.message).toContain(`This ticket is already a refund`);
+ await tx.rollback();
+ }
+ });
});
diff --git a/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js b/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js
index dde535c99..5f2428539 100644
--- a/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js
+++ b/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js
@@ -12,7 +12,7 @@ module.exports = Self => {
description: 'Issued invoice id'
},
{
- arg: 'ref',
+ arg: 'refFk',
type: 'string',
required: true
},
@@ -22,17 +22,17 @@ module.exports = Self => {
required: true
},
{
- arg: 'cplusRectificationId',
+ arg: 'cplusRectificationTypeFk',
type: 'number',
required: true
},
{
- arg: 'siiTypeInvoiceOutId',
+ arg: 'siiTypeInvoiceOutFk',
type: 'number',
required: true
},
{
- arg: 'invoiceCorrectionTypeId',
+ arg: 'invoiceCorrectionTypeFk',
type: 'number',
required: true
},
@@ -50,14 +50,14 @@ module.exports = Self => {
Self.transferInvoice = async(ctx, options) => {
const models = Self.app.models;
const myOptions = {userId: ctx.req.accessToken.userId};
- const args = ctx.args;
+ const {id, refFk, newClientFk, cplusRectificationTypeFk, siiTypeInvoiceOutFk, invoiceCorrectionTypeFk} = ctx.args;
let tx;
if (typeof options == 'object')
Object.assign(myOptions, options);
- const {clientFk} = await models.InvoiceOut.findById(args.id);
+ const {clientFk} = await models.InvoiceOut.findById(id);
- if (clientFk == args.newClientFk)
+ if (clientFk == newClientFk)
throw new UserError(`Select a different client`);
if (!myOptions.transaction) {
@@ -65,10 +65,10 @@ module.exports = Self => {
myOptions.transaction = tx;
}
try {
- const filterRef = {where: {refFk: args.ref}};
+ const filterRef = {where: {refFk: refFk}};
const tickets = await models.Ticket.find(filterRef, myOptions);
const ticketsIds = tickets.map(ticket => ticket.id);
- await models.Ticket.refund(ctx, ticketsIds, null, myOptions);
+ const refundTickets = await models.Ticket.refund(ctx, ticketsIds, null, myOptions);
const filterTicket = {where: {ticketFk: {inq: ticketsIds}}};
@@ -82,20 +82,16 @@ module.exports = Self => {
const clonedTicketIds = [];
for (const clonedTicket of clonedTickets) {
- await clonedTicket.updateAttribute('clientFk', args.newClientFk, myOptions);
+ await clonedTicket.updateAttribute('clientFk', newClientFk, myOptions);
clonedTicketIds.push(clonedTicket.id);
}
- const invoiceIds = await models.Ticket.invoiceTickets(ctx, clonedTicketIds, myOptions);
- const [invoiceId] = invoiceIds;
+ const invoiceCorrection =
+ {correctedFk: id, cplusRectificationTypeFk, siiTypeInvoiceOutFk, invoiceCorrectionTypeFk};
+ const refundTicketIds = refundTickets.map(ticket => ticket.id);
- await models.InvoiceCorrection.create({
- correctingFk: invoiceId,
- correctedFk: args.id,
- cplusRectificationTypeFk: args.cplusRectificationId,
- siiTypeInvoiceOutFk: args.siiTypeInvoiceOutId,
- invoiceCorrectionTypeFk: args.invoiceCorrectionTypeId
- }, myOptions);
+ await models.Ticket.invoiceTickets(ctx, refundTicketIds, invoiceCorrection, myOptions);
+ const [invoiceId] = await models.Ticket.invoiceTickets(ctx, clonedTicketIds, null, myOptions);
if (tx) {
await tx.commit();
diff --git a/modules/invoiceOut/back/models/invoice-correction.json b/modules/invoiceOut/back/models/invoice-correction.json
index 43e4f07ef..58f6f63b7 100644
--- a/modules/invoiceOut/back/models/invoice-correction.json
+++ b/modules/invoiceOut/back/models/invoice-correction.json
@@ -16,13 +16,43 @@
"type": "number"
},
"cplusRectificationTypeFk": {
- "type": "number"
+ "type": "number",
+ "required": true
},
"siiTypeInvoiceOutFk": {
- "type": "number"
+ "type": "number",
+ "required": true
},
"invoiceCorrectionTypeFk": {
- "type": "number"
+ "type": "number",
+ "required": true
+ },
+ "relations": {
+ "correcting": {
+ "type": "belongsTo",
+ "model": "InvoiceOut",
+ "foreignKey": "correctingFk"
+ },
+ "corrected": {
+ "type": "belongsTo",
+ "model": "InvoiceOut",
+ "foreignKey": "correctedFk"
+ },
+ "cplusRectificationType": {
+ "type": "belongsTo",
+ "model": "cplusRectificationType",
+ "foreignKey": "cplusRectificationTypeFk"
+ },
+ "siiTypeInvoiceOut": {
+ "type": "belongsTo",
+ "model": "siiTypeInvoiceOut",
+ "foreignKey": "siiTypeInvoiceOutFk"
+ },
+ "invoiceCorrectionType": {
+ "type": "belongsTo",
+ "model": "invoiceCorrectionType",
+ "foreignKey": "invoiceCorrectionTypeFk"
+ }
}
}
}
diff --git a/modules/invoiceOut/back/models/sii-type-invoice-out.json b/modules/invoiceOut/back/models/sii-type-invoice-out.json
index 17b312617..58d50a12c 100644
--- a/modules/invoiceOut/back/models/sii-type-invoice-out.json
+++ b/modules/invoiceOut/back/models/sii-type-invoice-out.json
@@ -12,6 +12,9 @@
"type": "number",
"description": "Identifier"
},
+ "code": {
+ "type": "string"
+ },
"description": {
"type": "string"
}
diff --git a/modules/invoiceOut/front/descriptor-menu/index.html b/modules/invoiceOut/front/descriptor-menu/index.html
index 0052f0c03..435db3612 100644
--- a/modules/invoiceOut/front/descriptor-menu/index.html
+++ b/modules/invoiceOut/front/descriptor-menu/index.html
@@ -7,7 +7,8 @@
+ data="siiTypeInvoiceOuts"
+ where="{code: {like: 'R%'}}">
+
+ transferInvoice
+
-
-
-
- #{{id}} - {{::name}}
-
-
-
-
- {{::description}}
-
-
-
-
-
-
-
-
-
-
+
+
+
+ #{{id}} - {{::name}}
+
+
+
+
+ {{::description}}
+
+
+
+
+
+
+ {{::code}} - {{::description}}
+
+
+
+
+
+
diff --git a/modules/invoiceOut/front/descriptor-menu/index.js b/modules/invoiceOut/front/descriptor-menu/index.js
index d3862a753..2c28599e7 100644
--- a/modules/invoiceOut/front/descriptor-menu/index.js
+++ b/modules/invoiceOut/front/descriptor-menu/index.js
@@ -129,15 +129,15 @@ class Controller extends Section {
transferInvoice() {
const params = {
id: this.invoiceOut.id,
- ref: this.invoiceOut.ref,
- newClientFk: this.invoiceOut.client.id,
- cplusRectificationId: this.cplusRectificationType,
- siiTypeInvoiceOutId: this.siiTypeInvoiceOut,
- invoiceCorrectionTypeId: this.invoiceCorrectionType
+ refFk: this.invoiceOut.ref,
+ newClientFk: this.clientId,
+ cplusRectificationTypeFk: this.cplusRectificationType,
+ siiTypeInvoiceOutFk: this.siiTypeInvoiceOut,
+ invoiceCorrectionTypeFk: this.invoiceCorrectionType
};
this.$http.post(`InvoiceOuts/transferInvoice`, params).then(res => {
const invoiceId = res.data;
- this.vnApp.showSuccess(this.$t('Invoice trasfered!'));
+ this.vnApp.showSuccess(this.$t('Transferred invoice'));
this.$state.go('invoiceOut.card.summary', {id: invoiceId});
});
}
diff --git a/modules/invoiceOut/front/descriptor-menu/locale/es.yml b/modules/invoiceOut/front/descriptor-menu/locale/es.yml
index 0f74b5fec..aaeefd9cc 100644
--- a/modules/invoiceOut/front/descriptor-menu/locale/es.yml
+++ b/modules/invoiceOut/front/descriptor-menu/locale/es.yml
@@ -22,4 +22,5 @@ The email can't be empty: El correo no puede estar vacío
The following refund tickets have been created: "Se han creado los siguientes tickets de abono: {{ticketIds}}"
Refund...: Abono...
Transfer invoice to...: Transferir factura a...
-Cplus Type: Cplus Tipo
+Rectificative type: Tipo rectificativa
+Transferred invoice: Factura transferida
diff --git a/modules/invoiceOut/front/index/manual/index.html b/modules/invoiceOut/front/index/manual/index.html
index c3362a319..5872911e4 100644
--- a/modules/invoiceOut/front/index/manual/index.html
+++ b/modules/invoiceOut/front/index/manual/index.html
@@ -6,6 +6,7 @@
auto-load="true"
url="InvoiceOutSerials"
data="invoiceOutSerials"
+ where="{code: {neq: 'R'}}"
order="code">
{
}
],
returns: {
- type: ['number'],
+ type: ['object'],
root: true
},
http: {
@@ -54,7 +54,7 @@ module.exports = Self => {
if (tx) await tx.commit();
- return refundsTicket[0];
+ return refundsTicket;
} catch (e) {
if (tx) await tx.rollback();
throw e;
diff --git a/modules/ticket/back/methods/sale/specs/canEdit.spec.js b/modules/ticket/back/methods/sale/specs/canEdit.spec.js
index eef9136a8..200ea24cc 100644
--- a/modules/ticket/back/methods/sale/specs/canEdit.spec.js
+++ b/modules/ticket/back/methods/sale/specs/canEdit.spec.js
@@ -102,7 +102,7 @@ describe('sale canEdit()', () => {
try {
const options = {transaction: tx};
- const role = await models.Role.findOne({
+ const role = await models.VnRole.findOne({
where: {
name: roleEnabled.principalId
}
@@ -159,7 +159,7 @@ describe('sale canEdit()', () => {
try {
const options = {transaction: tx};
- const role = await models.Role.findOne({
+ const role = await models.VnRole.findOne({
where: {
name: roleEnabled.principalId
}
diff --git a/modules/ticket/back/methods/sale/specs/refund.spec.js b/modules/ticket/back/methods/sale/specs/refund.spec.js
index 08eb1fabd..60f77e90c 100644
--- a/modules/ticket/back/methods/sale/specs/refund.spec.js
+++ b/modules/ticket/back/methods/sale/specs/refund.spec.js
@@ -23,9 +23,9 @@ describe('Sale refund()', () => {
try {
const options = {transaction: tx};
- const refundedTicket = await models.Sale.refund(ctx, salesIds, servicesIds, withWarehouse, options);
+ const refundedTickets = await models.Sale.refund(ctx, salesIds, servicesIds, withWarehouse, options);
- expect(refundedTicket).toBeDefined();
+ expect(refundedTickets).toBeDefined();
await tx.rollback();
} catch (e) {
@@ -42,11 +42,11 @@ describe('Sale refund()', () => {
const options = {transaction: tx};
const ticketsBefore = await models.Ticket.find({}, options);
- const ticket = await models.Sale.refund(ctx, salesIds, servicesIds, withWarehouse, options);
+ const tickets = await models.Sale.refund(ctx, salesIds, servicesIds, withWarehouse, options);
const refundedTicket = await models.Ticket.findOne({
where: {
- id: ticket.id
+ id: tickets[0].id
},
include: [
{
diff --git a/modules/ticket/back/methods/ticket/canBeInvoiced.js b/modules/ticket/back/methods/ticket/canBeInvoiced.js
index 348f02348..855a864c2 100644
--- a/modules/ticket/back/methods/ticket/canBeInvoiced.js
+++ b/modules/ticket/back/methods/ticket/canBeInvoiced.js
@@ -10,20 +10,20 @@ module.exports = function(Self) {
description: 'The tickets id',
type: ['number'],
required: true
+ },
+ {
+ arg: 'isRectificative',
+ description: 'If it is rectificative',
+ type: 'boolean'
}
],
- returns: {
- arg: 'data',
- type: 'boolean',
- root: true
- },
http: {
path: `/canBeInvoiced`,
verb: 'get'
}
});
- Self.canBeInvoiced = async(ctx, ticketsIds, options) => {
+ Self.canBeInvoiced = async(ctx, ticketsIds, isRectificative, options) => {
const myOptions = {};
const $t = ctx.req.__; // $translate
@@ -34,26 +34,14 @@ module.exports = function(Self) {
where: {
id: {inq: ticketsIds}
},
- fields: ['id', 'refFk', 'shipped', 'totalWithVat', 'companyFk']
+ fields: ['id', 'refFk', 'shipped', 'totalWithVat']
}, myOptions);
- const [firstTicket] = tickets;
- const companyFk = firstTicket.companyFk;
-
- const query =
- `SELECT COUNT(*) isSpanishCompany
- FROM supplier s
- JOIN country c ON c.id = s.countryFk
- AND c.code = 'ES'
- WHERE s.id = ?`;
- const [supplierCompany] = await Self.rawSql(query, [companyFk], options);
-
- const isSpanishCompany = supplierCompany?.isSpanishCompany;
-
- const [result] = await Self.rawSql('SELECT hasAnyNegativeBase() AS base', null, options);
- const hasAnyNegativeBase = result?.base && isSpanishCompany;
- if (hasAnyNegativeBase)
- throw new UserError($t('Negative basis of tickets', {ticketsIds: ticketsIds}));
+ const taxBaseFunction = isRectificative ? 'hasAnyPositiveBase' : 'hasAnyNegativeBase';
+ const [hasAnyIncorrectBase] =
+ await Self.rawSql(`SELECT ${taxBaseFunction}() AS hasBasesProblem`, null, options);
+ if (hasAnyIncorrectBase?.hasBasesProblem)
+ throw new UserError($t(taxBaseFunction, {ticketsIds: ticketsIds}));
const today = Date.vnNew();
tickets.some(ticket => {
@@ -70,7 +58,5 @@ module.exports = function(Self) {
if (ticketsIds.length == 1 && priceZero)
throw new UserError(`A ticket with an amount of zero can't be invoiced`);
});
-
- return true;
};
};
diff --git a/modules/ticket/back/methods/ticket/invoiceTickets.js b/modules/ticket/back/methods/ticket/invoiceTickets.js
index fa3ee93af..06429836e 100644
--- a/modules/ticket/back/methods/ticket/invoiceTickets.js
+++ b/modules/ticket/back/methods/ticket/invoiceTickets.js
@@ -10,7 +10,13 @@ module.exports = function(Self) {
description: 'The tickets id',
type: ['number'],
required: true
+ },
+ {
+ arg: 'invoiceCorrection',
+ description: 'The invoice correction',
+ type: 'object',
}
+
],
returns: {
type: ['object'],
@@ -22,7 +28,7 @@ module.exports = function(Self) {
}
});
- Self.invoiceTickets = async(ctx, ticketsIds, options) => {
+ Self.invoiceTickets = async(ctx, ticketsIds, invoiceCorrection, options) => {
const models = Self.app.models;
const date = Date.vnNew();
date.setHours(0, 0, 0, 0);
@@ -41,10 +47,10 @@ module.exports = function(Self) {
let invoicesIds = [];
try {
const tickets = await models.Ticket.find({
+ fields: ['id', 'clientFk', 'companyFk', 'addressFk'],
where: {
id: {inq: ticketsIds}
- },
- fields: ['id', 'clientFk', 'companyFk']
+ }
}, myOptions);
const [firstTicket] = tickets;
@@ -55,22 +61,20 @@ module.exports = function(Self) {
if (!isSameClient)
throw new UserError(`You can't invoice tickets from multiple clients`);
- const client = await models.Client.findById(clientId, {
- fields: ['id', 'hasToInvoiceByAddress']
+ const {hasToInvoiceByAddress} = await models.Client.findById(clientId, {
+ fields: ['hasToInvoiceByAddress']
}, myOptions);
- if (client.hasToInvoiceByAddress) {
- const query = `
- SELECT DISTINCT addressFk
- FROM ticket t
- WHERE id IN (?)`;
- const result = await Self.rawSql(query, [ticketsIds], myOptions);
+ let ticketsByAddress = hasToInvoiceByAddress
+ ? Object.values(tickets.reduce((group, {id, addressFk}) => {
+ group[addressFk] = group[addressFk] ?? [];
+ group[addressFk].push(id);
+ return group;
+ }, {}))
+ : [ticketsIds];
- const addressIds = result.map(address => address.addressFk);
- for (const address of addressIds)
- await createInvoice(ctx, companyId, ticketsIds, address, invoicesIds, myOptions);
- } else
- await createInvoice(ctx, companyId, ticketsIds, null, invoicesIds, myOptions);
+ for (const ticketIds of ticketsByAddress)
+ invoicesIds.push(await createInvoice(ctx, companyId, ticketIds, invoiceCorrection, myOptions));
if (tx) await tx.commit();
} catch (e) {
@@ -85,9 +89,8 @@ module.exports = function(Self) {
return invoicesIds;
};
- async function createInvoice(ctx, companyId, ticketsIds, address, invoicesIds, myOptions) {
+ async function createInvoice(ctx, companyId, ticketsIds, invoiceCorrection, myOptions) {
const models = Self.app.models;
-
await models.Ticket.rawSql(`
CREATE OR REPLACE TEMPORARY TABLE tmp.ticketToInvoice
(PRIMARY KEY (id))
@@ -95,11 +98,8 @@ module.exports = function(Self) {
SELECT id
FROM vn.ticket
WHERE id IN (?)
- ${address ? `AND addressFk = ${address}` : ''}
`, [ticketsIds], myOptions);
-
- const invoiceId = await models.Ticket.makeInvoice(ctx, 'R', companyId, Date.vnNew(), myOptions);
- invoicesIds.push(invoiceId);
+ return models.Ticket.makeInvoice(ctx, 'R', companyId, Date.vnNew(), invoiceCorrection, myOptions);
}
};
diff --git a/modules/ticket/back/methods/ticket/makeInvoice.js b/modules/ticket/back/methods/ticket/makeInvoice.js
index e7ee806c7..83222a4ee 100644
--- a/modules/ticket/back/methods/ticket/makeInvoice.js
+++ b/modules/ticket/back/methods/ticket/makeInvoice.js
@@ -22,6 +22,11 @@ module.exports = function(Self) {
description: 'The invoice date',
type: 'date',
required: true
+ },
+ {
+ arg: 'invoiceCorrection',
+ description: 'The invoice correction',
+ type: 'object',
}
],
returns: {
@@ -34,7 +39,7 @@ module.exports = function(Self) {
}
});
- Self.makeInvoice = async(ctx, invoiceType, companyFk, invoiceDate, options) => {
+ Self.makeInvoice = async(ctx, invoiceType, companyFk, invoiceDate, invoiceCorrection, options) => {
const models = Self.app.models;
invoiceDate.setHours(0, 0, 0, 0);
@@ -62,20 +67,24 @@ module.exports = function(Self) {
fields: ['id', 'clientFk', 'addressFk']
}, myOptions);
- await models.Ticket.canBeInvoiced(ctx, ticketsIds, myOptions);
+ await models.Ticket.canBeInvoiced(ctx, ticketsIds, !!invoiceCorrection, myOptions);
const [firstTicket] = tickets;
const clientId = firstTicket.clientFk;
- const clientCanBeInvoiced = await models.Client.canBeInvoiced(clientId, companyFk, myOptions);
+ const clientCanBeInvoiced =
+ await models.Client.canBeInvoiced(clientId, companyFk, myOptions);
+
if (!clientCanBeInvoiced)
throw new UserError(`This client can't be invoiced`);
- const query = `SELECT vn.invoiceSerial(?, ?, ?) AS serial`;
- const [{serial}] = await Self.rawSql(query, [
- clientId,
- companyFk,
- invoiceType,
- ], myOptions);
+ const [{serial}] = invoiceCorrection ? [{serial: 'R'}] : await Self.rawSql(
+ `SELECT vn.invoiceSerial(?, ?, ?) AS serial`,
+ [
+ clientId,
+ companyFk,
+ invoiceType
+ ],
+ myOptions);
const invoiceOutSerial = await models.InvoiceOutSerial.findById(serial);
if (invoiceOutSerial?.taxAreaFk == 'WORLD') {
@@ -87,11 +96,17 @@ module.exports = function(Self) {
await Self.rawSql('CALL invoiceOut_new(?, ?, null, @invoiceId)', [serial, invoiceDate], myOptions);
const [resultInvoice] = await Self.rawSql('SELECT @invoiceId id', [], myOptions);
- if (!resultInvoice)
+ if (!resultInvoice?.id)
throw new UserError('No tickets to invoice', 'notInvoiced');
- if (serial != 'R' && resultInvoice.id)
- await Self.rawSql('CALL invoiceOutBooking(?)', [resultInvoice.id], myOptions);
+ if (invoiceCorrection) {
+ await models.InvoiceCorrection.create(
+ Object.assign(invoiceCorrection, {correctingFk: resultInvoice.id}),
+ myOptions
+ );
+ }
+
+ await Self.rawSql('CALL invoiceOutBooking(?)', [resultInvoice.id], myOptions);
if (tx) await tx.commit();
diff --git a/modules/ticket/back/methods/ticket/refund.js b/modules/ticket/back/methods/ticket/refund.js
index 758384ae2..4fed02260 100644
--- a/modules/ticket/back/methods/ticket/refund.js
+++ b/modules/ticket/back/methods/ticket/refund.js
@@ -15,7 +15,7 @@ module.exports = Self => {
}
],
returns: {
- type: ['number'],
+ type: ['object'],
root: true
},
http: {
diff --git a/modules/ticket/back/methods/ticket/specs/canBeInvoiced.spec.js b/modules/ticket/back/methods/ticket/specs/canBeInvoiced.spec.js
index 538dbc49f..78973e040 100644
--- a/modules/ticket/back/methods/ticket/specs/canBeInvoiced.spec.js
+++ b/modules/ticket/back/methods/ticket/specs/canBeInvoiced.spec.js
@@ -27,10 +27,7 @@ describe('ticket canBeInvoiced()', () => {
WHERE id IN (?)
`, [ticketId], options);
- const canBeInvoiced = await models.Ticket.canBeInvoiced(ctx, [ticketId], options);
-
- expect(canBeInvoiced).toEqual(false);
-
+ await models.Ticket.canBeInvoiced(ctx, [ticketId], false, options);
await tx.rollback();
} catch (e) {
error = e;
@@ -59,10 +56,7 @@ describe('ticket canBeInvoiced()', () => {
WHERE id IN (?)
`, [ticketId], options);
- const canBeInvoiced = await models.Ticket.canBeInvoiced(ctx, [ticketId], options);
-
- expect(canBeInvoiced).toEqual(false);
-
+ await models.Ticket.canBeInvoiced(ctx, [ticketId], false, options);
await tx.rollback();
} catch (e) {
error = e;
@@ -95,10 +89,7 @@ describe('ticket canBeInvoiced()', () => {
WHERE id IN (?)
`, [ticketId], options);
- const canBeInvoiced = await models.Ticket.canBeInvoiced(ctx, [ticketId], options);
-
- expect(canBeInvoiced).toEqual(false);
-
+ await models.Ticket.canBeInvoiced(ctx, [ticketId], false, options);
await tx.rollback();
} catch (e) {
error = e;
@@ -123,14 +114,36 @@ describe('ticket canBeInvoiced()', () => {
WHERE id IN (?)
`, [ticketId], options);
- const canBeInvoiced = await models.Ticket.canBeInvoiced(ctx, [ticketId], options);
-
- expect(canBeInvoiced).toEqual(true);
-
+ await models.Ticket.canBeInvoiced(ctx, [ticketId], false, options);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
+
+ it('should return falsy for a ticket has positiveBase', async() => {
+ const tx = await models.Ticket.beginTransaction({});
+
+ try {
+ const options = {transaction: tx};
+
+ await models.Ticket.rawSql(`
+ CREATE OR REPLACE TEMPORARY TABLE tmp.ticketToInvoice
+ (PRIMARY KEY (id))
+ ENGINE = MEMORY
+ SELECT id
+ FROM vn.ticket
+ WHERE id IN (?)
+ `, [ticketId], options);
+
+ await models.Ticket.canBeInvoiced(ctx, [ticketId], true, options);
+ await tx.rollback();
+ } catch (e) {
+ error = e;
+ await tx.rollback();
+ }
+
+ expect(error.message).toEqual(`hasAnyPositiveBase`);
+ });
});
diff --git a/modules/ticket/back/methods/ticket/specs/invoiceTickets.spec.js b/modules/ticket/back/methods/ticket/specs/invoiceTickets.spec.js
index 8971fb24a..162dc066a 100644
--- a/modules/ticket/back/methods/ticket/specs/invoiceTickets.spec.js
+++ b/modules/ticket/back/methods/ticket/specs/invoiceTickets.spec.js
@@ -31,7 +31,7 @@ describe('ticket invoiceTickets()', () => {
const options = {transaction: tx};
const ticketsIds = [11, 16];
- await models.Ticket.invoiceTickets(ctx, ticketsIds, options);
+ await models.Ticket.invoiceTickets(ctx, ticketsIds, null, options);
await tx.rollback();
} catch (e) {
@@ -57,7 +57,7 @@ describe('ticket invoiceTickets()', () => {
await client.updateAttribute('isTaxDataChecked', false, options);
const ticketsIds = [11];
- await models.Ticket.invoiceTickets(ctx, ticketsIds, options);
+ await models.Ticket.invoiceTickets(ctx, ticketsIds, null, options);
await tx.rollback();
} catch (e) {
@@ -80,8 +80,8 @@ describe('ticket invoiceTickets()', () => {
const options = {transaction: tx};
const ticketsIds = [11];
- await models.Ticket.invoiceTickets(ctx, ticketsIds, options);
- await models.Ticket.invoiceTickets(ctx, ticketsIds, options);
+ await models.Ticket.invoiceTickets(ctx, ticketsIds, null, options);
+ await models.Ticket.invoiceTickets(ctx, ticketsIds, null, options);
await tx.rollback();
} catch (e) {
@@ -102,7 +102,7 @@ describe('ticket invoiceTickets()', () => {
const options = {transaction: tx};
const ticketsIds = [11];
- const invoicesIds = await models.Ticket.invoiceTickets(ctx, ticketsIds, options);
+ const invoicesIds = await models.Ticket.invoiceTickets(ctx, ticketsIds, null, options);
expect(invoicesIds.length).toBeGreaterThan(0);
diff --git a/modules/ticket/back/methods/ticket/specs/makeInvoice.spec.js b/modules/ticket/back/methods/ticket/specs/makeInvoice.spec.js
index 9b1fd8f6f..456303602 100644
--- a/modules/ticket/back/methods/ticket/specs/makeInvoice.spec.js
+++ b/modules/ticket/back/methods/ticket/specs/makeInvoice.spec.js
@@ -42,7 +42,7 @@ describe('ticket makeInvoice()', () => {
WHERE id IN (?)
`, [ticketsIds], options);
- const invoiceId = await models.Ticket.makeInvoice(ctx, invoiceType, companyFk, invoiceDate, options);
+ const invoiceId = await models.Ticket.makeInvoice(ctx, invoiceType, companyFk, invoiceDate, null, options);
expect(invoiceId).toBeDefined();
@@ -70,7 +70,7 @@ describe('ticket makeInvoice()', () => {
WHERE id IN (?)
`, [ticketsId], options);
- await models.Ticket.makeInvoice(ctx, invoiceType, companyFk, invoiceDate, options);
+ await models.Ticket.makeInvoice(ctx, invoiceType, companyFk, invoiceDate, null, options);
await tx.rollback();
} catch (e) {
error = e;
diff --git a/modules/ticket/back/models/expedition.json b/modules/ticket/back/models/expedition.json
index 069c6e281..2dcca1e87 100644
--- a/modules/ticket/back/models/expedition.json
+++ b/modules/ticket/back/models/expedition.json
@@ -1,6 +1,9 @@
{
"name": "Expedition",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "expedition"
diff --git a/modules/ticket/back/models/sale.json b/modules/ticket/back/models/sale.json
index 72ca1f5e0..96a36bbc9 100644
--- a/modules/ticket/back/models/sale.json
+++ b/modules/ticket/back/models/sale.json
@@ -1,6 +1,9 @@
{
"name": "Sale",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "sale"
diff --git a/modules/ticket/back/models/ticket-dms.json b/modules/ticket/back/models/ticket-dms.json
index 071999be7..a3e697506 100644
--- a/modules/ticket/back/models/ticket-dms.json
+++ b/modules/ticket/back/models/ticket-dms.json
@@ -1,6 +1,9 @@
{
"name": "TicketDms",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "ticketDms"
diff --git a/modules/ticket/back/models/ticket-observation.json b/modules/ticket/back/models/ticket-observation.json
index 64e49b217..26d6f7586 100644
--- a/modules/ticket/back/models/ticket-observation.json
+++ b/modules/ticket/back/models/ticket-observation.json
@@ -1,6 +1,9 @@
{
"name": "TicketObservation",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "ticketObservation"
diff --git a/modules/ticket/back/models/ticket-packaging.json b/modules/ticket/back/models/ticket-packaging.json
index 6c94c810e..0cf494809 100644
--- a/modules/ticket/back/models/ticket-packaging.json
+++ b/modules/ticket/back/models/ticket-packaging.json
@@ -1,6 +1,9 @@
{
"name": "TicketPackaging",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "ticketPackaging"
diff --git a/modules/ticket/back/models/ticket-refund.json b/modules/ticket/back/models/ticket-refund.json
index d344a3f1c..249270c8b 100644
--- a/modules/ticket/back/models/ticket-refund.json
+++ b/modules/ticket/back/models/ticket-refund.json
@@ -1,6 +1,9 @@
{
"name": "TicketRefund",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "ticketRefund"
diff --git a/modules/ticket/back/models/ticket-request.json b/modules/ticket/back/models/ticket-request.json
index f8407792e..2cfcd30a1 100644
--- a/modules/ticket/back/models/ticket-request.json
+++ b/modules/ticket/back/models/ticket-request.json
@@ -1,6 +1,9 @@
{
"name": "TicketRequest",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "ticketRequest"
diff --git a/modules/ticket/back/models/ticket-service.json b/modules/ticket/back/models/ticket-service.json
index f1dbede13..4dfbd2fbd 100644
--- a/modules/ticket/back/models/ticket-service.json
+++ b/modules/ticket/back/models/ticket-service.json
@@ -1,6 +1,9 @@
{
"name": "TicketService",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "ticketService"
diff --git a/modules/ticket/back/models/ticket-tracking.json b/modules/ticket/back/models/ticket-tracking.json
index ac0eb9a69..025a07bc0 100644
--- a/modules/ticket/back/models/ticket-tracking.json
+++ b/modules/ticket/back/models/ticket-tracking.json
@@ -1,6 +1,9 @@
{
"name": "TicketTracking",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "ticketTracking"
diff --git a/modules/ticket/back/models/ticket-weekly.json b/modules/ticket/back/models/ticket-weekly.json
index c5e485aa2..7494cac79 100644
--- a/modules/ticket/back/models/ticket-weekly.json
+++ b/modules/ticket/back/models/ticket-weekly.json
@@ -1,6 +1,9 @@
{
"name": "TicketWeekly",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "ticketWeekly"
diff --git a/modules/ticket/back/models/ticket.json b/modules/ticket/back/models/ticket.json
index ec4193bed..c55cd82bb 100644
--- a/modules/ticket/back/models/ticket.json
+++ b/modules/ticket/back/models/ticket.json
@@ -1,6 +1,9 @@
{
"name": "Ticket",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "ticket"
diff --git a/modules/ticket/front/descriptor-menu/index.js b/modules/ticket/front/descriptor-menu/index.js
index 18db8c147..cd819e623 100644
--- a/modules/ticket/front/descriptor-menu/index.js
+++ b/modules/ticket/front/descriptor-menu/index.js
@@ -292,7 +292,7 @@ class Controller extends Section {
const query = 'Tickets/refund';
return this.$http.post(query, params)
.then(res => {
- const refundTicket = res.data;
+ const [refundTicket] = res.data;
this.vnApp.showSuccess(this.$t('The following refund ticket have been created', {
ticketId: refundTicket.id
}));
diff --git a/modules/ticket/front/descriptor-menu/index.spec.js b/modules/ticket/front/descriptor-menu/index.spec.js
index 1bb270165..c755b14c3 100644
--- a/modules/ticket/front/descriptor-menu/index.spec.js
+++ b/modules/ticket/front/descriptor-menu/index.spec.js
@@ -262,11 +262,12 @@ describe('Ticket Component vnTicketDescriptorMenu', () => {
const params = {
ticketsIds: [16]
};
- $httpBackend.expectPOST('Tickets/refund', params).respond({id: 99});
+ const response = {id: 99};
+ $httpBackend.expectPOST('Tickets/refund', params).respond([response]);
controller.refund();
$httpBackend.flush();
- expect(controller.$state.go).toHaveBeenCalledWith('ticket.card.sale', {id: 99});
+ expect(controller.$state.go).toHaveBeenCalledWith('ticket.card.sale', response);
});
});
diff --git a/modules/ticket/front/sale/index.js b/modules/ticket/front/sale/index.js
index 4f6a9e757..ed6d9b10a 100644
--- a/modules/ticket/front/sale/index.js
+++ b/modules/ticket/front/sale/index.js
@@ -526,7 +526,7 @@ class Controller extends Section {
const params = {salesIds: salesIds, withWarehouse: withWarehouse};
const query = 'Sales/refund';
this.$http.post(query, params).then(res => {
- const refundTicket = res.data;
+ const [refundTicket] = res.data;
this.vnApp.showSuccess(this.$t('The following refund ticket have been created', {
ticketId: refundTicket.id
}));
diff --git a/modules/ticket/front/sale/index.spec.js b/modules/ticket/front/sale/index.spec.js
index 70781eb58..36be32f52 100644
--- a/modules/ticket/front/sale/index.spec.js
+++ b/modules/ticket/front/sale/index.spec.js
@@ -729,7 +729,7 @@ describe('Ticket', () => {
salesIds: [1, 4],
};
const refundTicket = {id: 99};
- $httpBackend.expect('POST', 'Sales/refund', params).respond(200, refundTicket);
+ $httpBackend.expect('POST', 'Sales/refund', params).respond(200, [refundTicket]);
controller.createRefund();
$httpBackend.flush();
diff --git a/modules/travel/back/models/travel-thermograph.json b/modules/travel/back/models/travel-thermograph.json
index 08eec2847..cc8e60aaf 100644
--- a/modules/travel/back/models/travel-thermograph.json
+++ b/modules/travel/back/models/travel-thermograph.json
@@ -1,6 +1,9 @@
{
"name": "TravelThermograph",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "travelThermograph"
diff --git a/modules/travel/back/models/travel.json b/modules/travel/back/models/travel.json
index 95d458121..701894a76 100644
--- a/modules/travel/back/models/travel.json
+++ b/modules/travel/back/models/travel.json
@@ -1,6 +1,9 @@
{
"name": "Travel",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "travel"
diff --git a/modules/worker/back/methods/worker/specs/activeWithInheritedRole.spec.js b/modules/worker/back/methods/worker/specs/activeWithInheritedRole.spec.js
index da54f6adb..580e07351 100644
--- a/modules/worker/back/methods/worker/specs/activeWithInheritedRole.spec.js
+++ b/modules/worker/back/methods/worker/specs/activeWithInheritedRole.spec.js
@@ -3,7 +3,7 @@ const app = require('vn-loopback/server/server');
describe('Worker activeWithInheritedRole', () => {
let allRolesCount;
beforeAll(async() => {
- allRolesCount = await app.models.Role.count();
+ allRolesCount = await app.models.VnRole.count();
});
it('should return the workers with an inherited role of salesPerson', async() => {
diff --git a/modules/worker/back/models/device-production-user.json b/modules/worker/back/models/device-production-user.json
index 3eeaae137..35a90fb50 100644
--- a/modules/worker/back/models/device-production-user.json
+++ b/modules/worker/back/models/device-production-user.json
@@ -1,6 +1,9 @@
{
"name": "DeviceProductionUser",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"log": {
"model": "DeviceProductionLog",
"relation": "deviceProduction"
diff --git a/modules/worker/back/models/device-production.json b/modules/worker/back/models/device-production.json
index 35787cccc..f6e5105ad 100644
--- a/modules/worker/back/models/device-production.json
+++ b/modules/worker/back/models/device-production.json
@@ -1,6 +1,9 @@
{
"name": "DeviceProduction",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"log": {
"model": "DeviceProductionLog"
},
diff --git a/modules/worker/back/models/worker-dms.json b/modules/worker/back/models/worker-dms.json
index e9a9f1773..a5c0f30b2 100644
--- a/modules/worker/back/models/worker-dms.json
+++ b/modules/worker/back/models/worker-dms.json
@@ -1,6 +1,9 @@
{
"name": "WorkerDms",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "workerDocument"
diff --git a/modules/worker/back/models/worker.json b/modules/worker/back/models/worker.json
index 1a777fffe..ed430f133 100644
--- a/modules/worker/back/models/worker.json
+++ b/modules/worker/back/models/worker.json
@@ -1,7 +1,10 @@
{
"name": "Worker",
"description": "Company employees",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "worker"
diff --git a/modules/zone/back/models/zone-event.json b/modules/zone/back/models/zone-event.json
index e477dad6a..366bdec9d 100644
--- a/modules/zone/back/models/zone-event.json
+++ b/modules/zone/back/models/zone-event.json
@@ -1,6 +1,9 @@
{
"name": "ZoneEvent",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "zoneEvent"
diff --git a/modules/zone/back/models/zone-exclusion.json b/modules/zone/back/models/zone-exclusion.json
index 00c9145cd..6e91a0a01 100644
--- a/modules/zone/back/models/zone-exclusion.json
+++ b/modules/zone/back/models/zone-exclusion.json
@@ -1,6 +1,9 @@
{
"name": "ZoneExclusion",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "zoneExclusion"
diff --git a/modules/zone/back/models/zone-included.json b/modules/zone/back/models/zone-included.json
index deba73f34..a34e51091 100644
--- a/modules/zone/back/models/zone-included.json
+++ b/modules/zone/back/models/zone-included.json
@@ -1,6 +1,9 @@
{
"name": "ZoneIncluded",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "zoneIncluded"
diff --git a/modules/zone/back/models/zone-warehouse.json b/modules/zone/back/models/zone-warehouse.json
index b222e95e7..c2cc989f0 100644
--- a/modules/zone/back/models/zone-warehouse.json
+++ b/modules/zone/back/models/zone-warehouse.json
@@ -1,6 +1,9 @@
{
"name": "ZoneWarehouse",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "zoneWarehouse"
diff --git a/modules/zone/back/models/zone.json b/modules/zone/back/models/zone.json
index c86da3d3e..cf7371053 100644
--- a/modules/zone/back/models/zone.json
+++ b/modules/zone/back/models/zone.json
@@ -1,6 +1,9 @@
{
"name": "Zone",
- "base": "Loggable",
+ "base": "VnModel",
+ "mixins": {
+ "Loggable": true
+ },
"options": {
"mysql": {
"table": "zone"
diff --git a/package-lock.json b/package-lock.json
index 012fb50e7..36e11dc8f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "salix-back",
- "version": "24.02.01",
+ "version": "24.04.01",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "salix-back",
- "version": "24.02.01",
+ "version": "24.04.01",
"license": "GPL-3.0",
"dependencies": {
"axios": "^1.2.2",
diff --git a/package.json b/package.json
index ab3d99e19..f13c44162 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "salix-back",
- "version": "24.02.01",
+ "version": "24.04.01",
"author": "Verdnatura Levante SL",
"description": "Salix backend",
"license": "GPL-3.0",