diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3388ceb73a..bff0feed76 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,18 +5,27 @@ 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).
+## [2310.01] - 2023-03-23
+
+### Added
+-
+
+### Changed
+-
+
+### Fixed
+-
+
## [2308.01] - 2023-03-09
### Added
+- (Proveedores -> Datos fiscales) Añadido checkbox 'Vies'
- (Client -> Descriptor) Nuevo icono $ con barrotes para los clientes con impago
- (Trabajador -> Datos Básicos) Añadido nuevo campo Taquilla
- (Trabajador -> PDA) Nueva sección
### Changed
--
-
-### Fixed
--
+- (Ticket -> Borrar ticket) Restringido el borrado de tickets con abono
## [2306.01] - 2023-02-23
diff --git a/back/tests.js b/back/tests.js
index ab68937917..8f7cfd3d4f 100644
--- a/back/tests.js
+++ b/back/tests.js
@@ -30,7 +30,10 @@ async function test() {
const bootOptions = {dataSources};
const app = require('vn-loopback/server/server');
- app.boot(bootOptions);
+ await new Promise((resolve, reject) => {
+ app.boot(bootOptions,
+ err => err ? reject(err) : resolve());
+ });
const Jasmine = require('jasmine');
const jasmine = new Jasmine();
diff --git a/db/changes/230801/00-supplierIsVies.sql b/db/changes/230801/00-supplierIsVies.sql
new file mode 100644
index 0000000000..5861e7615e
--- /dev/null
+++ b/db/changes/230801/00-supplierIsVies.sql
@@ -0,0 +1,16 @@
+ALTER TABLE `vn`.`supplier` ADD `isVies` tinyint(4) DEFAULT 0 NOT NULL;
+
+UPDATE `vn`.`supplier` s
+ JOIN vn.country c ON c.id = s.countryFk
+ SET s.nif = MID(s.nif, 3, LENGTH(s.nif)-1), s.isVies = TRUE
+WHERE s.nif <> TRIM(IF(c.code = LEFT(s.nif, 2), MID(s.nif, 3, LENGTH(s.nif)-1), s.nif));
+
+INSERT IGNORE INTO `vn`.`chat`
+(senderFk, recipient, checkUserStatus, message, status, attempts)
+VALUES(19263, '#informatica-cau', 0, '
+```
+UPDATE `vn`.`supplier` s
+ JOIN vn.country c ON c.id = s.countryFk
+ SET s.nif = MID(s.nif, 3, LENGTH(s.nif)-1), s.isVies = TRUE
+WHERE s.nif <> TRIM(IF(c.code = LEFT(s.nif, 2), MID(s.nif, 3, LENGTH(s.nif)-1), s.nif));
+```', 0, 0);
diff --git a/db/changes/230801/01-sage_supplierAdd.sql b/db/changes/230801/01-sage_supplierAdd.sql
new file mode 100644
index 0000000000..66cb0aff17
--- /dev/null
+++ b/db/changes/230801/01-sage_supplierAdd.sql
@@ -0,0 +1,127 @@
+DROP PROCEDURE IF EXISTS `sage`.`clientSupplier_add`;
+
+DELIMITER $$
+$$
+CREATE DEFINER=`root`@`localhost` PROCEDURE `sage`.`clientSupplier_add`(vCompanyFk INT)
+BEGIN
+/**
+ * Prepara los datos de clientes y proveedores para exportarlos a Sage
+ * @vCompanyFk Empresa dela que se quiere trasladar datos
+ */
+ DECLARE vCountryCeutaMelillaFk INT;
+ DECLARE vCountryCanariasCode, vCountryCeutaMelillaCode VARCHAR(2);
+
+ SELECT SiglaNacion INTO vCountryCanariasCode
+ FROM Naciones
+ WHERE Nacion ='ISLAS CANARIAS';
+
+ SELECT CodigoNacion, SiglaNacion INTO vCountryCeutaMelillaFk, vCountryCeutaMelillaCode
+ FROM Naciones
+ WHERE Nacion ='CEUTA Y MELILLA';
+
+ TRUNCATE TABLE clientesProveedores;
+
+ INSERT INTO clientesProveedores
+ (CodigoEmpresa,
+ ClienteOProveedor,
+ CodigoClienteProveedor,
+ RazonSocial,
+ Nombre,
+ Domicilio,
+ CodigoCuenta,
+ CifDni,
+ CifEuropeo,
+ CodigoPostal,
+ Municipio,
+ CodigoProvincia,
+ Provincia,
+ CodigoNacion,
+ SiglaNacion,
+ PersonaFisicaJuridica,
+ TipoDocumentoPersona,
+ CodigoIva,
+ Nacion,
+ Telefono,
+ Telefono2,
+ CodigoTransaccion,
+ CodigoRetencion,
+ Email1,
+ iban)
+ SELECT
+ company_getCode(vCompanyFk),
+ 'C',
+ c.id,
+ c.socialName,
+ c.socialName,
+ IFNULL(c.street, ''),
+ c.accountingAccount,
+ TRIM(IF(c.isVies, CONCAT(cu.code,c.fi), c.fi)),
+ IF(n.NacionCEE,TRIM(IF(cu.code = LEFT(c.fi, 2), c.fi, CONCAT(cu.code,c.fi))) , ''),
+ IFNULL(c.postcode, ''),
+ IFNULL(c.city, ''),
+ IFNULL(pr.CodigoProvincia, ''),
+ IFNULL(p.name, ''),
+ IF(n.SiglaNacion = vCountryCanariasCode COLLATE utf8mb3_unicode_ci, IF(@isCeutaMelilla := IF(pr.Provincia IN ('CEUTA', 'MELILLA'), TRUE, FALSE), vCountryCeutaMelillaFk, IF (@isCanarias, vCountryCanariasCode, n.CodigoNacion)), n.CodigoNacion),
+ IF(n.SiglaNacion = vCountryCanariasCode COLLATE utf8mb3_unicode_ci, IF(@isCeutaMelilla, vCountryCeutaMelillaCode, IF (@isCanarias, vCountryCanariasCode, n.SiglaNacion)), n.SiglaNacion),
+ IF((c.fi REGEXP '^([[:blank:]]|[[:digit:]])'), 'J','F'),
+ IF(cu.code IN('ES','EX'),
+ 1,
+ IF((cu.isUeeMember AND c.isVies), 2, 4)),
+ IFNULL(c.taxTypeSageFk,0),
+ IF(n.SiglaNacion = vCountryCanariasCode COLLATE utf8mb3_unicode_ci,
+ IF(@isCeutaMelilla, 'CEUTA Y MELILLA', IF (@isCanarias, 'ISLAS CANARIAS', n.Nacion)),
+ n.Nacion),
+ IFNULL(c.phone, ''),
+ IFNULL(c.mobile, ''),
+ IFNULL(c.transactionTypeSageFk, 0),
+ '0',
+ IFNULL(SUBSTR(c.email, 1, LOCATE(',', CONCAT(c.email, ','))-1), ''),
+ IFNULL(c.iban, '')
+ FROM vn.`client` c
+ JOIN clientLastTwoMonths clm ON clm.clientFk = c.id
+ LEFT JOIN vn.country cu ON cu.id = c.countryFk
+ LEFT JOIN Naciones n ON n.countryFk = cu.id
+ LEFT JOIN vn.province p ON p.id = c.provinceFk
+ LEFT JOIN Provincias pr ON pr.provinceFk = p.id
+ WHERE c.isRelevant
+ AND clm.companyFk = vCompanyFk
+ UNION ALL
+ SELECT company_getCode(vCompanyFk),
+ 'P',
+ s.id,
+ s.name,
+ s.name,
+ IFNULL(s.street, ''),
+ s.account,
+ TRIM(IF(s.isVies, CONCAT(co.code,s.nif), s.nif)),
+ IF(n.NacionCEE, TRIM(CONCAT(co.code, IF(co.code = LEFT(s.nif, 2), MID(s.nif, 3, LENGTH(s.nif) - 1), s.nif))), ''),
+ IFNULL(s.postCode,''),
+ IFNULL(s.city, ''),
+ IFNULL(pr.CodigoProvincia, ''),
+ IFNULL(p.name, ''),
+ n.CodigoNacion,
+ n.SiglaNacion COLLATE utf8mb3_unicode_ci,
+ IF((s.nif REGEXP '^([[:blank:]]|[[:digit:]])'),'J','F'),
+ IF(co.country IN ('España', 'España exento'), 1,IF(co.isUeeMember = 1, 2, 4)),
+ IFNULL(s.taxTypeSageFk, 0),
+ n.Nacion,
+ IFNULL(sc.phone, ''),
+ IFNULL(sc.mobile, ''),
+ IFNULL(s.transactionTypeSageFk, 0),
+ IFNULL(s.withholdingSageFk, '0'),
+ IFNULL(SUBSTR(sc.email, 1, (COALESCE(NULLIF(LOCATE(',', sc.email), 0), 99) - 1)), ''),
+ IFNULL(iban, '')
+ FROM vn.supplier s
+ JOIN supplierLastThreeMonths pl ON pl.supplierFk = s.id
+ LEFT JOIN vn.country co ON co.id = s.countryFk
+ LEFT JOIN Naciones n ON n.countryFk = co.id
+ LEFT JOIN vn.province p ON p.id = s.provinceFk
+ LEFT JOIN Provincias pr ON pr.provinceFk = p.id
+ LEFT JOIN vn.supplierContact sc ON sc.supplierFk = s.id
+ LEFT JOIN vn.supplierAccount sa ON sa.supplierFk = s.id
+ WHERE pl.companyFk = vCompanyFk AND
+ s.isActive AND
+ s.nif <> ''
+ GROUP BY pl.supplierFk, pl.companyFk;
+END$$
+DELIMITER ;
diff --git a/db/changes/231001/.gitkeep b/db/changes/231001/.gitkeep
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql
index c0989f1ed0..5af9b9eeb3 100644
--- a/db/dump/fixtures.sql
+++ b/db/dump/fixtures.sql
@@ -2787,6 +2787,10 @@ INSERT INTO `vn`.`workerConfig` (`id`, `businessUpdated`, `roleFk`)
VALUES
(1, NULL, 1);
+INSERT INTO `vn`.`ticketRefund`(`refundTicketFk`, `originalTicketFk`)
+ VALUES
+ (1, 12);
+
INSERT INTO `vn`.`deviceProductionModels` (`code`)
VALUES
('BLACKVIEW'),
diff --git a/db/tests/vn/ticketCalculateClon.spec.js b/db/tests/vn/ticketCalculateClon.spec.js
index a3c7904922..9116d805fb 100644
--- a/db/tests/vn/ticketCalculateClon.spec.js
+++ b/db/tests/vn/ticketCalculateClon.spec.js
@@ -22,7 +22,7 @@ describe('ticket ticketCalculateClon()', () => {
originalTicketId: 11
};
- stmt = new ParameterizedSQL('CALL vn.ticketCreateWithUser(?, ?, ?, ?, ?, ?, ?, ?, ?, @result)', [
+ stmt = new ParameterizedSQL('CALL vn.ticket_add(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, @result)', [
params.clientFk,
params.shipped,
params.warehouseFk,
@@ -31,7 +31,8 @@ describe('ticket ticketCalculateClon()', () => {
params.agencyType,
params.routeFk,
params.landed,
- params.userId
+ params.userId,
+ true
]);
stmts.push(stmt);
@@ -71,7 +72,7 @@ describe('ticket ticketCalculateClon()', () => {
originalTicketId: 11
};
- stmt = new ParameterizedSQL('CALL vn.ticketCreateWithUser(?, ?, ?, ?, ?, ?, ?, ?, ?, @result)', [
+ stmt = new ParameterizedSQL('CALL vn.ticket_add(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, @result)', [
params.clientFk,
params.shipped,
params.warehouseFk,
@@ -80,7 +81,8 @@ describe('ticket ticketCalculateClon()', () => {
params.agencyType,
params.routeFk,
params.landed,
- params.userId
+ params.userId,
+ true
]);
stmts.push(stmt);
diff --git a/db/tests/vn/ticketCreateWithUser.spec.js b/db/tests/vn/ticketCreateWithUser.spec.js
index 4aeece564a..5dd84d3975 100644
--- a/db/tests/vn/ticketCreateWithUser.spec.js
+++ b/db/tests/vn/ticketCreateWithUser.spec.js
@@ -1,7 +1,7 @@
const app = require('vn-loopback/server/server');
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
-describe('ticket ticketCreateWithUser()', () => {
+describe('ticket ticket_add()', () => {
const today = Date.vnNew();
it('should confirm the procedure creates the expected ticket', async() => {
let stmts = [];
@@ -21,7 +21,7 @@ describe('ticket ticketCreateWithUser()', () => {
userId: 18
};
- stmt = new ParameterizedSQL(`CALL vn.ticketCreateWithUser(?, ?, ?, ?, ?, ?, ?, ?, ?, @newTicketId)`, [
+ stmt = new ParameterizedSQL(`CALL vn.ticket_add(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, @newTicketId)`, [
params.clientFk,
params.shipped,
params.warehouseFk,
@@ -30,7 +30,8 @@ describe('ticket ticketCreateWithUser()', () => {
params.agencyModeFk,
params.routeFk,
params.landed,
- params.userId
+ params.userId,
+ true
]);
stmts.push(stmt);
@@ -70,7 +71,7 @@ describe('ticket ticketCreateWithUser()', () => {
userId: 18
};
- stmt = new ParameterizedSQL('CALL vn.ticketCreateWithUser(?, ?, ?, ?, ?, ?, ?, ?, ?, @newTicketId)', [
+ stmt = new ParameterizedSQL('CALL vn.ticket_add(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, @newTicketId)', [
params.clientFk,
params.shipped,
params.warehouseFk,
@@ -79,7 +80,8 @@ describe('ticket ticketCreateWithUser()', () => {
params.agencyModeFk,
params.routeFk,
params.landed,
- params.userId
+ params.userId,
+ true
]);
stmts.push(stmt);
@@ -120,7 +122,7 @@ describe('ticket ticketCreateWithUser()', () => {
userId: 18
};
- stmt = new ParameterizedSQL(`CALL vn.ticketCreateWithUser(?, ?, ?, ?, ?, ?, ?, ?, ?, @newTicketId)`, [
+ stmt = new ParameterizedSQL(`CALL vn.ticket_add(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, @newTicketId)`, [
params.clientFk,
params.shipped,
params.warehouseFk,
@@ -129,7 +131,8 @@ describe('ticket ticketCreateWithUser()', () => {
params.agencyModeFk,
params.routeFk,
params.landed,
- params.userId
+ params.userId,
+ true
]);
stmts.push(stmt);
@@ -172,7 +175,7 @@ describe('ticket ticketCreateWithUser()', () => {
]);
stmts.push(stmt);
- stmt = new ParameterizedSQL(`CALL vn.ticketCreateWithUser(?, ?, ?, ?, ?, ?, ?, ?, ?, @newTicketId)`, [
+ stmt = new ParameterizedSQL(`CALL vn.ticket_add(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, @newTicketId)`, [
params.clientFk,
params.shipped,
params.warehouseFk,
@@ -181,7 +184,8 @@ describe('ticket ticketCreateWithUser()', () => {
params.agencyModeFk,
params.routeFk,
params.landed,
- params.userId
+ params.userId,
+ true
]);
stmts.push(stmt);
stmts.push(`select @newTicketId`);
diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js
index e32bab57db..9840696c23 100644
--- a/e2e/helpers/selectors.js
+++ b/e2e/helpers/selectors.js
@@ -22,6 +22,7 @@ export default {
userConfigSecondAutocomplete: '#localBank',
userConfigThirdAutocomplete: '#localCompany',
acceptButton: '.vn-confirm.shown button[response=accept]',
+ cancelButton: '.vn-confirm.shown input[response=cancel]',
searchButton: 'vn-searchbar vn-icon[icon="search"]'
},
moduleIndex: {
diff --git a/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js b/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js
index 9e4898be9a..36161ae1d5 100644
--- a/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js
+++ b/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js
@@ -227,9 +227,21 @@ describe('Ticket Edit sale path', () => {
await page.waitToClick(selectors.ticketSales.firstSaleCheckbox);
await page.waitToClick(selectors.ticketSales.moreMenu);
await page.waitToClick(selectors.ticketSales.moreMenuRefund);
+ await page.waitForSnackbar();
await page.waitForState('ticket.card.sale');
});
+ it('should show error trying to delete a ticket with a refund', async() => {
+ await page.accessToSearchResult('16');
+ await page.waitToClick(selectors.ticketDescriptor.moreMenu);
+ await page.waitToClick(selectors.ticketDescriptor.moreMenuDeleteTicket);
+ await page.waitToClick(selectors.globalItems.acceptButton);
+ const message = await page.waitForSnackbar();
+
+ expect(message.text).toContain('Tickets with associated refunds can\'t be deleted');
+ await page.waitToClick(selectors.globalItems.cancelButton);
+ });
+
it('should select the third sale and create a claim of it', async() => {
await page.accessToSearchResult('16');
await page.accessToSection('ticket.card.sale');
diff --git a/front/core/components/autocomplete/style.scss b/front/core/components/autocomplete/style.scss
index 19e8362d58..201d29c1e5 100755
--- a/front/core/components/autocomplete/style.scss
+++ b/front/core/components/autocomplete/style.scss
@@ -19,6 +19,10 @@
padding-right: 0;
}
}
+
+ & > .icons.pre {
+ min-width: 22px
+ }
}
&.readonly > .container > .icons.post {
display: none;
diff --git a/front/core/components/chip/style.scss b/front/core/components/chip/style.scss
index 7651638bea..5628614411 100644
--- a/front/core/components/chip/style.scss
+++ b/front/core/components/chip/style.scss
@@ -58,10 +58,33 @@ vn-chip {
background-color: $color-font-bg-dark;
color: $color-font-bg;
}
+ &.pink,
+ &.pink.clickable:hover,
+ &.pink.clickable:focus {
+ background-color: $color-pink;
+ }
+ &.dark-notice,
+ &.dark-notice.clickable:hover,
+ &.dark-notice.clickable:focus {
+ background-color: $color-notice;
+ }
+ &.yellow,
+ &.yellow.clickable:hover,
+ &.yellow.clickable:focus {
+ background-color: $color-yellow;
+ }
+ &.none,
+ &.none.clickable:hover,
+ &.none.clickable:focus {
+ background-color: $color-bg-panel;
+ border-radius: 50%;
+ border: 1px solid $color-font-link
+
+ }
&.clickable {
@extend %clickable;
opacity: 0.8;
-
+
&:hover,
&:focus {
opacity: 1;
@@ -118,4 +141,4 @@ vn-avatar {
display: inline-block;
min-width: 28px;
border-radius: 50%;
-}
\ No newline at end of file
+}
diff --git a/front/core/components/field/index.html b/front/core/components/field/index.html
index bd13f46d6d..0d65c1f406 100644
--- a/front/core/components/field/index.html
+++ b/front/core/components/field/index.html
@@ -12,7 +12,7 @@
*
-
+
.icons.pre.clearable {
+ min-width: 22px
+ }
& > .underline {
position: absolute;
bottom: 0;
diff --git a/loopback/locale/en.json b/loopback/locale/en.json
index c810e5a698..eeb25f75dd 100644
--- a/loopback/locale/en.json
+++ b/loopback/locale/en.json
@@ -147,8 +147,8 @@
"Receipt's bank was not found": "Receipt's bank was not found",
"This receipt was not compensated": "This receipt was not compensated",
"Client's email was not found": "Client's email was not found",
+ "Tickets with associated refunds": "Tickets with associated refunds can't be deleted. This ticket is associated with refund Nº {{id}}",
"It is not possible to modify tracked sales": "It is not possible to modify tracked sales",
"It is not possible to modify sales that their articles are from Floramondo": "It is not possible to modify sales that their articles are from Floramondo",
- "It is not possible to modify cloned sales": "It is not possible to modify cloned sales",
- "Valid priorities: 1,2,3": "Valid priorities: 1,2,3"
+ "It is not possible to modify cloned sales": "It is not possible to modify cloned sales"
}
diff --git a/loopback/locale/es.json b/loopback/locale/es.json
index 10db9a54ff..507cc90030 100644
--- a/loopback/locale/es.json
+++ b/loopback/locale/es.json
@@ -259,11 +259,12 @@
"Aplicación bloqueada por el usuario 9": "Aplicación bloqueada por el usuario 9",
"Failed to upload file": "Error al subir archivo",
"The DOCUWARE PDF document does not exists": "El documento PDF Docuware no existe",
- "It is not possible to modify tracked sales": "No es posible modificar líneas de pedido que se hayan empezado a preparar",
- "It is not possible to modify sales that their articles are from Floramondo": "No es posible modificar líneas de pedido cuyos artículos sean de Floramondo",
- "It is not possible to modify cloned sales": "No es posible modificar líneas de pedido clonadas",
+ "It is not possible to modify tracked sales": "No es posible modificar líneas de pedido que se hayan empezado a preparar",
+ "It is not possible to modify sales that their articles are from Floramondo": "No es posible modificar líneas de pedido cuyos artículos sean de Floramondo",
+ "It is not possible to modify cloned sales": "No es posible modificar líneas de pedido clonadas",
"A supplier with the same name already exists. Change the country.": "Un proveedor con el mismo nombre ya existe. Cambie el país.",
"There is no assigned email for this client": "No hay correo asignado para este cliente",
- "This locker has already been assigned": "Esta taquilla ya ha sido asignada"
+ "This locker has already been assigned": "Esta taquilla ya ha sido asignada",
+ "Tickets with associated refunds": "No se pueden borrar tickets con abonos asociados. Este ticket está asociado al abono Nº {{id}}",
+ "Not exist this branch": "La rama no existe"
}
-
diff --git a/modules/item/back/methods/item/new.js b/modules/item/back/methods/item/new.js
index 0057cb50f8..d066f2c9f0 100644
--- a/modules/item/back/methods/item/new.js
+++ b/modules/item/back/methods/item/new.js
@@ -57,6 +57,7 @@ module.exports = Self => {
const itemType = await models.ItemType.findById(params.typeFk, {fields: ['isLaid']}, myOptions);
params.isLaid = itemType.isLaid;
+ params.isPhotoRequested = true;
const item = await models.Item.create(params, myOptions);
diff --git a/modules/item/back/models/item.json b/modules/item/back/models/item.json
index 2f58c30a9b..10300f7a1a 100644
--- a/modules/item/back/models/item.json
+++ b/modules/item/back/models/item.json
@@ -146,6 +146,12 @@
},
"isLaid": {
"type": "boolean"
+ },
+ "isPhotoRequested": {
+ "type": "boolean",
+ "mysql":{
+ "columnName": "doPhoto"
+ }
}
},
"relations": {
diff --git a/modules/item/front/basic-data/index.html b/modules/item/front/basic-data/index.html
index fd21ab240f..974aa37d8b 100644
--- a/modules/item/front/basic-data/index.html
+++ b/modules/item/front/basic-data/index.html
@@ -182,6 +182,12 @@
ng-model="$ctrl.item.isFragile"
info="Is shown at website, app that this item cannot travel (wreath, palms, ...)">
+
+
diff --git a/modules/item/front/basic-data/locale/es.yml b/modules/item/front/basic-data/locale/es.yml
index d59752ebb1..747dfe7920 100644
--- a/modules/item/front/basic-data/locale/es.yml
+++ b/modules/item/front/basic-data/locale/es.yml
@@ -11,4 +11,6 @@ Identifier: Identificador
Fragile: Frágil
Is shown at website, app that this item cannot travel (wreath, palms, ...): Se muestra en la web, app que este artículo no puede viajar (coronas, palmas, ...)
Multiplier: Multiplicador
-Generic: Genérico
\ No newline at end of file
+Generic: Genérico
+This item does need a photo: Este artículo necesita una foto
+Do photo: Hacer foto
\ No newline at end of file
diff --git a/modules/item/front/descriptor/index.js b/modules/item/front/descriptor/index.js
index 972c89ae06..5f38d08dde 100644
--- a/modules/item/front/descriptor/index.js
+++ b/modules/item/front/descriptor/index.js
@@ -91,6 +91,9 @@ class Controller extends Descriptor {
this.$.photo.setAttribute('src', newSrc);
this.$.photo.setAttribute('zoom-image', newZoomSrc);
+
+ if (this.item.isPhotoRequested)
+ this.$http.patch(`Items/${this.item.id}`, {isPhotoRequested: false});
}
getWarehouseName(warehouseFk) {
diff --git a/modules/item/front/descriptor/index.spec.js b/modules/item/front/descriptor/index.spec.js
index 23053432e6..dc2a5acf77 100644
--- a/modules/item/front/descriptor/index.spec.js
+++ b/modules/item/front/descriptor/index.spec.js
@@ -8,7 +8,8 @@ describe('vnItemDescriptor', () => {
id: 1,
itemType: {
warehouseFk: 1
- }
+ },
+ isPhotoRequested: true
};
const stock = {
visible: 1,
@@ -43,4 +44,16 @@ describe('vnItemDescriptor', () => {
expect(controller.item).toEqual(item);
});
});
+
+ describe('onUploadResponse()', () => {
+ it(`should change isPhotoRequested when a new photo is uploaded`, () => {
+ controller.item = item;
+ controller.$rootScope = {imagePath: () => {}};
+ controller.$.photo = {setAttribute: () => {}};
+
+ $httpBackend.expectPATCH(`Items/${item.id}`).respond(200);
+ controller.onUploadResponse();
+ $httpBackend.flush();
+ });
+ });
});
diff --git a/modules/item/front/diary/index.js b/modules/item/front/diary/index.js
index 9e104c8e67..03134913fb 100644
--- a/modules/item/front/diary/index.js
+++ b/modules/item/front/diary/index.js
@@ -70,7 +70,8 @@ class Controller extends Section {
}
$onDestroy() {
- this.card.reload();
+ if (this.$state.getCurrentPath()[2].state.name === 'item')
+ this.card.reload();
}
}
diff --git a/modules/item/front/summary/index.html b/modules/item/front/summary/index.html
index 40e9c5aa75..46a2baef44 100644
--- a/modules/item/front/summary/index.html
+++ b/modules/item/front/summary/index.html
@@ -75,6 +75,15 @@
{{$ctrl.summary.item.itemType.worker.user.name}}
+
+
+
+
diff --git a/modules/item/front/waste/index/index.html b/modules/item/front/waste/index/index.html
index 5da5acbf12..f1475c1b3d 100644
--- a/modules/item/front/waste/index/index.html
+++ b/modules/item/front/waste/index/index.html
@@ -33,16 +33,16 @@
-
+ ng-show="$ctrl.wasteConfig[detail.buyer].hidden">
{{::waste.family}}
{{::(waste.percentage / 100) | percentage: 2}}
{{::waste.dwindle | currency: 'EUR'}}
{{::waste.total | currency: 'EUR'}}
-
+
diff --git a/modules/mdb/back/methods/mdbVersion/upload.js b/modules/mdb/back/methods/mdbVersion/upload.js
index 864a73f527..58fc46abb5 100644
--- a/modules/mdb/back/methods/mdbVersion/upload.js
+++ b/modules/mdb/back/methods/mdbVersion/upload.js
@@ -47,7 +47,16 @@ module.exports = Self => {
verb: 'POST'
}
});
- Self.upload = async(ctx, options) => {
+ Self.upload = async(
+ ctx,
+ appName,
+ toVersion,
+ branch,
+ fromVersion,
+ description,
+ unlock,
+ options
+ ) => {
const models = Self.app.models;
const myOptions = {};
const $t = ctx.req.__; // $translate
@@ -55,12 +64,6 @@ module.exports = Self => {
const AccessContainer = models.AccessContainer;
const fileOptions = {};
let tx;
- const appName = ctx.args.appName;
- const toVersion = ctx.args.toVersion;
- const branch = ctx.args.branch;
- const fromVersion = ctx.args.fromVersion;
- let description = ctx.args.description;
- const unlock = ctx.args.unlock;
if (typeof options == 'object')
Object.assign(myOptions, options);
@@ -153,11 +156,14 @@ module.exports = Self => {
formatDesc += `*${appName.toUpperCase()}* v.${toVersion} `;
const oldVersion = await models.MdbVersionTree.findOne({
- where: {version: fromVersion},
+ where: {
+ version: fromVersion,
+ app: appName
+ },
fields: ['branchFk']
}, myOptions);
- if (branch == oldVersion.branchFk)
+ if (!oldVersion || branch == oldVersion.branchFk)
formatDesc += `[*${branch}*]: `;
else
formatDesc += `[*${oldVersion.branchFk}* » *${branch}*]: `;
diff --git a/modules/route/front/summary/index.html b/modules/route/front/summary/index.html
index a64ad4ff72..56f7a49b9b 100644
--- a/modules/route/front/summary/index.html
+++ b/modules/route/front/summary/index.html
@@ -93,7 +93,14 @@
{{ticket.priority | dashIfEmpty}}
{{ticket.street}}
- {{ticket.city}}
+
+ {{::ticket.city}}
+
{{ticket.postalCode}}
{
+ if (!response.data)
+ throw new UserError(`The route's vehicle doesn't have a delivery point`);
+
+ const address = response.data + '+to:' + ticket.postalCode + ' ' + ticket.city + ' ' + ticket.street;
+ const url = 'http://gps.buscalia.com/usuario/localizar.aspx?bmi=true&addr=';
+ window.open(url + encodeURI(address), '_blank');
+ });
+ }
}
ngModule.vnComponent('vnRouteSummary', {
diff --git a/modules/route/front/summary/index.spec.js b/modules/route/front/summary/index.spec.js
index ad300817ac..cfa21aeb92 100644
--- a/modules/route/front/summary/index.spec.js
+++ b/modules/route/front/summary/index.spec.js
@@ -37,5 +37,29 @@ describe('Route', () => {
expect(controller.packagesTotal).toEqual(4);
});
});
+
+ describe('goToBuscaman()', () => {
+ it('should open buscaman with the given arguments', () => {
+ jest.spyOn(window, 'open').mockReturnThis();
+ const expectedUrl = 'http://gps.buscalia.com/usuario/localizar.aspx?bmi=true&addr=46460%20Av%20Espioca%20100+to:n19%20London%20my%20street';
+ controller.route = {vehicleFk: 1};
+ const url = `Routes/${controller.route.vehicleFk}/getDeliveryPoint`;
+ $httpBackend.when('GET', `Routes/1/summary`).respond();
+ $httpBackend.expectGET(url).respond('46460 Av Espioca 100');
+
+ const ticket = {
+ id: 1,
+ checked: true,
+ street: 'my street',
+ postalCode: 'n19',
+ city: 'London'
+ };
+
+ controller.goToBuscaman(ticket);
+ $httpBackend.flush();
+
+ expect(window.open).toHaveBeenCalledWith(expectedUrl, '_blank');
+ });
+ });
});
});
diff --git a/modules/route/front/tickets/index.html b/modules/route/front/tickets/index.html
index 18d6fb1601..32a4a2d7c6 100644
--- a/modules/route/front/tickets/index.html
+++ b/modules/route/front/tickets/index.html
@@ -93,7 +93,14 @@
{{::ticket.street}}
- {{::ticket.city}}
+
+ {{::ticket.city}}
+
{{::ticket.postalCode}}
{
- if (!response.data)
+ this.$http.get(`Routes/${this.route.vehicleFk}/getDeliveryPoint`).then(res => {
+ if (!res.data)
throw new UserError(`The route's vehicle doesn't have a delivery point`);
- return response.data;
- }).then(address => {
- let addresses;
- if (address) addresses = address;
- let lines = this.getSelectedItems(this.tickets);
-
- let url = 'http://gps.buscalia.com/usuario/localizar.aspx?bmi=true&addr=';
+ let addresses = res.data;
+ const lines = ticket ? [ticket] : this.getSelectedItems(this.tickets);
lines.forEach((line, index) => {
- const previusLine = lines[index - 1] ? lines[index - 1].street : null;
- if (previusLine != line.street)
+ const previousLine = lines[index - 1] ? lines[index - 1].street : null;
+ if (previousLine != line.street)
addresses = addresses + '+to:' + line.postalCode + ' ' + line.city + ' ' + line.street;
});
- window.open(url + addresses, '_blank');
+ const url = 'http://gps.buscalia.com/usuario/localizar.aspx?bmi=true&addr=';
+ window.open(url + encodeURI(addresses), '_blank');
});
}
diff --git a/modules/route/front/tickets/index.spec.js b/modules/route/front/tickets/index.spec.js
index f4a58154e4..2c73048bd7 100644
--- a/modules/route/front/tickets/index.spec.js
+++ b/modules/route/front/tickets/index.spec.js
@@ -136,7 +136,7 @@ describe('Route', () => {
describe('goToBuscaman()', () => {
it('should open buscaman with the given arguments', () => {
jest.spyOn(window, 'open').mockReturnThis();
- const expectedUrl = 'http://gps.buscalia.com/usuario/localizar.aspx?bmi=true&addr=46460 Av Espioca 100+to:n19 London my street';
+ const expectedUrl = 'http://gps.buscalia.com/usuario/localizar.aspx?bmi=true&addr=46460%20Av%20Espioca%20100+to:n19%20London%20my%20street';
controller.route = {vehicleFk: 1};
const url = `Routes/${controller.route.vehicleFk}/getDeliveryPoint`;
$httpBackend.expectGET(url).respond('46460 Av Espioca 100');
diff --git a/modules/supplier/back/methods/supplier/updateFiscalData.js b/modules/supplier/back/methods/supplier/updateFiscalData.js
index 4604b3f910..271ed8769e 100644
--- a/modules/supplier/back/methods/supplier/updateFiscalData.js
+++ b/modules/supplier/back/methods/supplier/updateFiscalData.js
@@ -64,6 +64,14 @@ module.exports = Self => {
{
arg: 'healthRegister',
type: 'string'
+ },
+ {
+ arg: 'isVies',
+ type: 'boolean'
+ },
+ {
+ arg: 'isTrucker',
+ type: 'boolean'
}],
returns: {
arg: 'res',
diff --git a/modules/supplier/back/models/supplier.json b/modules/supplier/back/models/supplier.json
index 3cd6386a87..ee2c4fbbd1 100644
--- a/modules/supplier/back/models/supplier.json
+++ b/modules/supplier/back/models/supplier.json
@@ -110,6 +110,9 @@
},
"healthRegister": {
"type": "string"
+ },
+ "isVies": {
+ "type": "boolean"
}
},
"relations": {
@@ -175,4 +178,4 @@
"foreignKey": "supplierActivityFk"
}
}
-}
\ No newline at end of file
+}
diff --git a/modules/supplier/front/fiscal-data/index.html b/modules/supplier/front/fiscal-data/index.html
index a3ede2058d..ccbd5b0d92 100644
--- a/modules/supplier/front/fiscal-data/index.html
+++ b/modules/supplier/front/fiscal-data/index.html
@@ -129,7 +129,7 @@
show-field="code"
rule>
- {{code}} - {{town.name}} ({{town.province.name}},
+ {{code}} - {{town.name}} ({{town.province.name}},
{{town.province.country.country}})
@@ -144,7 +144,7 @@
-
-
-
-
+
+
+
+
+
+
@@ -203,4 +210,4 @@
-
\ No newline at end of file
+
diff --git a/modules/ticket/back/methods/ticket/new.js b/modules/ticket/back/methods/ticket/new.js
index e6048421e3..597ece3e5a 100644
--- a/modules/ticket/back/methods/ticket/new.js
+++ b/modules/ticket/back/methods/ticket/new.js
@@ -111,7 +111,7 @@ module.exports = Self => {
args.landed = landedResult && landedResult.landed;
}
- query = `CALL vn.ticketCreateWithUser(?, ?, ?, ?, ?, ?, ?, ?, ?, @result);
+ query = `CALL vn.ticket_add(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, @result);
SELECT @result newTicketId;`;
const result = await Self.rawSql(query, [
args.clientId,
@@ -122,6 +122,7 @@ module.exports = Self => {
args.agencyModeId || null,
args.routeId || null,
args.landed,
+ true,
myUserId
], myOptions);
diff --git a/modules/ticket/back/methods/ticket/setDeleted.js b/modules/ticket/back/methods/ticket/setDeleted.js
index cec8096a69..6ebc37d6e3 100644
--- a/modules/ticket/back/methods/ticket/setDeleted.js
+++ b/modules/ticket/back/methods/ticket/setDeleted.js
@@ -42,6 +42,14 @@ module.exports = Self => {
if (!isEditable)
throw new UserError(`The sales of this ticket can't be modified`);
+ // Check if ticket has refunds
+ const ticketRefunds = await models.TicketRefund.find({
+ where: {originalTicketFk: id},
+ fields: ['id']}
+ , myOptions);
+ if (ticketRefunds.length > 0)
+ throw new UserError($t('Tickets with associated refunds', {id: ticketRefunds[0].id}));
+
// Check if has sales with shelving
const isSalesAssistant = await models.Account.hasRole(userId, 'salesAssistant', myOptions);
const sales = await models.Sale.find({
@@ -134,12 +142,12 @@ module.exports = Self => {
await models.TicketCollection.destroyById(ticketCollection.id, myOptions);
await Self.rawSql(`
- DELETE sc
+ DELETE sc
FROM vn.saleGroup sg
JOIN vn.sectorCollectionSaleGroup scsg ON scsg.saleGroupFk = sg.id
JOIN vn.sectorCollection sc ON sc.id = scsg.sectorCollectionFk
JOIN vn.saleGroupDetail sgd ON sgd.saleGroupFk = sg.id
- JOIN vn.sale s ON s.id = sgd.saleFk
+ JOIN vn.sale s ON s.id = sgd.saleFk
WHERE s.ticketFk = ?;`, [ticket.id], myOptions);
if (tx) await tx.commit();
diff --git a/modules/ticket/back/methods/ticket/specs/setDeleted.spec.js b/modules/ticket/back/methods/ticket/specs/setDeleted.spec.js
index 1c17d4d0b6..b2e70697ac 100644
--- a/modules/ticket/back/methods/ticket/specs/setDeleted.spec.js
+++ b/modules/ticket/back/methods/ticket/specs/setDeleted.spec.js
@@ -101,4 +101,32 @@ describe('ticket setDeleted()', () => {
throw e;
}
});
+
+ it('should show error trying to delete a ticket with a refund', async() => {
+ const tx = await models.Ticket.beginTransaction({});
+ let error;
+ try {
+ const options = {transaction: tx};
+
+ const ctx = {
+ req: {
+ accessToken: {userId: 9},
+ headers: {origin: 'http://localhost:5000'},
+ }
+ };
+ ctx.req.__ = value => {
+ return value;
+ };
+
+ const ticketId = 12;
+ await models.Ticket.setDeleted(ctx, ticketId, options);
+
+ await tx.rollback();
+ } catch (e) {
+ await tx.rollback();
+ error = e;
+ }
+
+ expect(error.message).toContain('Tickets with associated refunds');
+ });
});
diff --git a/modules/ticket/back/methods/ticket/specs/transferSales.spec.js b/modules/ticket/back/methods/ticket/specs/transferSales.spec.js
index cd2ce85998..270aae2f8e 100644
--- a/modules/ticket/back/methods/ticket/specs/transferSales.spec.js
+++ b/modules/ticket/back/methods/ticket/specs/transferSales.spec.js
@@ -80,34 +80,6 @@ describe('sale transferSales()', () => {
expect(error.message).toEqual(`Can't transfer claimed sales`);
});
- it('should be able to transfer claimed sales if the role is claimManager', async() => {
- const tx = await models.Ticket.beginTransaction({});
-
- let error;
- try {
- const options = {transaction: tx};
-
- const claimManagerId = 72;
- const myActiveCtx = {
- accessToken: {userId: claimManagerId},
- };
- const myCtx = {req: myActiveCtx};
-
- const ticketId = 11;
- const receiverTicketId = null;
- const sales = await models.Ticket.getSales(ticketId, options);
-
- await models.Ticket.transferSales(myCtx, ticketId, receiverTicketId, sales, options);
-
- await tx.rollback();
- } catch (e) {
- await tx.rollback();
- error = e;
- }
-
- expect(error).toBeUndefined();
- });
-
it('should transfer the sales from a ticket to a new one', async() => {
const tx = await models.Ticket.beginTransaction({});
diff --git a/modules/ticket/back/methods/ticket/transferSales.js b/modules/ticket/back/methods/ticket/transferSales.js
index 1b8476184e..57f620f3d2 100644
--- a/modules/ticket/back/methods/ticket/transferSales.js
+++ b/modules/ticket/back/methods/ticket/transferSales.js
@@ -77,9 +77,8 @@ module.exports = Self => {
const saleIds = sales.map(sale => sale.id);
- const isClaimManager = await models.Account.hasRole(userId, 'claimManager');
const hasClaimedSales = await models.ClaimBeginning.findOne({where: {saleFk: {inq: saleIds}}});
- if (hasClaimedSales && !isClaimManager)
+ if (hasClaimedSales)
throw new UserError(`Can't transfer claimed sales`);
for (const sale of sales) {
diff --git a/modules/ticket/front/sale-tracking/index.html b/modules/ticket/front/sale-tracking/index.html
index 8d3f414c2e..33d22f92ea 100644
--- a/modules/ticket/front/sale-tracking/index.html
+++ b/modules/ticket/front/sale-tracking/index.html
@@ -24,12 +24,44 @@
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+