merge
gitea/salix/test This commit looks good
Details
gitea/salix/test This commit looks good
Details
This commit is contained in:
commit
2c6ba0089b
|
@ -1,7 +1,9 @@
|
|||
node_modules
|
||||
dist/*
|
||||
e2e/dms/*/
|
||||
!e2e/dms/temp/
|
||||
!e2e/dms/c4c
|
||||
!e2e/dms/c81
|
||||
!e2e/dms/ecc
|
||||
npm-debug.log
|
||||
.eslintcache
|
||||
datasources.*.json
|
||||
|
|
|
@ -30,11 +30,7 @@ module.exports = Self => {
|
|||
arg: 'description',
|
||||
type: 'String'
|
||||
}, {
|
||||
arg: 'hasFile',
|
||||
type: 'Boolean',
|
||||
description: 'True if has original file'
|
||||
}, {
|
||||
arg: 'hasAttachedFile',
|
||||
arg: 'hasFileAttached',
|
||||
type: 'Boolean',
|
||||
description: 'True if has an attached file'
|
||||
}],
|
||||
|
@ -49,7 +45,7 @@ module.exports = Self => {
|
|||
});
|
||||
|
||||
Self.updateFile = async(ctx, id, warehouseId, companyId,
|
||||
dmsTypeId, reference, description, hasFile, hasAttachedFile, options) => {
|
||||
dmsTypeId, reference, description, hasFileAttached, options) => {
|
||||
const models = Self.app.models;
|
||||
|
||||
let tx;
|
||||
|
@ -74,11 +70,10 @@ module.exports = Self => {
|
|||
companyFk: companyId,
|
||||
warehouseFk: warehouseId,
|
||||
reference: reference,
|
||||
description: description,
|
||||
hasFile: hasFile
|
||||
description: description
|
||||
}, myOptions);
|
||||
|
||||
if (hasAttachedFile)
|
||||
if (hasFileAttached)
|
||||
await uploadNewFile(ctx, dms, myOptions);
|
||||
|
||||
if (tx) await tx.commit();
|
||||
|
|
|
@ -21,6 +21,7 @@ WORKDIR /docker-entrypoint-initdb.d
|
|||
ARG STAMP=unknown
|
||||
|
||||
COPY import-changes.sh config.ini /docker-entrypoint-initdb.d/import/
|
||||
COPY docker.cnf /etc/mysql/mysql.conf.d/
|
||||
COPY changes /docker-entrypoint-initdb.d/import/changes
|
||||
|
||||
COPY docker-boot.sh /docker-entrypoint-initdb.d/
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
UPDATE `salix`.`ACL` SET principalId ='employee' WHERE id = 122;
|
||||
|
||||
INSERT INTO `salix`.`ACL` (`id`, `model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
|
||||
VALUES
|
||||
(167, 'Worker', 'isSubordinate', 'READ', 'ALLOW', 'ROLE', 'employee'),
|
||||
(168, 'Worker', 'mySubordinates', 'READ', 'ALLOW', 'ROLE', 'employee'),
|
||||
(169, 'WorkerTimeControl', 'filter', 'READ', 'ALLOW', 'ROLE', 'employee'),
|
||||
(170, 'WorkerTimeControl', 'addTime', 'WRITE', 'ALLOW', 'ROLE', 'employee'),
|
||||
(171, 'TicketServiceType', '*', 'WRITE', 'ALLOW', 'ROLE', 'administrative');
|
||||
|
||||
-- ONLY FOR ACL ALREADY ON PRODUCTION
|
||||
INSERT IGNORE INTO `salix`.`ACL` (`id`, `model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
|
||||
VALUES
|
||||
(172, 'Sms', '*', 'READ', 'ALLOW', 'ROLE', 'employee'),
|
||||
(173, 'Sms', 'send', 'WRITE', 'ALLOW', 'ROLE', 'employee');
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
ALTER TABLE `vn2008`.`cl_est`
|
||||
ADD COLUMN `roleFk` INT(10) UNSIGNED NOT NULL DEFAULT '1' AFTER `estado`;
|
||||
|
||||
ALTER TABLE `vn2008`.`cl_est`
|
||||
ADD INDEX `roleFgn_idx` (`roleFk` ASC);
|
||||
|
||||
ALTER TABLE `vn2008`.`cl_est`
|
||||
ADD CONSTRAINT `roleFgn`
|
||||
FOREIGN KEY (`roleFk`)
|
||||
REFERENCES `account`.`role` (`id`)
|
||||
ON DELETE RESTRICT
|
||||
ON UPDATE CASCADE;
|
|
@ -1,10 +0,0 @@
|
|||
CREATE
|
||||
ALGORITHM = UNDEFINED
|
||||
DEFINER = `root`@`%`
|
||||
SQL SECURITY DEFINER
|
||||
VIEW `vn`.`clientDms` AS
|
||||
SELECT
|
||||
`g`.`Id_Cliente` AS `clientFk`,
|
||||
`g`.`gest_doc_id` AS `dmsFk`
|
||||
FROM
|
||||
`vn2008`.`clientes_gestdoc` `g`
|
|
@ -1,19 +0,0 @@
|
|||
CREATE
|
||||
OR REPLACE ALGORITHM = UNDEFINED
|
||||
DEFINER = `root`@`%`
|
||||
SQL SECURITY DEFINER
|
||||
VIEW `vn`.`dms` AS
|
||||
SELECT
|
||||
`g`.`id` AS `id`,
|
||||
`g`.`gesttip_id` AS `dmsTypeFk`,
|
||||
`g`.`file` AS `file`,
|
||||
`g`.`trabajador_id` AS `workerFk`,
|
||||
`g`.`warehouse_id` AS `warehouseFk`,
|
||||
`g`.`emp_id` AS `companyFk`,
|
||||
`g`.`orden` AS `hardCopyNumber`,
|
||||
`g`.`original` AS `hasFile`,
|
||||
`g`.`sref` AS `reference`,
|
||||
`g`.`brief` AS `description`,
|
||||
`g`.`odbc_date` AS `created`
|
||||
FROM
|
||||
`vn2008`.`gestdoc` `g`
|
|
@ -1 +0,0 @@
|
|||
UPDATE `vn2008`.`mandato_tipo` SET `Nombre`='LCR' WHERE `idmandato_tipo`='3';
|
|
@ -1,4 +0,0 @@
|
|||
|
||||
INSERT INTO `vn`.`sample`(`code`, `description`, `isVisible`, `hasCompany`)
|
||||
VALUES
|
||||
('client-lcr', 'Email de solicitud de datos bancarios LCR', 1, 1);
|
|
@ -1,2 +0,0 @@
|
|||
ALTER TABLE `bi`.`tarifa_componentes`
|
||||
ADD COLUMN `code` VARCHAR(45) NULL DEFAULT NULL AFTER `is_renewable`;
|
|
@ -1,11 +0,0 @@
|
|||
CREATE
|
||||
OR REPLACE ALGORITHM = UNDEFINED
|
||||
DEFINER = `root`@`%`
|
||||
SQL SECURITY DEFINER
|
||||
VIEW `vn`.`claimState` AS
|
||||
SELECT
|
||||
`c`.`id` AS `id`,
|
||||
`c`.`estado` AS `description`,
|
||||
`c`.`roleFk` AS `roleFk`
|
||||
FROM
|
||||
`vn2008`.`cl_est` `c`;
|
|
@ -1,16 +0,0 @@
|
|||
|
||||
CREATE
|
||||
OR REPLACE ALGORITHM = UNDEFINED
|
||||
DEFINER = `root`@`%`
|
||||
SQL SECURITY DEFINER
|
||||
VIEW `vn`.`componentRate` AS
|
||||
SELECT
|
||||
`t`.`Id_Componente` AS `id`,
|
||||
`t`.`Componente` AS `name`,
|
||||
`t`.`tarifa_componentes_series_id` AS `componentTypeRate`,
|
||||
`t`.`tarifa_class` AS `classRate`,
|
||||
`t`.`tax` AS `tax`,
|
||||
`t`.`is_renewable` AS `isRenewable`,
|
||||
`t`.`code` AS `code`
|
||||
FROM
|
||||
`bi`.`tarifa_componentes` `t`;
|
|
@ -1,26 +0,0 @@
|
|||
CREATE OR REPLACE
|
||||
ALGORITHM = UNDEFINED
|
||||
DEFINER = `root`@`%`
|
||||
SQL SECURITY DEFINER
|
||||
VIEW `vn`.`ticket` AS
|
||||
SELECT
|
||||
`t`.`Id_Ticket` AS `id`,
|
||||
`t`.`Id_Cliente` AS `clientFk`,
|
||||
`t`.`warehouse_id` AS `warehouseFk`,
|
||||
`t`.`Fecha` AS `shipped`,
|
||||
`t`.`landing` AS `landed`,
|
||||
`t`.`Alias` AS `nickname`,
|
||||
`t`.`Factura` AS `refFk`,
|
||||
`t`.`Id_Consigna` AS `addressFk`,
|
||||
`t`.`Localizacion` AS `location`,
|
||||
`t`.`Solucion` AS `solution`,
|
||||
`t`.`Id_Ruta` AS `routeFk`,
|
||||
`t`.`empresa_id` AS `companyFk`,
|
||||
`t`.`Id_Agencia` AS `agencyModeFk`,
|
||||
`t`.`Prioridad` AS `priority`,
|
||||
`t`.`Bultos` AS `packages`,
|
||||
`t`.`isDeleted` AS `isDeleted`,
|
||||
`t`.`odbc_date` AS `created`,
|
||||
`t`.`zoneFk` AS `zoneFk`
|
||||
FROM
|
||||
`vn2008`.`Tickets` `t`;
|
|
@ -1,17 +0,0 @@
|
|||
INSERT INTO `salix`.`ACL` ( `model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
|
||||
VALUES
|
||||
('Dms', 'removeFile', 'WRITE', 'ALLOW', 'ROLE', 'employee'),
|
||||
('Dms', 'uploadFile', 'WRITE', 'ALLOW', 'ROLE', 'employee'),
|
||||
('Dms', 'downloadFile', 'READ', 'ALLOW', 'ROLE', 'employee'),
|
||||
('Client', 'uploadFile', 'WRITE', 'ALLOW', 'ROLE', 'employee'),
|
||||
('ClientDms', 'removeFile', 'WRITE', 'ALLOW', 'ROLE', 'employee'),
|
||||
('ClientDms', '*', 'READ', 'ALLOW', 'ROLE', 'employee'),
|
||||
('Ticket', 'uploadFile', 'WRITE', 'ALLOW', 'ROLE', 'employee'),
|
||||
('TicketDms', 'removeFile', 'WRITE', 'ALLOW', 'ROLE', 'employee'),
|
||||
('TicketDms', '*', 'READ', 'ALLOW', 'ROLE', 'employee'),
|
||||
('Route', 'updateVolume', 'WRITE', 'ALLOW', 'ROLE', 'deliveryBoss');
|
||||
|
||||
|
||||
|
||||
INSERT INTO `salix`.`ACL` (`id`, `model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('', 'Agency', 'getLanded', 'READ', 'ALLOW', 'ROLE', 'employee');
|
||||
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('Agency', 'getShipped', 'READ', 'ALLOW', 'ROLE', 'employee');
|
|
@ -1,15 +0,0 @@
|
|||
ALTER TABLE `vn2008`.`clientes_gestdoc`
|
||||
DROP FOREIGN KEY `clientes_gestdoc_ibfk_3`;
|
||||
ALTER TABLE `vn2008`.`clientes_gestdoc`
|
||||
DROP PRIMARY KEY,
|
||||
ADD PRIMARY KEY (`gest_doc_id`);
|
||||
|
||||
ALTER TABLE `vn2008`.`clientes_gestdoc`
|
||||
ADD INDEX `fk_clientes_gestdoc_1_idx` (`Id_Cliente` ASC);
|
||||
|
||||
ALTER TABLE `vn2008`.`clientes_gestdoc`
|
||||
ADD CONSTRAINT `fk_clientes_gestdoc_3`
|
||||
FOREIGN KEY (`Id_Cliente`)
|
||||
REFERENCES `vn2008`.`Clientes` (`id_cliente`)
|
||||
ON DELETE RESTRICT
|
||||
ON UPDATE CASCADE;
|
|
@ -1,28 +0,0 @@
|
|||
DROP TRIGGER IF EXISTS `vn2008`.`expeditionsBeforeInsert`;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` TRIGGER `vn2008`.`expeditionsBeforeInsert`
|
||||
BEFORE INSERT ON `expeditions` FOR EACH ROW
|
||||
-- Edit trigger body code below this line. Do not edit lines above this one
|
||||
BEGIN
|
||||
DECLARE intcounter INT;
|
||||
DECLARE vShipFk INT;
|
||||
|
||||
IF NEW.EsBulto > 0 THEN
|
||||
|
||||
UPDATE Tickets SET Bultos = nz(Bultos) + 1 WHERE Id_Ticket = NEW.ticket_id;
|
||||
SELECT IFNULL(MAX(counter),0) +1 INTO intcounter FROM expeditions e
|
||||
INNER JOIN Tickets t1 ON e.ticket_id = t1.Id_Ticket
|
||||
LEFT JOIN vn.ticketState ts ON ts.ticket = t1.Id_Ticket
|
||||
INNER JOIN Tickets t2 ON t2.Id_Consigna = t1.Id_Consigna AND DATE(t2.Fecha) = DATE(t1.Fecha) AND t1.warehouse_id = t2.warehouse_id
|
||||
WHERE t2.Id_Ticket = NEW.ticket_id AND ts.alertLevel < 3 AND t1.empresa_id = t2.empresa_id AND t1.Id_Agencia = t2.Id_Agencia;
|
||||
SET NEW.`counter` = intcounter;
|
||||
END IF;
|
||||
|
||||
-- JGF 14/01/19 si existe un polizon queda anulado
|
||||
SELECT shipFk INTO vShipFk FROM vn.stowaway WHERE id = NEW.ticket_id;
|
||||
IF vShipFk THEN
|
||||
CALL vn.stowawayUnBoarding(vShipFk, NEW.ticket_id);
|
||||
END IF;
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -1,21 +0,0 @@
|
|||
-- adds column to table
|
||||
ALTER TABLE `vn2008`.`gesttip`
|
||||
ADD COLUMN `code` VARCHAR(45) NOT NULL AFTER `readRoleFk`;
|
||||
|
||||
-- adds column to view
|
||||
CREATE
|
||||
OR REPLACE ALGORITHM = UNDEFINED
|
||||
DEFINER = `root`@`%`
|
||||
SQL SECURITY DEFINER
|
||||
VIEW `vn`.`dmsType` AS
|
||||
SELECT
|
||||
`g`.`id` AS `id`,
|
||||
`g`.`tipo` AS `name`,
|
||||
`g`.`path` AS `path`,
|
||||
`g`.`readRoleFk` AS `readRoleFk`,
|
||||
`g`.`writeRoleFk` AS `writeRoleFk`,
|
||||
`g`.`code` AS `code`
|
||||
FROM
|
||||
`vn2008`.`gesttip` `g`;
|
||||
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
|
||||
DROP procedure IF EXISTS `vn`.`routeUpdateM3`;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`routeUpdateM3`(vRoute INT)
|
||||
BEGIN
|
||||
|
||||
UPDATE vn.route r
|
||||
JOIN (SELECT routeFk, SUM(volume) AS m3
|
||||
FROM ticketGetVolume
|
||||
WHERE routeFk = vRoute
|
||||
) v ON v.routeFk = r.id
|
||||
SET r.m3 = v.m3;
|
||||
END$$
|
||||
|
||||
DELIMITER ;
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
UPDATE `bi`.`tarifa_componentes` SET `code`='specialPrices' WHERE `Id_Componente`='10';
|
||||
UPDATE `bi`.`tarifa_componentes` SET `code`='extraCostPerWeekDay' WHERE `Id_Componente`='14';
|
||||
UPDATE `bi`.`tarifa_componentes` SET `code`='delivery' WHERE `Id_Componente`='15';
|
||||
UPDATE `bi`.`tarifa_componentes` SET `code`='debtCollection' WHERE `Id_Componente`='17';
|
||||
UPDATE `bi`.`tarifa_componentes` SET `code`='adjustment' WHERE `Id_Componente`='21';
|
||||
UPDATE `bi`.`tarifa_componentes` SET `code`='salePerPackage' WHERE `Id_Componente`='22';
|
||||
UPDATE `bi`.`tarifa_componentes` SET `code`='salePerBox' WHERE `Id_Componente`='23';
|
||||
UPDATE `bi`.`tarifa_componentes` SET `code`='purchaseValue' WHERE `Id_Componente`='28';
|
||||
UPDATE `bi`.`tarifa_componentes` SET `code`='margin' WHERE `Id_Componente`='29';
|
||||
UPDATE `bi`.`tarifa_componentes` SET `code`='lastUnitsDiscount' WHERE `Id_Componente`='32';
|
||||
UPDATE `bi`.`tarifa_componentes` SET `code`='salePerBox' WHERE `Id_Componente`='33';
|
||||
UPDATE `bi`.`tarifa_componentes` SET `code`='buyerDiscount' WHERE `Id_Componente`='34';
|
||||
UPDATE `bi`.`tarifa_componentes` SET `code`='mismatch' WHERE `Id_Componente`='36';
|
||||
UPDATE `bi`.`tarifa_componentes` SET `code`='mana' WHERE `Id_Componente`='37';
|
||||
UPDATE `bi`.`tarifa_componentes` SET `code`='bagged' WHERE `Id_Componente`='38';
|
||||
UPDATE `bi`.`tarifa_componentes` SET `code`='autoMana' WHERE `Id_Componente`='39';
|
||||
UPDATE `bi`.`tarifa_componentes` SET `code`='freightCharge' WHERE `Id_Componente`='41';
|
|
@ -1,49 +0,0 @@
|
|||
|
||||
DROP procedure IF EXISTS `vn`.`zoneGetWarehouse`;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`zoneGetWarehouse`(vAddress INT, vLanded DATE, vWarehouse INT)
|
||||
BEGIN
|
||||
/**
|
||||
* Devuelve el listado de agencias disponibles para la fecha,
|
||||
* dirección y warehouse pasadas
|
||||
*
|
||||
* @param vAddress
|
||||
* @param vWarehouse warehouse
|
||||
* @param vLanded Fecha de recogida
|
||||
* @select Listado de agencias disponibles
|
||||
*/
|
||||
|
||||
DECLARE vPostalCode varchar(10);
|
||||
|
||||
SELECT postalCode INTO vPostalCode
|
||||
FROM address WHERE id = vAddress;
|
||||
SELECT * FROM (
|
||||
SELECT * FROM (
|
||||
SELECT am.id agencyModeFk,
|
||||
am.name agencyMode,
|
||||
am.description,
|
||||
am.deliveryMethodFk,
|
||||
TIMESTAMPADD(DAY,-z.travelingDays, vLanded) shipped,
|
||||
z.warehouseFk,
|
||||
zi.isIncluded,
|
||||
z.id zoneFk
|
||||
FROM zoneGeo zgSon
|
||||
JOIN zoneGeo zgFather ON zgSon.lft BETWEEN zgFather.lft AND zgFather.rgt
|
||||
JOIN zoneIncluded zi ON zi.geoFk = zgFather.id
|
||||
JOIN zone z ON z.id = zi.zoneFk
|
||||
JOIN zoneCalendar zc ON zc.zoneFk = z.id
|
||||
JOIN agencyMode am ON am.id = z.agencyModeFk
|
||||
WHERE zgSon.`name` LIKE vPostalCode
|
||||
AND delivered = vLanded
|
||||
AND z.warehouseFk = vWarehouse
|
||||
AND IF(TIMESTAMPADD(DAY,-z.travelingDays, vLanded) = CURDATE(), hour(now()) < hour(z.`hour`),TRUE)
|
||||
ORDER BY z.id, zgFather.depth DESC) t
|
||||
GROUP BY zoneFk
|
||||
HAVING isIncluded > 0) t
|
||||
GROUP BY agencyModeFk;
|
||||
|
||||
END$$
|
||||
|
||||
DELIMITER ;
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
UPDATE `vn2008`.`gesttip` SET `writeRoleFk`='1', `readRoleFk`='1' WHERE `id`='5';
|
||||
UPDATE `vn2008`.`gesttip` SET `writeRoleFk`='1', `readRoleFk`='1' WHERE `id`='12';
|
||||
UPDATE `vn2008`.`gesttip` SET `writeRoleFk`='1', `readRoleFk`='1' WHERE `id`='14';
|
||||
UPDATE `vn2008`.`gesttip` SET `writeRoleFk`='1', `readRoleFk`='1' WHERE `id`='13';
|
||||
UPDATE `vn2008`.`gesttip` SET `code`='invoiceIn' WHERE `id`='1';
|
||||
UPDATE `vn2008`.`gesttip` SET `code`='officialDoc' WHERE `id`='2';
|
||||
UPDATE `vn2008`.`gesttip` SET `code`='hhrrData' WHERE `id`='3';
|
||||
UPDATE `vn2008`.`gesttip` SET `code`='deliveryNote' WHERE `id`='4';
|
||||
UPDATE `vn2008`.`gesttip` SET `code`='miscellaneous' WHERE `id`='5';
|
||||
UPDATE `vn2008`.`gesttip` SET `code`='tests' WHERE `id`='6';
|
||||
UPDATE `vn2008`.`gesttip` SET `code`='economicActivitiesTax' WHERE `id`='7';
|
||||
UPDATE `vn2008`.`gesttip` SET `code`='fiscal' WHERE `id`='8';
|
||||
UPDATE `vn2008`.`gesttip` SET `code`='vehicles' WHERE `id`='9';
|
||||
UPDATE `vn2008`.`gesttip` SET `code`='templates' WHERE `id`='10';
|
||||
UPDATE `vn2008`.`gesttip` SET `code`='contracts' WHERE `id`='11';
|
||||
UPDATE `vn2008`.`gesttip` SET `code`='paymentsLaw' WHERE `id`='12';
|
||||
UPDATE `vn2008`.`gesttip` SET `code`='trash' WHERE `id`='13';
|
||||
UPDATE `vn2008`.`gesttip` SET `code`='ticket' WHERE `id`='14';
|
||||
UPDATE `vn2008`.`gesttip` SET `code`='budgets' WHERE `id`='15';
|
||||
UPDATE `vn2008`.`gesttip` SET `code`='logistics' WHERE `id`='16';
|
||||
UPDATE `vn2008`.`gesttip` SET `code`='cmr' WHERE `id`='17';
|
||||
UPDATE `vn2008`.`gesttip` SET `code`='dua' WHERE `id`='18';
|
||||
UPDATE `vn2008`.`gesttip` SET `code`='fixedAssets' WHERE `id`='19';
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
ALTER TABLE `vn2008`.`Paises`
|
||||
ADD COLUMN `ibanLength` TINYINT(4) NULL DEFAULT NULL AFTER `isUeeMember`;
|
||||
|
||||
CREATE
|
||||
OR REPLACE ALGORITHM = UNDEFINED
|
||||
DEFINER = `root`@`%`
|
||||
SQL SECURITY DEFINER
|
||||
VIEW `vn`.`country` AS
|
||||
SELECT
|
||||
`p`.`Id` AS `id`,
|
||||
`p`.`Pais` AS `country`,
|
||||
`p`.`CEE` AS `CEE`,
|
||||
`p`.`isUeeMember` AS `isUeeMember`,
|
||||
`p`.`Codigo` AS `code`,
|
||||
`p`.`Id_Moneda` AS `currencyFk`,
|
||||
`p`.`Id_Paisreal` AS `politicalCountryFk`,
|
||||
`p`.`geoFk` AS `geoFk`,
|
||||
`p`.`ibanLength` AS `ibanLength`
|
||||
FROM
|
||||
`vn2008`.`Paises` `p`;
|
||||
|
||||
UPDATE `vn2008`.`Paises` SET `ibanLength`=22 WHERE `Id`=1;
|
||||
UPDATE `vn2008`.`Paises` SET `ibanLength`=25 WHERE `Id`=2;
|
||||
UPDATE `vn2008`.`Paises` SET `ibanLength`=20 WHERE `Id`=3;
|
||||
UPDATE `vn2008`.`Paises` SET `ibanLength`=22 WHERE `Id`=4;
|
||||
UPDATE `vn2008`.`Paises` SET `ibanLength`=16 WHERE `Id`=5;
|
||||
UPDATE `vn2008`.`Paises` SET `ibanLength`=25 WHERE `Id`=19;
|
||||
UPDATE `vn2008`.`Paises` SET `ibanLength`=22 WHERE `Id`=30;
|
|
@ -1,5 +0,0 @@
|
|||
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
|
||||
VALUES
|
||||
('Zone', 'editPrices', 'WRITE', 'ALLOW', 'ROLE', 'deliveryBoss'),
|
||||
('Postcode', '*', 'WRITE', 'ALLOW', 'ROLE', 'employee'),
|
||||
('Ticket', 'addSale', 'WRITE', 'ALLOW', 'ROLE', 'employee');
|
|
@ -1,3 +0,0 @@
|
|||
ALTER TABLE `vn`.`zoneCalendar`
|
||||
ADD COLUMN `price` DOUBLE NOT NULL AFTER `delivered`,
|
||||
ADD COLUMN `bonus` DOUBLE NOT NULL AFTER `price`;
|
|
@ -1,139 +0,0 @@
|
|||
DROP procedure IF EXISTS `vn`.`ticketGetProblems`;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`ticketGetProblems`()
|
||||
BEGIN
|
||||
|
||||
DECLARE vWarehouse INT;
|
||||
DECLARE vDate DATE;
|
||||
DECLARE vAvailableCache INT;
|
||||
DECLARE vVisibleCache INT;
|
||||
DECLARE vDone INT DEFAULT 0;
|
||||
|
||||
DECLARE vCursor CURSOR FOR
|
||||
SELECT DISTINCT tt.warehouseFk, date(tt.shipped)
|
||||
FROM tmp.ticketGetProblems tt
|
||||
WHERE DATE(tt.shipped) BETWEEN CURDATE()
|
||||
AND TIMESTAMPADD(DAY, 1.9, CURDATE());
|
||||
|
||||
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = 1;
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp.ticketProblems;
|
||||
CREATE TEMPORARY TABLE tmp.ticketProblems (
|
||||
ticketFk INT(11) PRIMARY KEY,
|
||||
isFreezed INTEGER(1) DEFAULT 0,
|
||||
risk DECIMAL(10,2) DEFAULT 0,
|
||||
hasTicketRequest INTEGER(1) DEFAULT 0,
|
||||
isAvailable INTEGER(1) DEFAULT 1
|
||||
) ENGINE = MEMORY;
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp.ticketList;
|
||||
CREATE TEMPORARY TABLE tmp.ticketList
|
||||
(PRIMARY KEY (ticketFk))
|
||||
ENGINE = MEMORY
|
||||
SELECT tp.ticketFk, c.id clientFk
|
||||
FROM tmp.ticketGetProblems tp
|
||||
JOIN vn.client c ON c.id = tp.clientFk;
|
||||
|
||||
|
||||
INSERT INTO tmp.ticketProblems(ticketFk, isFreezed)
|
||||
SELECT DISTINCT tl.ticketFk, 1
|
||||
FROM tmp.ticketList tl
|
||||
JOIN vn.client c ON c.id = tl.clientFk
|
||||
WHERE c.isFreezed;
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp.clientGetDebt;
|
||||
CREATE TEMPORARY TABLE tmp.clientGetDebt
|
||||
(PRIMARY KEY (clientFk))
|
||||
ENGINE = MEMORY
|
||||
SELECT DISTINCT clientFk
|
||||
FROM tmp.ticketList;
|
||||
|
||||
CALL clientGetDebt(CURDATE());
|
||||
|
||||
|
||||
INSERT INTO tmp.ticketProblems(ticketFk, risk)
|
||||
SELECT DISTINCT tl.ticketFk, r.risk
|
||||
FROM tmp.ticketList tl
|
||||
JOIN vn.ticket t ON t.id = tl.ticketFk
|
||||
JOIN vn.agencyMode a ON t.agencyModeFk = a.id
|
||||
JOIN tmp.risk r ON r.clientFk = t.clientFk
|
||||
JOIN vn.client c ON c.id = t.clientFk
|
||||
WHERE r.risk > c.credit + 10
|
||||
AND a.deliveryMethodFk != 3
|
||||
ON DUPLICATE KEY UPDATE
|
||||
risk = r.risk;
|
||||
|
||||
INSERT INTO tmp.ticketProblems(ticketFk, hasTicketRequest)
|
||||
SELECT DISTINCT tl.ticketFk, 1
|
||||
FROM tmp.ticketList tl
|
||||
JOIN vn.ticketRequest tr ON tr.ticketFk = tl.ticketFk
|
||||
WHERE tr.isOK IS NULL
|
||||
ON DUPLICATE KEY UPDATE
|
||||
hasTicketRequest = 1;
|
||||
|
||||
OPEN vCursor;
|
||||
|
||||
WHILE NOT vDone
|
||||
DO
|
||||
FETCH vCursor INTO vWarehouse, vDate;
|
||||
|
||||
CALL cache.visible_refresh(vVisibleCache, FALSE, vWarehouse);
|
||||
CALL cache.available_refresh(vAvailableCache, FALSE, vWarehouse, vDate);
|
||||
|
||||
|
||||
INSERT INTO tmp.ticketProblems(ticketFk, isAvailable)
|
||||
SELECT tl.ticketFk, 0
|
||||
FROM tmp.ticketList tl
|
||||
JOIN vn.ticket t ON t.id = tl.ticketFk
|
||||
LEFT JOIN vn.sale s ON s.ticketFk = t.id
|
||||
JOIN vn.item i ON i.id = s.itemFk
|
||||
JOIN vn.itemType it on it.id = i.typeFk
|
||||
LEFT JOIN cache.available av ON av.item_id = i.id
|
||||
AND av.calc_id = vAvailableCache
|
||||
WHERE date(t.shipped) = vDate
|
||||
AND categoryFk != 6
|
||||
AND IFNULL(av.available, 0) < 0
|
||||
AND s.isPicked = FALSE
|
||||
AND NOT i.generic
|
||||
AND vWarehouse = t.warehouseFk
|
||||
GROUP BY tl.ticketFk
|
||||
ON DUPLICATE KEY UPDATE
|
||||
isAvailable = 0;
|
||||
|
||||
INSERT INTO tmp.ticketProblems(ticketFk, isAvailable)
|
||||
SELECT tl.ticketFk, 0
|
||||
FROM tmp.ticketList tl
|
||||
JOIN vn.ticket t ON t.id = tl.ticketFk
|
||||
LEFT JOIN vn.sale s ON s.ticketFk = t.id
|
||||
JOIN vn.item i ON i.id = s.itemFk
|
||||
JOIN vn.itemType it on it.id = i.typeFk
|
||||
LEFT JOIN cache.visible v ON i.id = v.item_id AND v.calc_id = vVisibleCache
|
||||
LEFT JOIN cache.available av ON av.item_id = i.id AND av.calc_id = vAvailableCache
|
||||
WHERE IFNULL(av.available, 0) >= 0
|
||||
AND s.quantity > IFNULL(v.visible, 0)
|
||||
AND s.isPicked = FALSE
|
||||
AND s.reserved = FALSE
|
||||
AND it.categoryFk != 6
|
||||
AND date(t.shipped) = vDate
|
||||
AND NOT i.generic
|
||||
AND CURDATE() = vDate
|
||||
AND t.warehouseFk = vWarehouse
|
||||
GROUP BY tl.ticketFk
|
||||
ON DUPLICATE KEY UPDATE
|
||||
isAvailable = 0;
|
||||
|
||||
END WHILE;
|
||||
|
||||
CLOSE vCursor;
|
||||
|
||||
SELECT * FROM tmp.ticketProblems;
|
||||
|
||||
DROP TEMPORARY TABLE
|
||||
tmp.clientGetDebt,
|
||||
tmp.ticketList;
|
||||
|
||||
END$$
|
||||
|
||||
DELIMITER ;
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
CREATE
|
||||
OR REPLACE ALGORITHM = UNDEFINED
|
||||
DEFINER = `root`@`%`
|
||||
SQL SECURITY DEFINER
|
||||
VIEW `vn`.`invoiceOut` AS
|
||||
SELECT
|
||||
`f`.`factura_id` AS `id`,
|
||||
`f`.`Id_Factura` AS `ref`,
|
||||
`f`.`Serie` AS `serial`,
|
||||
`f`.`Fecha` AS `issued`,
|
||||
`f`.`Importe` AS `amount`,
|
||||
`f`.`Id_Cliente` AS `clientFk`,
|
||||
`f`.`odbc_date` AS `created`,
|
||||
`f`.`empresa_id` AS `companyFk`,
|
||||
`f`.`Vencimiento` AS `dued`,
|
||||
`f`.`booked` AS `booked`,
|
||||
`f`.`Id_Banco` AS `bankFk`,
|
||||
`f`.`cplusInvoiceType477Fk` AS `cplusInvoiceType477Fk`,
|
||||
`f`.`cplusTaxBreakFk` AS `cplusTaxBreakFk`,
|
||||
`f`.`cplusSubjectOpFk` AS `cplusSubjectOpFk`,
|
||||
`f`.`cplusTrascendency477Fk` AS `cplusTrascendency477Fk`,
|
||||
`f`.`pdf` AS `hasPdf`
|
||||
FROM
|
||||
`vn2008`.`Facturas` `f`;
|
|
@ -0,0 +1,60 @@
|
|||
DROP procedure IF EXISTS `vn`.`invoiceOutAgain`;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`invoiceOutAgain`(IN vInvoiceRef VARCHAR(15), vTaxArea VARCHAR(25))
|
||||
BEGIN
|
||||
|
||||
/* Para tickets ya facturados, vuelve a repetir el proceso de facturación.
|
||||
*
|
||||
* @param vInvoiceFk Numero de factura
|
||||
* @param vTaxArea Numero de factura
|
||||
*/
|
||||
|
||||
DECLARE vInvoiceFk INT;
|
||||
DECLARE vCountry INT;
|
||||
DECLARE vTaxArea VARCHAR(15);
|
||||
DECLARE vSpainCountryCode INT DEFAULT 1;
|
||||
|
||||
SELECT id INTO vInvoiceFk
|
||||
FROM invoiceOut
|
||||
WHERE ref = vInvoiceRef;
|
||||
|
||||
UPDATE invoiceOut
|
||||
SET hasPdf = 0
|
||||
WHERE id = vInvoiceFk;
|
||||
|
||||
SELECT s.countryFk INTO vCountry
|
||||
FROM supplier s
|
||||
JOIN invoiceOut io ON io.companyFk = s.id
|
||||
WHERE io.id = vInvoiceFk;
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS ticketToInvoice;
|
||||
|
||||
CREATE TEMPORARY TABLE ticketToInvoice
|
||||
SELECT id
|
||||
FROM ticket
|
||||
WHERE refFk = vInvoiceRef;
|
||||
|
||||
CALL invoiceExpenceMake(vInvoiceFk);
|
||||
|
||||
CALL invoiceTaxMake(vInvoiceFk,vTaxArea);
|
||||
|
||||
UPDATE invoiceOut io
|
||||
JOIN (
|
||||
SELECT SUM(amount) AS total
|
||||
FROM invoiceOutExpence
|
||||
WHERE invoiceOutFk = vInvoiceFk
|
||||
) base
|
||||
JOIN (
|
||||
SELECT SUM(vat) AS total
|
||||
FROM invoiceOutTax
|
||||
WHERE invoiceOutFk = vInvoiceFk
|
||||
) vat
|
||||
SET io.amount = base.total + vat.total
|
||||
WHERE io.id = vInvoiceFk;
|
||||
|
||||
CALL vn.invoiceOutBooking(vInvoiceFk);
|
||||
|
||||
END$$
|
||||
|
||||
DELIMITER ;
|
|
@ -0,0 +1,38 @@
|
|||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`ticket_componentMakeUpdate`(
|
||||
vTicketFk INT,
|
||||
vClientFk INT,
|
||||
vAgencyModeFk INT,
|
||||
vAddressFk INT,
|
||||
vZoneFk INT,
|
||||
vWarehouseFk TINYINT,
|
||||
vCompanyFk SMALLINT,
|
||||
vShipped DATETIME,
|
||||
vLanded DATE,
|
||||
vIsDeleted BOOLEAN,
|
||||
vHasToBeUnrouted BOOLEAN,
|
||||
vOption INT)
|
||||
BEGIN
|
||||
|
||||
CALL vn.ticket_componentPreview (vTicketFk, vLanded, vAddressFk, vZoneFk, vWarehouseFk);
|
||||
CALL vn.ticket_componentUpdate (
|
||||
vTicketFk,
|
||||
vClientFk,
|
||||
vAgencyModeFk,
|
||||
vAddressFk,
|
||||
vZoneFk,
|
||||
vWarehouseFk,
|
||||
vCompanyFk,
|
||||
vShipped,
|
||||
vLanded,
|
||||
vIsDeleted,
|
||||
vHasToBeUnrouted,
|
||||
vOption
|
||||
);
|
||||
|
||||
DROP TEMPORARY TABLE
|
||||
tmp.ticketComponent,
|
||||
tmp.ticketComponentPrice;
|
||||
END$$
|
||||
|
||||
DELIMITER ;
|
|
@ -0,0 +1,111 @@
|
|||
USE `vn`;
|
||||
DROP procedure IF EXISTS `ticket_componentPreview`;
|
||||
|
||||
DELIMITER $$
|
||||
USE `vn`$$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `ticket_componentPreview`(
|
||||
vTicketFk INT,
|
||||
vLanded DATE,
|
||||
vAddressFk INT,
|
||||
vZoneFk INT,
|
||||
vWarehouseFk SMALLINT)
|
||||
BEGIN
|
||||
/**
|
||||
* Calcula los componentes de los articulos de un ticket
|
||||
*
|
||||
* @param vTicketFk id del ticket
|
||||
* @param vLanded nueva fecha de entrega
|
||||
* @param vAddressFk nuevo consignatario
|
||||
* @param vZoneFk nueva zona
|
||||
* @param vWarehouseFk nuevo warehouse
|
||||
*
|
||||
* @return tmp.ticketComponent (warehouseFk, itemFk, componentFk, cost)
|
||||
*/
|
||||
DECLARE vShipped DATE;
|
||||
DECLARE vBuyOrderItem INT DEFAULT 100;
|
||||
|
||||
DECLARE vHasDataChanged BOOL DEFAULT FALSE;
|
||||
DECLARE vHasAddressChanged BOOL;
|
||||
DECLARE vHasZoneChanged BOOL DEFAULT FALSE;
|
||||
DECLARE vHasWarehouseChanged BOOL DEFAULT FALSE;
|
||||
|
||||
DECLARE vAddressTypeRateFk INT DEFAULT NULL;
|
||||
DECLARE vAgencyModeTypeRateFk INT DEFAULT NULL;
|
||||
|
||||
DECLARE vHasChangeAll BOOL DEFAULT FALSE;
|
||||
|
||||
SELECT DATE(landed) <> vLanded,
|
||||
addressFk <> vAddressFk,
|
||||
zoneFk <> vZoneFk,
|
||||
warehouseFk <> vWarehouseFk
|
||||
INTO
|
||||
vHasDataChanged,
|
||||
vHasAddressChanged,
|
||||
vHasZoneChanged,
|
||||
vHasWarehouseChanged
|
||||
FROM vn.ticket t
|
||||
WHERE t.id = vTicketFk;
|
||||
|
||||
IF vHasDataChanged OR vHasWarehouseChanged THEN
|
||||
SET vHasChangeAll = TRUE;
|
||||
END IF;
|
||||
|
||||
IF vHasAddressChanged THEN
|
||||
SET vAddressTypeRateFk = 5;
|
||||
END IF;
|
||||
|
||||
IF vHasZoneChanged THEN
|
||||
SET vAgencyModeTypeRateFk = 6;
|
||||
END IF;
|
||||
|
||||
SELECT TIMESTAMPADD(DAY, -travelingDays, vLanded) INTO vShipped
|
||||
FROM zone
|
||||
WHERE id = vZoneFk;
|
||||
|
||||
CALL buyUltimate(vWarehouseFk, vShipped);
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp.ticketLot;
|
||||
CREATE TEMPORARY TABLE tmp.ticketLot ENGINE = MEMORY (
|
||||
SELECT
|
||||
vWarehouseFk AS warehouseFk,
|
||||
NULL AS available,
|
||||
s.itemFk,
|
||||
bu.buyFk
|
||||
FROM sale s
|
||||
LEFT JOIN tmp.buyUltimate bu ON bu.itemFk = s.itemFk
|
||||
WHERE s.ticketFk = vTicketFk
|
||||
AND s.itemFk != vBuyOrderItem
|
||||
GROUP BY bu.warehouseFk, bu.itemFk);
|
||||
|
||||
CALL catalog_componentCalculate(vZoneFk, vAddressFk, vShipped);
|
||||
|
||||
REPLACE INTO tmp.ticketComponent (warehouseFk, itemFk, componentFk, cost)
|
||||
SELECT t.warehouseFk, s.itemFk, sc.componentFk, sc.value
|
||||
FROM saleComponent sc
|
||||
JOIN sale s ON s.id = sc.saleFk
|
||||
JOIN ticket t ON t.id = s.ticketFk
|
||||
JOIN componentRate cr ON cr.id = sc.componentFk
|
||||
WHERE s.ticketFk = vTicketFk
|
||||
AND (cr.isRenewable = FALSE
|
||||
OR
|
||||
(NOT vHasChangeAll
|
||||
AND (NOT (cr.componentTypeRate <=> vAddressTypeRateFk
|
||||
OR cr.componentTypeRate <=> vAgencyModeTypeRateFk))));
|
||||
|
||||
SET @shipped = vShipped;
|
||||
|
||||
DROP TEMPORARY TABLE
|
||||
tmp.buyUltimate,
|
||||
tmp.ticketLot;
|
||||
|
||||
IF vShipped IS NULL THEN
|
||||
CALL util.throw('NO_ZONE_AVAILABLE');
|
||||
END IF;
|
||||
|
||||
IF vShipped < CURDATE() THEN
|
||||
CALL util.throw('ERROR_PAST_SHIPMENT');
|
||||
END IF;
|
||||
END$$
|
||||
|
||||
DELIMITER ;
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
DROP procedure IF EXISTS `vn`.`ticket_priceDifference`;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`ticket_priceDifference`(
|
||||
vTicketFk INT,
|
||||
vLanded DATE,
|
||||
vAddressFk INT,
|
||||
vZoneFk INT,
|
||||
vWarehouseFk INT)
|
||||
BEGIN
|
||||
/**
|
||||
* Devuelve las diferencias de precio
|
||||
* de los movimientos de un ticket.
|
||||
*
|
||||
* @param vTicketFk Id del ticket
|
||||
* @param vLanded Fecha de recepcion
|
||||
* @param vAddressFk Id del consignatario
|
||||
* @param vZoneFk Id de la zona
|
||||
* @param vWarehouseFk Id del almacén
|
||||
*/
|
||||
CALL vn.ticket_componentPreview(vTicketFk, vLanded, vAddressFk, vZoneFk, vWarehouseFk);
|
||||
|
||||
SELECT s.itemFk,
|
||||
i.name,
|
||||
i.size,
|
||||
i.category,
|
||||
IFNULL(s.quantity, 0) AS quantity,
|
||||
IFNULL(s.price, 0) AS price,
|
||||
ROUND(SUM(tc.cost), 2) AS newPrice,
|
||||
s.quantity * (s.price - ROUND(SUM(tc.cost), 2)) difference,
|
||||
s.id AS saleFk
|
||||
FROM sale s
|
||||
JOIN item i ON i.id = s.itemFk
|
||||
JOIN ticket t ON t.id = s.ticketFk
|
||||
LEFT JOIN tmp.ticketComponent tc ON tc.itemFk = s.itemFk
|
||||
AND tc.warehouseFk = t.warehouseFk
|
||||
LEFT JOIN saleComponent sc ON sc.saleFk = s.id
|
||||
AND sc.componentFk = tc.componentFk
|
||||
LEFT JOIN componentRate cr ON cr.id = tc.componentFk
|
||||
WHERE
|
||||
t.id = vTicketFk
|
||||
AND IF(sc.componentFk IS NULL
|
||||
AND cr.classRate IS NOT NULL, FALSE, TRUE)
|
||||
GROUP BY s.id ORDER BY s.id;
|
||||
|
||||
DROP TEMPORARY TABLE
|
||||
tmp.ticketComponent,
|
||||
tmp.ticketComponentPrice;
|
||||
END$$
|
||||
|
||||
DELIMITER ;
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
DROP procedure IF EXISTS `cache`.`available_refresh`;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `cache`.`available_refresh`(OUT `vCalc` INT, IN `vRefresh` INT, IN `vWarehouse` INT, IN `vDate` DATE)
|
||||
proc: BEGIN
|
||||
DECLARE vStartDate DATE;
|
||||
DECLARE vEndDate DATETIME;
|
||||
DECLARE vReserveDate DATETIME;
|
||||
DECLARE vParams CHAR(100);
|
||||
DECLARE vInventoryDate DATE;
|
||||
|
||||
DECLARE EXIT HANDLER FOR SQLEXCEPTION
|
||||
BEGIN
|
||||
CALL cache_calc_unlock (vCalc);
|
||||
RESIGNAL;
|
||||
END;
|
||||
|
||||
IF vDate < CURDATE() THEN
|
||||
LEAVE proc;
|
||||
END IF;
|
||||
|
||||
CALL vn2008.item_stock (vWarehouse, vDate, NULL);
|
||||
|
||||
SET vParams = CONCAT_WS('/', vWarehouse, vDate);
|
||||
CALL cache_calc_start (vCalc, vRefresh, 'available', vParams);
|
||||
|
||||
IF !vRefresh THEN
|
||||
LEAVE proc;
|
||||
END IF;
|
||||
|
||||
-- Calcula algunos parámetros necesarios
|
||||
|
||||
SET vStartDate = TIMESTAMP(vDate, '00:00:00');
|
||||
SET vEndDate = TIMESTAMP(TIMESTAMPADD(DAY, 4, vDate), '23:59:59');
|
||||
|
||||
SELECT FechaInventario INTO vInventoryDate FROM vn2008.tblContadores;
|
||||
|
||||
SELECT SUBTIME(NOW(), reserveTime) INTO vReserveDate
|
||||
FROM hedera.orderConfig;
|
||||
|
||||
-- Calcula el ultimo dia de vida para cada producto
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS item_range;
|
||||
CREATE TEMPORARY TABLE item_range
|
||||
(PRIMARY KEY (item_id))
|
||||
ENGINE = MEMORY
|
||||
SELECT c.item_id, IF(t.life IS NULL, NULL,
|
||||
TIMESTAMP(TIMESTAMPADD(DAY, t.life, c.landing), '23:59:59')) AS date_end
|
||||
FROM (
|
||||
SELECT c.Id_Article item_id, MAX(landing) landing
|
||||
FROM vn2008.Compres c
|
||||
JOIN vn2008.Entradas e ON c.Id_Entrada = e.Id_Entrada
|
||||
JOIN vn2008.travel t ON t.id = e.travel_id
|
||||
JOIN vn2008.warehouse w ON w.id = t.warehouse_id
|
||||
WHERE t.landing BETWEEN vInventoryDate AND vStartDate
|
||||
AND t.warehouse_id = vWarehouse
|
||||
AND NOT e.Inventario
|
||||
AND NOT e.Redada
|
||||
GROUP BY Id_Article
|
||||
) c
|
||||
JOIN vn2008.Articles a ON a.Id_Article = c.item_id
|
||||
JOIN vn2008.Tipos t ON t.tipo_id = a.tipo_id
|
||||
HAVING date_end >= vStartDate OR date_end IS NULL;
|
||||
|
||||
-- Replica la tabla item_range para poder usarla varias veces en la misma consulta
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS item_range_copy1;
|
||||
CREATE TEMPORARY TABLE item_range_copy1 LIKE item_range;
|
||||
INSERT INTO item_range_copy1
|
||||
SELECT * FROM item_range;
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS item_range_copy2;
|
||||
CREATE TEMPORARY TABLE item_range_copy2 LIKE item_range;
|
||||
INSERT INTO item_range_copy2
|
||||
SELECT * FROM item_range;
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS item_range_copy3;
|
||||
CREATE TEMPORARY TABLE item_range_copy3 LIKE item_range;
|
||||
INSERT INTO item_range_copy3
|
||||
SELECT * FROM item_range;
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS item_range_copy4;
|
||||
CREATE TEMPORARY TABLE item_range_copy4 LIKE item_range;
|
||||
INSERT INTO item_range_copy4
|
||||
SELECT * FROM item_range;
|
||||
|
||||
-- Calcula el ATP
|
||||
|
||||
DELETE FROM available WHERE calc_id = vCalc;
|
||||
|
||||
INSERT INTO available (calc_id, item_id, available)
|
||||
SELECT vCalc, t.item_id, SUM(stock) amount FROM (
|
||||
SELECT ti.item_id, stock
|
||||
FROM vn2008.tmp_item ti
|
||||
JOIN item_range ir ON ir.item_id = ti.item_id
|
||||
UNION ALL
|
||||
SELECT t.item_id, minacum(dt, amount, vDate) AS available FROM (
|
||||
SELECT item_id, DATE(dat) dt, SUM(amount) amount FROM (
|
||||
SELECT i.item_id, i.dat, i.amount
|
||||
FROM vn2008.item_out i
|
||||
JOIN item_range_copy1 ir ON ir.item_id = i.item_id
|
||||
WHERE i.dat >= vStartDate
|
||||
AND (ir.date_end IS NULL OR i.dat <= ir.date_end)
|
||||
AND i.warehouse_id = vWarehouse
|
||||
UNION ALL
|
||||
SELECT i.item_id, i.dat, i.amount
|
||||
FROM vn2008.item_entry_in i
|
||||
JOIN item_range_copy2 ir ON ir.item_id = i.item_id
|
||||
WHERE i.dat >= vStartDate
|
||||
AND (ir.date_end IS NULL OR i.dat <= ir.date_end)
|
||||
AND i.warehouse_id = vWarehouse
|
||||
UNION ALL
|
||||
SELECT i.item_id, i.dat, i.amount
|
||||
FROM vn2008.item_entry_out i
|
||||
JOIN item_range_copy3 ir ON ir.item_id = i.item_id
|
||||
WHERE i.dat >= vStartDate
|
||||
AND (ir.date_end IS NULL OR i.dat <= ir.date_end)
|
||||
AND i.warehouse_id = vWarehouse
|
||||
UNION ALL
|
||||
SELECT r.item_id, r.shipment, -r.amount
|
||||
FROM hedera.order_row r
|
||||
JOIN hedera.`order` o ON o.id = r.order_id
|
||||
JOIN item_range_copy4 ir ON ir.item_id = r.item_id
|
||||
WHERE r.shipment >= vStartDate
|
||||
AND (ir.date_end IS NULL OR r.shipment <= ir.date_end)
|
||||
AND r.warehouse_id = vWarehouse
|
||||
AND r.created >= vReserveDate
|
||||
AND NOT o.confirmed
|
||||
) t
|
||||
GROUP BY item_id, dt
|
||||
) t
|
||||
GROUP BY t.item_id
|
||||
) t GROUP BY t.item_id;
|
||||
|
||||
DROP TEMPORARY TABLE
|
||||
vn2008.tmp_item
|
||||
,item_range
|
||||
,item_range_copy1
|
||||
,item_range_copy2
|
||||
,item_range_copy3
|
||||
,item_range_copy4;
|
||||
|
||||
CALL cache_calc_end (vCalc);
|
||||
END$$
|
||||
|
||||
DELIMITER ;
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
DROP VIEW IF EXISTS `vn`.`queuePriority` ;
|
||||
|
||||
CREATE
|
||||
OR REPLACE ALGORITHM = UNDEFINED
|
||||
DEFINER = `root`@`%`
|
||||
SQL SECURITY DEFINER
|
||||
VIEW `vn`.`queuePriority` AS
|
||||
SELECT
|
||||
`p`.`Id_Prioridad` AS `id`,
|
||||
`p`.`Prioridad` AS `priority`
|
||||
FROM
|
||||
`vn2008`.`Prioridades` `p`;
|
|
@ -4,7 +4,7 @@ export MYSQL_PWD=root
|
|||
|
||||
mysql_import() {
|
||||
FILE=$1
|
||||
echo "[INFO] -> Imported $FILE"
|
||||
echo "[INFO] -> Importing $FILE"
|
||||
mysql -u root --default-character-set=utf8 --comments -f < "$FILE"
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
[mysqld]
|
||||
innodb_log_file_size = 4M
|
||||
innodb_autoextend_increment = 4
|
File diff suppressed because one or more lines are too long
|
@ -381,7 +381,7 @@ INSERT INTO `vn`.`company`(`id`, `code`, `supplierAccountFk`, `workerManagerFk`,
|
|||
(791 , 'FTH', NULL, 30, NULL, 3, '2015-11-30'),
|
||||
(1381, 'ORN', NULL, 30, NULL, 7, NULL);
|
||||
|
||||
INSERT INTO `vn`.`invoiceOut`(`id`, `serial`, `amount`, `issued`,`clientFk`, `created`, `companyFk`, `dued`, `booked`, `bankFk`, `pdf`)
|
||||
INSERT INTO `vn`.`invoiceOut`(`id`, `serial`, `amount`, `issued`,`clientFk`, `created`, `companyFk`, `dued`, `booked`, `bankFk`, `hasPdf`)
|
||||
VALUES
|
||||
(1, 'T', 1014.24, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 101, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 442, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 1),
|
||||
(2, 'T', 121.36, CURDATE(), 102, CURDATE(), 442, CURDATE(), CURDATE(), 1, 1),
|
||||
|
@ -1448,6 +1448,14 @@ INSERT INTO `vn`.`ticketRequest`(`id`, `description`, `requesterFk`, `atenderFk`
|
|||
(3, 'Melee weapon heavy shield 1x0.5m', 18, 35, 20, 4, 3.06, 0, NULL, 1, DATE_ADD(CURDATE(), INTERVAL -15 DAY)),
|
||||
(4, 'Melee weapon combat first 15cm', 18, 35, 15, NULL, 1.30, NULL, NULL, 11, CURDATE());
|
||||
|
||||
INSERT INTO `vn`.`ticketServiceType`(`id`, `name`)
|
||||
VALUES
|
||||
(1, 'Porte Agencia'),
|
||||
(2, 'Portes Retorno'),
|
||||
(3, 'Porte Carry'),
|
||||
(4, 'Cargo FITOSANITARIO'),
|
||||
(5, 'Documentos');
|
||||
|
||||
INSERT INTO `vn`.`ticketService`(`id`, `description`, `quantity`, `price`, `taxClassFk`, `ticketFk`)
|
||||
VALUES
|
||||
(1, 'Documentos', 1, 2.00, 1, 1),
|
||||
|
@ -1820,11 +1828,11 @@ INSERT INTO `vn`.`dmsType`(`id`, `name`, `path`, `readRoleFk`, `writeRoleFk`, `c
|
|||
(18, 'dua', 'dua', NULL, NULL, 'dua'),
|
||||
(19, 'inmovilizado', 'inmovilizado', NULL, NULL, 'fixedAssets');
|
||||
|
||||
INSERT INTO `vn`.`dms`(`id`, `dmsTypeFk`, `file`, `workerFk`, `warehouseFk`, `companyFk`, `hardCopyNumber`, `hasFile`, `reference`, `description`, `created`)
|
||||
INSERT INTO `vn`.`dms`(`id`, `dmsTypeFk`, `file`, `contentType`, `workerFk`, `warehouseFk`, `companyFk`, `hardCopyNumber`, `hasFile`, `reference`, `description`, `created`)
|
||||
VALUES
|
||||
(1, 14, '1.pdf', 5, 1, 442, NULL, FALSE, 'Ticket:11', 'Ticket:11 dms for the ticket', CURDATE()),
|
||||
(2, 5, '2.pdf', 5, 1, 442, 1, TRUE, 'Client:101', 'Client:101 dms for the client', CURDATE()),
|
||||
(3, 5, '3.pdf', 5, 1, 442, NULL, TRUE, 'Client: 101', 'Client:101 readme', CURDATE());
|
||||
(1, 14, '1.txt', 'text/plain', 5, 1, 442, NULL, FALSE, 'Ticket:11', 'Ticket:11 dms for the ticket', CURDATE()),
|
||||
(2, 5, '2.txt', 'text/plain', 5, 1, 442, 1, TRUE, 'Client:101', 'Client:101 dms for the client', CURDATE()),
|
||||
(3, 5, '3.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'Client: 101', 'Client:101 readme', CURDATE());
|
||||
|
||||
INSERT INTO `vn`.`ticketDms`(`ticketFk`, `dmsFk`)
|
||||
VALUES
|
||||
|
@ -1835,4 +1843,12 @@ INSERT INTO `vn`.`clientDms`(`clientFk`, `dmsFk`)
|
|||
(101, 2),
|
||||
(101, 3);
|
||||
|
||||
INSERT INTO `vn`.`device` (`sn`, `model`, `userFk`) VALUES ('aaa', 'android', '9');
|
||||
INSERT INTO `vn`.`device` (`sn`, `model`, `userFk`)
|
||||
VALUES
|
||||
('aaa', 'android', '9');
|
||||
|
||||
INSERT INTO `vn`.`queuePriority`(`id`, `priority`)
|
||||
VALUES
|
||||
(1, 'Alta'),
|
||||
(2, 'Normal'),
|
||||
(3, 'Baja');
|
File diff suppressed because it is too large
Load Diff
|
@ -100,4 +100,3 @@ TABLES=(
|
|||
workcenter
|
||||
)
|
||||
dump_tables ${TABLES[@]}
|
||||
|
||||
|
|
|
@ -26,4 +26,3 @@ mysqldump \
|
|||
--databases \
|
||||
${SCHEMAS[@]} \
|
||||
> dump/structure.sql
|
||||
|
||||
|
|
|
@ -20,27 +20,27 @@ describe('last_buy_refresh()', () => {
|
|||
|
||||
let lastBuyTable = result[lastBuyTableIndex];
|
||||
|
||||
expect(lastBuyTable.length).toEqual(6);
|
||||
expect(lastBuyTable.length).toEqual(12);
|
||||
|
||||
expect(lastBuyTable[0].item_id).toEqual(1);
|
||||
expect(lastBuyTable[1].item_id).toEqual(2);
|
||||
expect(lastBuyTable[2].item_id).toEqual(3);
|
||||
expect(lastBuyTable[3].item_id).toEqual(4);
|
||||
expect(lastBuyTable[4].item_id).toEqual(8);
|
||||
expect(lastBuyTable[5].item_id).toEqual(9);
|
||||
expect(lastBuyTable[1].item_id).toEqual(1);
|
||||
expect(lastBuyTable[2].item_id).toEqual(1);
|
||||
expect(lastBuyTable[3].item_id).toEqual(2);
|
||||
expect(lastBuyTable[4].item_id).toEqual(2);
|
||||
expect(lastBuyTable[5].item_id).toEqual(3);
|
||||
|
||||
expect(lastBuyTable[0].warehouse_id).toEqual(1);
|
||||
expect(lastBuyTable[1].warehouse_id).toEqual(1);
|
||||
expect(lastBuyTable[2].warehouse_id).toEqual(1);
|
||||
expect(lastBuyTable[1].warehouse_id).toEqual(3);
|
||||
expect(lastBuyTable[2].warehouse_id).toEqual(5);
|
||||
expect(lastBuyTable[3].warehouse_id).toEqual(1);
|
||||
expect(lastBuyTable[4].warehouse_id).toEqual(1);
|
||||
expect(lastBuyTable[4].warehouse_id).toEqual(5);
|
||||
expect(lastBuyTable[5].warehouse_id).toEqual(1);
|
||||
|
||||
expect(lastBuyTable[1].buy_id).toEqual(4);
|
||||
expect(lastBuyTable[1].buy_id).toEqual(10);
|
||||
expect(lastBuyTable[0].buy_id).toEqual(3);
|
||||
expect(lastBuyTable[2].buy_id).toEqual(5);
|
||||
expect(lastBuyTable[3].buy_id).toEqual(8);
|
||||
expect(lastBuyTable[4].buy_id).toEqual(6);
|
||||
expect(lastBuyTable[5].buy_id).toEqual(7);
|
||||
expect(lastBuyTable[2].buy_id).toEqual(13);
|
||||
expect(lastBuyTable[3].buy_id).toEqual(4);
|
||||
expect(lastBuyTable[4].buy_id).toEqual(14);
|
||||
expect(lastBuyTable[5].buy_id).toEqual(5);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -8,7 +8,7 @@ describe('ticketComponentUpdateSale()', () => {
|
|||
|
||||
let params = {
|
||||
warehouseFk: 1,
|
||||
ticketFk: 1
|
||||
ticketFk: 13
|
||||
};
|
||||
|
||||
stmts.push('START TRANSACTION');
|
||||
|
@ -48,26 +48,29 @@ describe('ticketComponentUpdateSale()', () => {
|
|||
let insertTicketComponentTable = `
|
||||
INSERT INTO tmp.ticketComponent (warehouseFk, itemFk, componentFk, cost)
|
||||
VALUES
|
||||
(1 , 2 , 23 , 999.00),
|
||||
(1 , 2 , 28 , 2.00),
|
||||
(1 , 4 , 23 , 999.00),
|
||||
(1 , 4 , 28 , 1.00)
|
||||
(1 , 4 , 15 , 999.00),
|
||||
(1 , 4 , 17 , 2.00),
|
||||
(1 , 4 , 22 , 999.00),
|
||||
(1 , 4 , 28 , 1.00),
|
||||
(1 , 4 , 29 , 2.00),
|
||||
(1 , 4 , 32 , 999.00),
|
||||
(1 , 4 , 39 , 1.00)
|
||||
`;
|
||||
|
||||
stmts.push(insertTicketComponentTable);
|
||||
|
||||
let updateComponentTwentyThree = `
|
||||
let updateComponentTwentyNine = `
|
||||
UPDATE vn.saleComponent
|
||||
SET value = '5'
|
||||
WHERE saleFk = 1 AND componentFk = 23
|
||||
WHERE saleFk = 26 AND componentFk = 29
|
||||
`;
|
||||
|
||||
stmts.push(updateComponentTwentyThree);
|
||||
stmts.push(updateComponentTwentyNine);
|
||||
|
||||
let updateComponentTwentyEight = `
|
||||
UPDATE vn.saleComponent
|
||||
SET value = '5'
|
||||
WHERE saleFk = 1 AND componentFk = 28
|
||||
WHERE saleFk = 26 AND componentFk = 28
|
||||
`;
|
||||
|
||||
stmts.push(updateComponentTwentyEight);
|
||||
|
@ -75,24 +78,24 @@ describe('ticketComponentUpdateSale()', () => {
|
|||
let priceFixtedToZero = `
|
||||
UPDATE vn.sale
|
||||
SET priceFixed = 0
|
||||
WHERE id = 1
|
||||
WHERE id = 26
|
||||
`;
|
||||
|
||||
stmts.push(priceFixtedToZero);
|
||||
|
||||
let firstSalePriceIndexBefore = stmts.push('SELECT price FROM vn.sale WHERE id = 1') - 1;
|
||||
let firstSalePriceIndexBefore = stmts.push('SELECT price FROM vn.sale WHERE id = 26') - 1;
|
||||
|
||||
stmts.push('CALL vn.ticketComponentUpdateSale(1)');
|
||||
|
||||
let firstSalePriceIndexAfter = stmts.push('SELECT price FROM vn.sale WHERE id = 1') - 1;
|
||||
let firstSalePriceIndexAfter = stmts.push('SELECT price FROM vn.sale WHERE id = 26') - 1;
|
||||
|
||||
stmts.push('ROLLBACK');
|
||||
|
||||
let sql = ParameterizedSQL.join(stmts, ';');
|
||||
let result = await app.models.Ticket.rawStmt(sql);
|
||||
|
||||
expect(result[firstSalePriceIndexBefore][0].price).toEqual(9.1);
|
||||
expect(result[firstSalePriceIndexAfter][0].price).toEqual(5);
|
||||
expect(result[firstSalePriceIndexBefore][0].price).toEqual(1.72);
|
||||
expect(result[firstSalePriceIndexAfter][0].price).toEqual(1005);
|
||||
});
|
||||
|
||||
it(`should keep the sale price when option TWO using the base components and save the difference in a new component`, async() => {
|
||||
|
@ -101,7 +104,7 @@ describe('ticketComponentUpdateSale()', () => {
|
|||
|
||||
let params = {
|
||||
warehouseFk: 1,
|
||||
ticketFk: 1
|
||||
ticketFk: 13
|
||||
};
|
||||
|
||||
stmts.push('START TRANSACTION');
|
||||
|
@ -139,28 +142,31 @@ describe('ticketComponentUpdateSale()', () => {
|
|||
stmts.push(createTicketComponentTable);
|
||||
|
||||
let insertTicketComponentTable = `
|
||||
INSERT INTO tmp.ticketComponent (warehouseFk, itemFk, componentFk, cost)
|
||||
VALUES
|
||||
(1 , 2 , 23 , 999.00),
|
||||
(1 , 2 , 28 , 2.00),
|
||||
(1 , 4 , 23 , 999.00),
|
||||
(1 , 4 , 28 , 1.00)
|
||||
INSERT INTO tmp.ticketComponent (warehouseFk, itemFk, componentFk, cost)
|
||||
VALUES
|
||||
(1 , 4 , 15 , 999.00),
|
||||
(1 , 4 , 17 , 2.00),
|
||||
(1 , 4 , 22 , 999.00),
|
||||
(1 , 4 , 28 , 1.00),
|
||||
(1 , 4 , 29 , 2.00),
|
||||
(1 , 4 , 32 , 999.00),
|
||||
(1 , 4 , 39 , 1.00)
|
||||
`;
|
||||
|
||||
stmts.push(insertTicketComponentTable);
|
||||
|
||||
let updateComponentTwentyThree = `
|
||||
let updateComponentTwentyNine = `
|
||||
UPDATE vn.saleComponent
|
||||
SET value = '5'
|
||||
WHERE saleFk = 1 AND componentFk = 23
|
||||
WHERE saleFk = 26 AND componentFk = 29
|
||||
`;
|
||||
|
||||
stmts.push(updateComponentTwentyThree);
|
||||
stmts.push(updateComponentTwentyNine);
|
||||
|
||||
let updateComponentTwentyEight = `
|
||||
UPDATE vn.saleComponent
|
||||
SET value = '5'
|
||||
WHERE saleFk = 1 AND componentFk = 28
|
||||
WHERE saleFk = 26 AND componentFk = 28
|
||||
`;
|
||||
|
||||
stmts.push(updateComponentTwentyEight);
|
||||
|
@ -168,24 +174,24 @@ describe('ticketComponentUpdateSale()', () => {
|
|||
let priceFixtedToZero = `
|
||||
UPDATE vn.sale
|
||||
SET priceFixed = 0
|
||||
WHERE id = 1
|
||||
WHERE id = 26
|
||||
`;
|
||||
|
||||
stmts.push(priceFixtedToZero);
|
||||
|
||||
let firstSalePriceIndexBefore = stmts.push('SELECT price FROM vn.sale WHERE id = 1') - 1;
|
||||
let firstSalePriceIndexBefore = stmts.push('SELECT price FROM vn.sale WHERE id = 26') - 1;
|
||||
|
||||
stmts.push('CALL vn.ticketComponentUpdateSale(2)');
|
||||
|
||||
let addedComponentIndex = stmts.push('SELECT * FROM vn.saleComponent WHERE saleFk = 1 AND componentFk = 17') - 1;
|
||||
let firstSalePriceIndexAfter = stmts.push('SELECT price FROM vn.sale WHERE id = 1') - 1;
|
||||
let addedComponentIndex = stmts.push('SELECT * FROM vn.saleComponent WHERE saleFk = 26 AND componentFk = 17') - 1;
|
||||
let firstSalePriceIndexAfter = stmts.push('SELECT price FROM vn.sale WHERE id = 26') - 1;
|
||||
|
||||
stmts.push('ROLLBACK');
|
||||
|
||||
let sql = ParameterizedSQL.join(stmts, ';');
|
||||
let result = await app.models.Ticket.rawStmt(sql);
|
||||
|
||||
expect(result[addedComponentIndex][0].value).toEqual(4.1);
|
||||
expect(result[addedComponentIndex][0].value).toEqual(-1003.28);
|
||||
expect(result[firstSalePriceIndexBefore][0].price).toEqual(result[firstSalePriceIndexAfter][0].price);
|
||||
});
|
||||
|
||||
|
@ -280,8 +286,8 @@ describe('ticketComponentUpdateSale()', () => {
|
|||
let sql = ParameterizedSQL.join(stmts, ';');
|
||||
let result = await app.models.Ticket.rawStmt(sql);
|
||||
|
||||
expect(result[componentTwentyEightIndex][0].value).toEqual(1.6);
|
||||
expect(result[componentTwentyNineIndex][0].value).toEqual(0.4);
|
||||
expect(result[componentTwentyEightIndex][0].value).toEqual(79.517);
|
||||
expect(result[componentTwentyNineIndex][0].value).toEqual(19.879);
|
||||
expect(result[firstSalePriceIndexBefore][0].price).toEqual(result[firstSalePriceIndexAfter][0].price);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
It works!
|
|
@ -0,0 +1 @@
|
|||
It works!
|
|
@ -441,7 +441,8 @@ export default {
|
|||
basicDataButton: 'vn-left-menu a[ui-sref="ticket.card.basicData.stepOne"]',
|
||||
clientAutocomplete: 'vn-autocomplete[field="$ctrl.clientFk"]',
|
||||
addressAutocomplete: 'vn-autocomplete[field="$ctrl.ticket.addressFk"]',
|
||||
agencyAutocomplete: 'vn-autocomplete[field="$ctrl.ticket.agencyModeFk"]',
|
||||
agencyAutocomplete: 'vn-autocomplete[field="$ctrl.agencyModeId"]',
|
||||
zoneAutocomplete: 'vn-autocomplete[field="$ctrl.zoneId"]',
|
||||
nextStepButton: 'vn-step-control > section > section.buttons > section:nth-child(2) > vn-button',
|
||||
finalizeButton: 'vn-step-control > section > section.buttons > section:nth-child(2) > vn-submit',
|
||||
stepTwoTotalPriceDif: 'vn-ticket-basic-data-step-two > form > vn-card > div > vn-horizontal > table > tfoot > tr > td:nth-child(4)',
|
||||
|
|
|
@ -14,6 +14,7 @@ describe('Ticket Edit basic data path', () => {
|
|||
it(`should edit the ticket agency then click next`, async() => {
|
||||
let url = await nightmare
|
||||
.autocompleteSearch(selectors.ticketBasicData.agencyAutocomplete, 'Silla247Expensive')
|
||||
.waitToGetProperty(`${selectors.ticketBasicData.zoneAutocomplete} input`, 'value')
|
||||
.waitToClick(selectors.ticketBasicData.nextStepButton)
|
||||
.waitForURL('data/step-two')
|
||||
.parsedUrl();
|
||||
|
|
|
@ -92,8 +92,6 @@ export default class Autocomplete extends Input {
|
|||
set field(value) {
|
||||
this._field = value;
|
||||
|
||||
if (!value) return;
|
||||
|
||||
this.refreshSelection();
|
||||
this.emit('change', {value});
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
Local warehouse: Almacén local
|
||||
Local bank: Banco local
|
||||
Local company: Compañia local
|
||||
Local company: Empresa local
|
||||
User warehouse: Almacén del usuario
|
||||
User company: Compañia del usuario
|
||||
User company: Empresa del usuario
|
|
@ -198,7 +198,9 @@ async function backendStatus() {
|
|||
timer = setInterval(() => {
|
||||
const url = `${e2eConfig.url}/api/Applications/status`;
|
||||
request.get(url, (err, res) => {
|
||||
if (res.body == 'true') {
|
||||
if (err || attempts > 100) // 250ms * 100 => 25s timeout
|
||||
throw new Error('Could not connect to backend');
|
||||
else if (res && res.body == 'true') {
|
||||
clearInterval(timer);
|
||||
resolve(attempts);
|
||||
} else
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
"Cannot check Equalization Tax in this NIF/CIF": "Cannot check Equalization Tax in this NIF/CIF",
|
||||
"You can't create an order for a frozen client": "You can't create an order for a frozen client",
|
||||
"This address doesn't exist": "This address doesn't exist",
|
||||
"NO_AGENCY_AVAILABLE": "NO_AGENCY_AVAILABLE",
|
||||
"Warehouse cannot be blank": "Warehouse cannot be blank",
|
||||
"Agency cannot be blank": "Agency cannot be blank",
|
||||
"The IBAN does not have the correct format": "The IBAN does not have the correct format",
|
||||
|
|
|
@ -82,7 +82,8 @@
|
|||
"INFINITE_LOOP": "Existe una dependencia entre dos Jefes",
|
||||
"The sales of the current ticket can't be modified": "Las lineas de este ticket no pueden ser modificadas",
|
||||
"The sales of the receiver ticket can't be modified": "Las lineas del ticket al que envias no pueden ser modificadas",
|
||||
"NO_AGENCY_AVAILABLE": "No hay agencias disponibles",
|
||||
"NO_AGENCY_AVAILABLE": "No hay una zona de reparto disponible con estos parámetros",
|
||||
"ERROR_PAST_SHIPMENT": "No puedes seleccionar una fecha de envío en pasado",
|
||||
"The current ticket can't be modified": "El ticket actual no puede ser modificado",
|
||||
"The sales of this ticket can't be modified": "Las lineas de este ticket no pueden ser modificadas",
|
||||
"Please select at least one sale": "Por favor selecciona al menos una linea",
|
||||
|
@ -95,5 +96,6 @@
|
|||
"This item is not available": "Este artículo no está disponible",
|
||||
"This postcode already exists": "Este código postal ya existe",
|
||||
"Concept cannot be blank": "El concepto no puede quedar en blanco",
|
||||
"File doesn't exists": "El archivo no existe"
|
||||
"File doesn't exists": "El archivo no existe",
|
||||
"You don't have privileges to change the zone": "No tienes permisos para cambiar la zona"
|
||||
}
|
|
@ -1,14 +1,10 @@
|
|||
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('getLanded', {
|
||||
Self.remoteMethod('getLanded', {
|
||||
description: 'Returns the first shipped and landed possible for params',
|
||||
accessType: 'READ',
|
||||
accepts: [{
|
||||
arg: 'params',
|
||||
type: 'Object',
|
||||
description: `shipped, addressFk, agencyModeFk, warehouseFk`
|
||||
}, {
|
||||
arg: 'shipped',
|
||||
type: 'date',
|
||||
required: true
|
||||
|
@ -38,15 +34,14 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.getLanded = async(ctx, params) => {
|
||||
Self.getLanded = async(shipped, addressFk, agencyModeFk, warehouseFk) => {
|
||||
let stmts = [];
|
||||
params = params || ctx.args;
|
||||
stmts.push(new ParameterizedSQL(
|
||||
`CALL vn.zoneGetLanded(?, ?, ?, ?)`, [
|
||||
params.shipped,
|
||||
params.addressFk,
|
||||
params.agencyModeFk,
|
||||
params.warehouseFk
|
||||
shipped,
|
||||
addressFk,
|
||||
agencyModeFk,
|
||||
warehouseFk
|
||||
]
|
||||
));
|
||||
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('getShipped', {
|
||||
Self.remoteMethod('getShipped', {
|
||||
description: 'Returns the first shipped possible for params',
|
||||
accessType: 'READ',
|
||||
accepts: [{
|
||||
arg: 'params',
|
||||
type: 'Object',
|
||||
description: `landed, addressFk, agencyModeFk, warehouseFk`
|
||||
}, {
|
||||
arg: 'landed',
|
||||
type: 'date',
|
||||
required: true
|
||||
|
@ -36,15 +32,14 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.getShipped = async(ctx, params)=> {
|
||||
params = params || ctx.args;
|
||||
Self.getShipped = async(landed, addressFk, agencyModeFk, warehouseFk)=> {
|
||||
let query = `CALL vn.zoneGetShipped(?, ?, ?, ?)`;
|
||||
let [response] = await Self.rawSql(query, [
|
||||
params.landed,
|
||||
params.addressFk,
|
||||
params.agencyModeFk,
|
||||
params.warehouseFk
|
||||
let [[response]] = await Self.rawSql(query, [
|
||||
landed,
|
||||
addressFk,
|
||||
agencyModeFk,
|
||||
warehouseFk
|
||||
]);
|
||||
return (response[0] && response[0].shipped && response[0].shipped.toJSON()) || null;
|
||||
return response;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -2,13 +2,11 @@ const app = require('vn-loopback/server/server');
|
|||
|
||||
describe('agency getLanded()', () => {
|
||||
it('should return a landing date', async() => {
|
||||
let data = {
|
||||
shipped: new Date(),
|
||||
addressFk: 121,
|
||||
agencyModeFk: 7,
|
||||
warehouseFk: 1
|
||||
};
|
||||
let result = await app.models.Agency.getLanded({}, data);
|
||||
const shipped = new Date();
|
||||
const addressFk = 121;
|
||||
const agencyModeFk = 7;
|
||||
const warehouseFk = 1;
|
||||
let result = await app.models.Agency.getLanded(shipped, addressFk, agencyModeFk, warehouseFk);
|
||||
|
||||
expect(result.landed).toBeDefined();
|
||||
});
|
||||
|
|
|
@ -2,13 +2,12 @@ const app = require('vn-loopback/server/server');
|
|||
|
||||
describe('agency getShipped()', () => {
|
||||
it('should return a shipment date', async() => {
|
||||
let data = {
|
||||
landed: new Date(),
|
||||
addressFk: 121,
|
||||
agencyModeFk: 7,
|
||||
warehouseFk: 1
|
||||
};
|
||||
let result = await app.models.Agency.getShipped({}, data);
|
||||
const landed = new Date();
|
||||
const addressFk = 121;
|
||||
const agencyModeFk = 7;
|
||||
const warehouseFk = 1;
|
||||
|
||||
let result = await app.models.Agency.getShipped(landed, addressFk, agencyModeFk, warehouseFk);
|
||||
|
||||
expect(result).toBeDefined();
|
||||
});
|
||||
|
@ -17,14 +16,13 @@ describe('agency getShipped()', () => {
|
|||
let newDate = new Date();
|
||||
newDate.setMonth(newDate.getMonth() - 1);
|
||||
|
||||
let data = {
|
||||
landed: newDate,
|
||||
addressFk: 121,
|
||||
agencyModeFk: 7,
|
||||
warehouseFk: 1
|
||||
};
|
||||
let result = await app.models.Agency.getShipped({}, data);
|
||||
const landed = newDate;
|
||||
const addressFk = 121;
|
||||
const agencyModeFk = 7;
|
||||
const warehouseFk = 1;
|
||||
|
||||
expect(result).toBeNull();
|
||||
let result = await app.models.Agency.getShipped(landed, addressFk, agencyModeFk, warehouseFk);
|
||||
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -43,7 +43,7 @@ module.exports = Self => {
|
|||
r.bankFk,
|
||||
u.nickname userNickname,
|
||||
r.clientFk,
|
||||
FALSE pdf,
|
||||
FALSE hasPdf,
|
||||
FALSE isInvoice
|
||||
FROM vn.receipt r
|
||||
LEFT JOIN vn.worker w ON w.id = r.workerFk
|
||||
|
@ -64,7 +64,7 @@ module.exports = Self => {
|
|||
NULL,
|
||||
NULL,
|
||||
i.clientFk,
|
||||
i.pdf,
|
||||
i.hasPdf,
|
||||
TRUE isInvoice
|
||||
FROM vn.invoiceOut i
|
||||
JOIN vn.company c ON c.id = i.companyFk
|
||||
|
|
|
@ -24,12 +24,30 @@
|
|||
<vn-textfield vn-one label="Street address" field="$ctrl.address.street"></vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete vn-id="province" vn-one
|
||||
field="$ctrl.address.provinceFk"
|
||||
url="/api/Provinces"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
label="Province">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete vn-id="town" vn-one
|
||||
label="City"
|
||||
url="/api/Towns"
|
||||
fields="['id', 'name']"
|
||||
where="{provinceFk: province.selection.id}"
|
||||
show-field="name"
|
||||
value-field="name"
|
||||
field="$ctrl.address.city">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete vn-one
|
||||
url="/api/Postcodes/location"
|
||||
fields="['code', 'townFk']"
|
||||
field="$ctrl.address.postalCode"
|
||||
selection="$ctrl.postcodeSelection"
|
||||
search-function="{code: $search}"
|
||||
url="/api/Postcodes/location"
|
||||
fields="['code', 'townFk']"
|
||||
where="{townFk: town.selection.id}"
|
||||
order="code, townFk"
|
||||
show-field="code"
|
||||
value-field="code"
|
||||
label="Postcode">
|
||||
|
@ -43,21 +61,7 @@
|
|||
vn-tooltip="New postcode"
|
||||
ng-click="postcode.open()">
|
||||
</vn-icon-button>
|
||||
<vn-autocomplete vn-one
|
||||
label="City"
|
||||
url="/api/Towns"
|
||||
show-field="name"
|
||||
value-field="name"
|
||||
field="$ctrl.address.city">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete vn-one
|
||||
disabled="true"
|
||||
field="$ctrl.address.provinceFk"
|
||||
url="/api/Provinces"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
label="Province">
|
||||
</vn-horizontal>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
|
|
|
@ -40,12 +40,30 @@
|
|||
<vn-textfield vn-one label="Street" field="$ctrl.address.street"></vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete vn-id="province" vn-one
|
||||
field="$ctrl.address.provinceFk"
|
||||
url="/api/Provinces"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
label="Province">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete vn-id="town" vn-one
|
||||
label="City"
|
||||
url="/api/Towns"
|
||||
fields="['id', 'name']"
|
||||
where="{provinceFk: province.selection.id}"
|
||||
show-field="name"
|
||||
value-field="name"
|
||||
field="$ctrl.address.city">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete vn-one
|
||||
url="/api/Postcodes/location"
|
||||
fields="['code', 'townFk']"
|
||||
field="$ctrl.address.postalCode"
|
||||
selection="$ctrl.postcodeSelection"
|
||||
search-function="{code: $search}"
|
||||
url="/api/Postcodes/location"
|
||||
fields="['code', 'townFk']"
|
||||
where="{townFk: town.selection.id}"
|
||||
order="code, townFk"
|
||||
show-field="code"
|
||||
value-field="code"
|
||||
label="Postcode">
|
||||
|
@ -59,21 +77,6 @@
|
|||
vn-tooltip="New postcode"
|
||||
ng-click="postcode.open()">
|
||||
</vn-icon-button>
|
||||
<vn-autocomplete vn-one
|
||||
label="City"
|
||||
url="/api/Towns"
|
||||
show-field="name"
|
||||
value-field="name"
|
||||
field="$ctrl.address.city">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete vn-one
|
||||
disabled="true"
|
||||
field="$ctrl.address.provinceFk"
|
||||
url="/api/Provinces"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
label="Province">
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete vn-one
|
||||
|
|
|
@ -25,9 +25,10 @@ export default class Controller {
|
|||
}
|
||||
|
||||
set postcodeSelection(selection) {
|
||||
const hasValue = this._postcodeSelection;
|
||||
this._postcodeSelection = selection;
|
||||
|
||||
if (!selection) return;
|
||||
if (!selection || !hasValue) return;
|
||||
|
||||
const town = selection.town;
|
||||
const province = town.province;
|
||||
|
|
|
@ -59,6 +59,7 @@ describe('Client', () => {
|
|||
describe('postcodeSelection() setter', () => {
|
||||
it(`should set the town, province and contry properties`, () => {
|
||||
controller.address = {};
|
||||
controller._postcodeSelection = {townFk: 2};
|
||||
controller.postcodeSelection = {
|
||||
townFk: 1,
|
||||
code: 46001,
|
||||
|
|
|
@ -83,7 +83,7 @@
|
|||
</vn-check>
|
||||
</vn-td>
|
||||
<vn-td center>
|
||||
<a ng-show="balance.pdf"
|
||||
<a ng-show="balance.hasPdf"
|
||||
target="_blank"
|
||||
href="api/InvoiceOuts/{{::balance.id}}/download?access_token={{::$ctrl.accessToken}}">
|
||||
<vn-icon-button
|
||||
|
|
|
@ -33,19 +33,31 @@
|
|||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete vn-one
|
||||
field="$ctrl.client.postcode"
|
||||
selection="$ctrl.postcodeSelection"
|
||||
search-function="{code: $search}"
|
||||
url="/api/Postcodes/location"
|
||||
fields="['code', 'townFk']"
|
||||
show-field="code"
|
||||
value-field="code"
|
||||
label="Postcode">
|
||||
<tpl-item>
|
||||
{{code}}, {{town.name}} - {{town.province.name}}
|
||||
({{town.province.country.country}})
|
||||
</tpl-item>
|
||||
<vn-autocomplete vn-id="country" vn-one
|
||||
field="$ctrl.client.countryFk"
|
||||
url="/api/Countries"
|
||||
show-field="country"
|
||||
value-field="id"
|
||||
label="Country">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete vn-id="province" vn-one
|
||||
url="/api/Provinces"
|
||||
field="$ctrl.client.provinceFk"
|
||||
where="{countryFk: country.selection.id}"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
label="Province">
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete vn-id="town" vn-one
|
||||
label="City"
|
||||
url="/api/Towns"
|
||||
fields="['id', 'name']"
|
||||
where="{provinceFk: province.selection.id}"
|
||||
show-field="name"
|
||||
value-field="name"
|
||||
field="$ctrl.client.city">
|
||||
</vn-autocomplete>
|
||||
<vn-icon-button vn-auto margin-medium-v
|
||||
icon="add_circle"
|
||||
|
@ -53,29 +65,20 @@
|
|||
ng-click="postcode.open()">
|
||||
</vn-icon-button>
|
||||
<vn-autocomplete vn-one
|
||||
label="City"
|
||||
url="/api/Towns"
|
||||
show-field="name"
|
||||
value-field="name"
|
||||
field="$ctrl.client.city">
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete vn-one
|
||||
disabled="true"
|
||||
field="$ctrl.client.provinceFk"
|
||||
url="/api/Provinces"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
label="Province">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete vn-one
|
||||
disabled="true"
|
||||
field="$ctrl.client.countryFk"
|
||||
url="/api/Countries"
|
||||
show-field="country"
|
||||
value-field="id"
|
||||
label="Country">
|
||||
url="/api/Postcodes/location"
|
||||
fields="['code', 'townFk']"
|
||||
field="$ctrl.client.postcode"
|
||||
selection="$ctrl.postcodeSelection"
|
||||
search-function="{code: $search}"
|
||||
where="{townFk: town.selection.id}"
|
||||
order="code, townFk"
|
||||
show-field="code"
|
||||
value-field="code"
|
||||
label="Postcode">
|
||||
<tpl-item>
|
||||
{{code}}, {{town.name}} - {{town.province.name}}
|
||||
({{town.province.country.country}})
|
||||
</tpl-item>
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
|
|
|
@ -11,7 +11,7 @@ class Controller {
|
|||
this.dms = {
|
||||
files: [],
|
||||
hasFile: false,
|
||||
hasAttachedFile: false
|
||||
hasFileAttached: false
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -79,12 +79,12 @@ class Controller {
|
|||
}
|
||||
|
||||
onFileChange(files) {
|
||||
let hasAttachedFile = false;
|
||||
let hasFileAttached = false;
|
||||
if (files.length > 0)
|
||||
hasAttachedFile = true;
|
||||
hasFileAttached = true;
|
||||
|
||||
this.$.$applyAsync(() => {
|
||||
this.dms.hasAttachedFile = hasAttachedFile;
|
||||
this.dms.hasFileAttached = hasFileAttached;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,12 +48,12 @@ describe('Client', () => {
|
|||
});
|
||||
|
||||
describe('onFileChange()', () => {
|
||||
it('should set dms hasFile property to true if has any files', () => {
|
||||
it('should set dms hasFileAttached property to true if has any files', () => {
|
||||
const files = [{id: 1, name: 'MyFile'}];
|
||||
controller.onFileChange(files);
|
||||
$scope.$apply();
|
||||
|
||||
expect(controller.dms.hasFile).toBeTruthy();
|
||||
expect(controller.dms.hasFileAttached).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
</vn-input-file>
|
||||
</vn-horizontal>
|
||||
<vn-vertical>
|
||||
<vn-check
|
||||
<vn-check disabled="true"
|
||||
label="Generate identifier for original file"
|
||||
field="$ctrl.dms.hasFile">
|
||||
</vn-check>
|
||||
|
|
|
@ -33,7 +33,7 @@ class Controller {
|
|||
dmsTypeId: dms.dmsTypeFk,
|
||||
description: dms.description,
|
||||
hasFile: dms.hasFile,
|
||||
hasAttachedFile: false,
|
||||
hasFileAttached: false,
|
||||
files: []
|
||||
};
|
||||
});
|
||||
|
@ -68,12 +68,12 @@ class Controller {
|
|||
}
|
||||
|
||||
onFileChange(files) {
|
||||
let hasAttachedFile = false;
|
||||
let hasFileAttached = false;
|
||||
if (files.length > 0)
|
||||
hasAttachedFile = true;
|
||||
hasFileAttached = true;
|
||||
|
||||
this.$.$applyAsync(() => {
|
||||
this.dms.hasAttachedFile = hasAttachedFile;
|
||||
this.dms.hasFileAttached = hasFileAttached;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,12 +48,12 @@ describe('Client', () => {
|
|||
});
|
||||
|
||||
describe('onFileChange()', () => {
|
||||
it('should set dms hasFile property to true if has any files', () => {
|
||||
it('should set dms hasFileAttached property to true if has any files', () => {
|
||||
const files = [{id: 1, name: 'MyFile'}];
|
||||
controller.onFileChange(files);
|
||||
$scope.$apply();
|
||||
|
||||
expect(controller.dms.hasFile).toBeTruthy();
|
||||
expect(controller.dms.hasFileAttached).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -14,7 +14,8 @@
|
|||
<vn-tr>
|
||||
<vn-th field="dmsFk" default-order="DESC" shrink>Id</vn-th>
|
||||
<vn-th field="dmsTypeFk" shrink>Type</vn-th>
|
||||
<vn-th field="reference">Reference</vn-th>
|
||||
<vn-th field="hardCopyNumber" shrink number>Order</vn-th>
|
||||
<vn-th field="reference" shrink>Reference</vn-th>
|
||||
<vn-th>Description</vn-th>
|
||||
<vn-th field="hasFile" shrink>Original</vn-th>
|
||||
<vn-th>File</vn-th>
|
||||
|
@ -31,7 +32,12 @@
|
|||
{{::document.dms.dmsType.name}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td>
|
||||
<vn-td shrink number>
|
||||
<span title="{{::document.dms.hardCopyNumber}}">
|
||||
{{::document.dms.hardCopyNumber}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td shrink>
|
||||
<span title="{{::document.dms.reference}}">
|
||||
{{::document.dms.reference}}
|
||||
</span>
|
||||
|
|
|
@ -15,8 +15,9 @@ class Controller {
|
|||
scope: {
|
||||
fields: [
|
||||
'dmsTypeFk',
|
||||
'workerFk',
|
||||
'reference',
|
||||
'hardCopyNumber',
|
||||
'workerFk',
|
||||
'description',
|
||||
'hasFile',
|
||||
'file',
|
||||
|
|
|
@ -83,7 +83,7 @@ module.exports = Self => {
|
|||
case 'max':
|
||||
return {amount: {lte: value}};
|
||||
case 'hasPdf':
|
||||
return {'i.pdf': value};
|
||||
return {'i.hasPdf': value};
|
||||
case 'created':
|
||||
return {'i.created': value};
|
||||
case 'amount':
|
||||
|
@ -109,7 +109,7 @@ module.exports = Self => {
|
|||
i.created,
|
||||
i.dued,
|
||||
i.clientFk,
|
||||
i.pdf AS hasPdf,
|
||||
i.hasPdf,
|
||||
c.socialName AS clientSocialName,
|
||||
co.code AS companyCode
|
||||
FROM invoiceOut i
|
||||
|
|
|
@ -35,10 +35,7 @@
|
|||
"type": "date"
|
||||
},
|
||||
"hasPdf": {
|
||||
"type": "Boolean",
|
||||
"mysql": {
|
||||
"columnName": "pdf"
|
||||
}
|
||||
"type": "Boolean"
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
|
|
|
@ -3,26 +3,29 @@
|
|||
url="/ticket/api/TicketRequests/filter"
|
||||
limit="20"
|
||||
data="requests"
|
||||
order="isOk ASC"
|
||||
auto-load="false">
|
||||
</vn-crud-model>
|
||||
<form name="form">
|
||||
<div margin-medium>
|
||||
<vn-card pad-medium-h class="vn-list">
|
||||
<vn-horizontal>
|
||||
<vn-searchbar
|
||||
<vn-searchbar
|
||||
auto-load="false"
|
||||
panel="vn-request-search-panel"
|
||||
on-search="$ctrl.onSearch($params)"
|
||||
info="Search request by id or alias"
|
||||
vn-one
|
||||
vn-focus>
|
||||
</vn-searchbar>
|
||||
</vn-horizontal>
|
||||
</vn-card>
|
||||
<vn-card margin-medium-v>
|
||||
<vn-table model="model">
|
||||
<vn-table model="model" auto-load="false">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th number field="ticketFk">Ticket ID</vn-th>
|
||||
<vn-th field="shipped" default-order="DESC">Shipped</vn-th>
|
||||
<vn-th field="shipped">Shipped</vn-th>
|
||||
<vn-th field="warehouse">Warehouse</vn-th>
|
||||
<vn-th field="salesPersonNickname">SalesPerson</vn-th>
|
||||
<vn-th field="description">Description</vn-th>
|
||||
|
@ -31,8 +34,8 @@
|
|||
<vn-th field="atenderNickname">Atender</vn-th>
|
||||
<vn-th field="itemFk">Item</vn-th>
|
||||
<vn-th field="description">Concept</vn-th>
|
||||
<vn-th number>Quantity</vn-th>
|
||||
<vn-th>State</vn-th>
|
||||
<vn-th field="saleQuantity" number>Sale quantity</vn-th>
|
||||
<vn-th field="isOk">State</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
|
@ -56,14 +59,8 @@
|
|||
ng-click="$ctrl.showWorkerDescriptor($event, request.salesPersonFk)">
|
||||
{{::request.salesPersonNickname}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td>
|
||||
<span
|
||||
class="link"
|
||||
ng-click="$ctrl.showItemDescriptor($event, request.itemFk)">
|
||||
{{::request.description}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td title="{{::request.description}}">{{::request.description}}</vn-td>
|
||||
<vn-td number>{{::request.quantity}}</vn-td>
|
||||
<vn-td number>{{::request.price | currency: 'EUR':2}}</vn-td>
|
||||
<vn-td>
|
||||
|
@ -73,7 +70,7 @@
|
|||
{{::request.atenderNickname}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td-editable number>
|
||||
<vn-td-editable disabled="request.isOk === 0" number>
|
||||
<text>{{request.itemFk}}</text>
|
||||
<field>
|
||||
<vn-input-number vn-focus
|
||||
|
@ -82,8 +79,15 @@
|
|||
</vn-input-number>
|
||||
</field>
|
||||
</vn-td-editable>
|
||||
<vn-td>{{::request.itemDescription}}</vn-td>
|
||||
<vn-td-editable disabled="!request.saleFk && request.itemFk" number>
|
||||
<vn-td>
|
||||
<span
|
||||
class="link"
|
||||
ng-click="$ctrl.showItemDescriptor($event, request.itemFk)"
|
||||
title="{{::request.itemDescription}}">
|
||||
{{::request.itemDescription}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td-editable disabled="request.isOk === 0" number>
|
||||
<text number>{{request.saleQuantity}}</text>
|
||||
<field>
|
||||
<vn-input-number vn-focus
|
||||
|
@ -94,8 +98,13 @@
|
|||
</vn-td-editable>
|
||||
<vn-td>{{::$ctrl.getState(request.isOk)}}</vn-td>
|
||||
<vn-td>
|
||||
<vn-icon
|
||||
ng-if="request.response.length"
|
||||
vn-tooltip="{{request.response}}"
|
||||
icon="insert_drive_file">
|
||||
</vn-icon>
|
||||
<vn-icon-button
|
||||
disabled="request.isOk === 0"
|
||||
ng-if="request.isOk != 0"
|
||||
number
|
||||
icon="thumb_down"
|
||||
ng-click="$ctrl.showDenyReason($event, request.id)"
|
||||
|
|
|
@ -28,16 +28,17 @@ export default class Controller {
|
|||
}
|
||||
|
||||
confirmRequest(request) {
|
||||
if (request.itemFk && request.quantity) {
|
||||
if (request.itemFk && request.saleQuantity) {
|
||||
let params = {
|
||||
itemFk: request.itemFk,
|
||||
quantity: request.quantity || request.saleQuantity
|
||||
quantity: request.saleQuantity
|
||||
};
|
||||
|
||||
let endpoint = `/api/TicketRequests/${request.id}/confirm`;
|
||||
|
||||
this.$http.post(endpoint, params).then(() => {
|
||||
this.vnApp.showSuccess(this._.instant('Data saved!'));
|
||||
this.$.model.refresh();
|
||||
}).catch( e => {
|
||||
this.$.model.refresh();
|
||||
throw e;
|
||||
|
@ -59,7 +60,8 @@ export default class Controller {
|
|||
this.$.model.refresh();
|
||||
throw e;
|
||||
});
|
||||
}
|
||||
} else
|
||||
this.confirmRequest(request);
|
||||
}
|
||||
|
||||
compareDate(date) {
|
||||
|
@ -87,6 +89,7 @@ export default class Controller {
|
|||
this.denyRequestId = requestId;
|
||||
this.$.denyReason.parent = event.target;
|
||||
this.$.denyReason.show();
|
||||
document.querySelector('vn-item-request vn-textarea textArea').focus();
|
||||
}
|
||||
|
||||
clear() {
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
import './index.js';
|
||||
import crudModel from 'core/mocks/crud-model';
|
||||
|
||||
describe('Item', () => {
|
||||
describe('Component vnItemRequest', () => {
|
||||
let $scope;
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
|
||||
beforeEach(ngModule('item'));
|
||||
|
||||
beforeEach(angular.mock.inject(($componentController, $rootScope, _$httpBackend_) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
$scope = $rootScope.$new();
|
||||
$scope.model = crudModel;
|
||||
$scope.denyReason = {hide: () => {}};
|
||||
controller = $componentController('vnItemRequest', {$scope: $scope});
|
||||
}));
|
||||
|
||||
describe('getState()', () => {
|
||||
it(`should return an string depending to the isOK value`, () => {
|
||||
let isOk = null;
|
||||
let result = controller.getState(isOk);
|
||||
|
||||
expect(result).toEqual('Nueva');
|
||||
|
||||
isOk = 1;
|
||||
result = controller.getState(isOk);
|
||||
|
||||
expect(result).toEqual('Aceptada');
|
||||
|
||||
isOk = 0;
|
||||
result = controller.getState(isOk);
|
||||
|
||||
expect(result).toEqual('Denegada');
|
||||
});
|
||||
});
|
||||
|
||||
describe('confirmRequest()', () => {
|
||||
it(`should do nothing if the request does't have itemFk or saleQuantity`, () => {
|
||||
let request = {};
|
||||
spyOn(controller.vnApp, 'showSuccess');
|
||||
|
||||
controller.confirmRequest(request);
|
||||
|
||||
expect(controller.vnApp.showSuccess).not.toHaveBeenCalledWith();
|
||||
});
|
||||
|
||||
it('should perform a query and call vnApp.showSuccess() and refresh if the conditions are met', () => {
|
||||
spyOn(controller.vnApp, 'showSuccess');
|
||||
let model = controller.$.model;
|
||||
spyOn(model, 'refresh');
|
||||
|
||||
let request = {itemFk: 1, saleQuantity: 1, id: 1};
|
||||
|
||||
$httpBackend.when('POST', `/api/TicketRequests/${request.id}/confirm`).respond();
|
||||
$httpBackend.expect('POST', `/api/TicketRequests/${request.id}/confirm`).respond();
|
||||
controller.confirmRequest(request);
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
|
||||
expect($scope.model.refresh).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('changeQuantity()', () => {
|
||||
it(`should call confirmRequest() if there's no sale id in the request`, () => {
|
||||
let request = {};
|
||||
spyOn(controller, 'confirmRequest');
|
||||
|
||||
controller.changeQuantity(request);
|
||||
|
||||
expect(controller.confirmRequest).toHaveBeenCalledWith(jasmine.any(Object));
|
||||
});
|
||||
|
||||
it(`should perform a query and call vnApp.showSuccess() if the conditions are met`, () => {
|
||||
let request = {saleFk: 1, saleQuantity: 1};
|
||||
spyOn(controller.vnApp, 'showSuccess');
|
||||
|
||||
|
||||
$httpBackend.when('PATCH', `/api/Sales/${request.saleFk}/`).respond();
|
||||
$httpBackend.expect('PATCH', `/api/Sales/${request.saleFk}/`).respond();
|
||||
controller.changeQuantity(request);
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
|
||||
});
|
||||
});
|
||||
|
||||
describe('compareDate()', () => {
|
||||
it(`should return "success" if receives a future date`, () => {
|
||||
let date = '3019-02-18T11:00:00.000Z';
|
||||
|
||||
let result = controller.compareDate(date);
|
||||
|
||||
expect(result).toEqual('success');
|
||||
});
|
||||
|
||||
it(`should return "warning" if date is today`, () => {
|
||||
let date = new Date();
|
||||
|
||||
let result = controller.compareDate(date);
|
||||
|
||||
expect(result).toEqual('warning');
|
||||
});
|
||||
});
|
||||
|
||||
describe('denyRequest()', () => {
|
||||
it(`should perform a query and call vnApp.showSuccess(), refresh(), hide() and set denyObservation to null in the controller`, () => {
|
||||
spyOn(controller.vnApp, 'showSuccess');
|
||||
let model = controller.$.model;
|
||||
spyOn(model, 'refresh');
|
||||
spyOn(controller.$.denyReason, 'hide');
|
||||
|
||||
controller.denyRequestId = 1;
|
||||
|
||||
$httpBackend.when('POST', `/api/TicketRequests/${controller.denyRequestId}/deny`).respond();
|
||||
$httpBackend.expect('POST', `/api/TicketRequests/${controller.denyRequestId}/deny`).respond();
|
||||
controller.denyRequest();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
|
||||
expect($scope.model.refresh).toHaveBeenCalledWith();
|
||||
expect($scope.denyReason.hide).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
Discard: Descartar
|
||||
Indicate the reasons to deny this request: Indique las razones para descartar esta peticion
|
||||
Buy requests: Peticiones de compra
|
||||
Buy requests: Peticiones de compra
|
||||
Search request by id or alias: Buscar peticiones por identificador o alias
|
||||
Sale quantity: C. conseguida
|
|
@ -1,12 +1,20 @@
|
|||
vn-dialog[vn-id="denyReason"] {
|
||||
button.close {
|
||||
display: none
|
||||
}
|
||||
& vn-button {
|
||||
margin: 0 auto
|
||||
@import "variables";
|
||||
|
||||
vn-item-request {
|
||||
vn-dialog[vn-id="denyReason"] {
|
||||
button.close {
|
||||
display: none
|
||||
}
|
||||
& vn-button {
|
||||
margin: 0 auto
|
||||
}
|
||||
|
||||
vn-textarea {
|
||||
width: 100%
|
||||
}
|
||||
}
|
||||
|
||||
vn-textarea {
|
||||
width: 100%
|
||||
vn-icon[icon=insert_drive_file]{
|
||||
color: $color-font-secondary;
|
||||
}
|
||||
}
|
|
@ -111,7 +111,7 @@ module.exports = Self => {
|
|||
FROM tmp.ticketCalculateItem tci
|
||||
JOIN vn.item i ON i.id = tci.itemFk
|
||||
JOIN vn.itemType it ON it.id = i.typeFk
|
||||
JOIN vn.ink ON ink.id = i.inkFk
|
||||
LEFT JOIN vn.ink ON ink.id = i.inkFk
|
||||
JOIN vn.worker w on w.id = it.workerFk`);
|
||||
|
||||
// Apply order by tag
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
Routes: Rutas
|
||||
Search routes by id: Buscar rutas por identificador
|
||||
Search routes by id: Buscar rutas por identificador
|
||||
New route: Nueva ruta
|
|
@ -27,12 +27,12 @@ module.exports = Self => {
|
|||
let newTicketData = {};
|
||||
let receiverTicket = params.receiverTicket;
|
||||
|
||||
let isCurrentTicketEditable = await models.Ticket.isEditable(params.currentTicket.currentTicketId);
|
||||
let isCurrentTicketEditable = await models.Ticket.isEditable(ctx, params.currentTicket.currentTicketId);
|
||||
if (!isCurrentTicketEditable)
|
||||
throw new UserError(`The sales of the current ticket can't be modified`);
|
||||
|
||||
if (params.receiverTicket.id) {
|
||||
let isReceiverTicketEditable = await models.Ticket.isEditable(params.receiverTicket.id);
|
||||
let isReceiverTicketEditable = await models.Ticket.isEditable(ctx, params.receiverTicket.id);
|
||||
if (!isReceiverTicketEditable)
|
||||
throw new UserError(`The sales of the receiver ticket can't be modified`);
|
||||
}
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
const UserError = require('vn-loopback/util/user-error');
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethod('priceDifference', {
|
||||
description: 'Returns sales with price difference if the ticket is editable',
|
||||
accessType: 'READ',
|
||||
accepts: [{
|
||||
arg: 'ticketFk',
|
||||
type: 'number',
|
||||
required: true,
|
||||
description: 'ticket id',
|
||||
http: {source: 'path'}
|
||||
}, {
|
||||
arg: 'data',
|
||||
type: 'Object',
|
||||
required: true,
|
||||
description: 'landed, addressFk, agencyModeFk',
|
||||
http: {source: 'body'}
|
||||
}],
|
||||
returns: {
|
||||
type: ['Object'],
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/:ticketFk/priceDifference`,
|
||||
verb: 'post'
|
||||
}
|
||||
});
|
||||
|
||||
Self.priceDifference = async(ticketFk, data) => {
|
||||
let thisTicketIsEditable = await Self.app.models.Ticket.isEditable(ticketFk);
|
||||
if (!thisTicketIsEditable)
|
||||
throw new UserError(`The sales of this ticket can't be modified`);
|
||||
|
||||
let filter = {
|
||||
where: {
|
||||
ticketFk: ticketFk
|
||||
},
|
||||
order: 'concept ASC',
|
||||
include: [{
|
||||
relation: 'item'
|
||||
}]
|
||||
};
|
||||
let salesObj = {};
|
||||
salesObj.items = await Self.find(filter);
|
||||
salesObj.totalUnitPrice = 0.00;
|
||||
salesObj.totalNewPrice = 0.00;
|
||||
salesObj.totalDifference = 0.00;
|
||||
|
||||
let query = `CALL vn.ticketComponentPriceDifference(?, ?, ?, ?, ?)`;
|
||||
let [differences] = await Self.rawSql(query, [
|
||||
ticketFk,
|
||||
data.landed,
|
||||
data.addressFk,
|
||||
data.agencyModeFk,
|
||||
data.warehouseFk
|
||||
]);
|
||||
|
||||
salesObj.items.forEach(sale => {
|
||||
differences.forEach(difference => {
|
||||
if (sale.id == difference.saleFk)
|
||||
sale.component = difference;
|
||||
});
|
||||
|
||||
salesObj.totalUnitPrice += sale.price;
|
||||
salesObj.totalNewPrice += sale.component.newPrice;
|
||||
salesObj.totalDifference += sale.component.difference;
|
||||
salesObj.totalUnitPrice = Math.round(salesObj.totalUnitPrice * 100) / 100;
|
||||
salesObj.totalNewPrice = Math.round(salesObj.totalNewPrice * 100) / 100;
|
||||
salesObj.totalDifference = Math.round(salesObj.totalDifference * 100) / 100;
|
||||
});
|
||||
|
||||
return salesObj;
|
||||
};
|
||||
};
|
|
@ -1,7 +1,7 @@
|
|||
let UserError = require('vn-loopback/util/user-error');
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethod('removes', {
|
||||
Self.remoteMethodCtx('removes', {
|
||||
description: 'Change the state of a ticket',
|
||||
accessType: 'WRITE',
|
||||
accepts: [{
|
||||
|
@ -21,8 +21,8 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.removes = async params => {
|
||||
let thisTicketIsEditable = await Self.app.models.Ticket.isEditable(params.actualTicketFk);
|
||||
Self.removes = async(ctx, params) => {
|
||||
let thisTicketIsEditable = await Self.app.models.Ticket.isEditable(ctx, params.actualTicketFk);
|
||||
if (!thisTicketIsEditable)
|
||||
throw new UserError(`The sales of this ticket can't be modified`);
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
let UserError = require('vn-loopback/util/user-error');
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethod('reserve', {
|
||||
Self.remoteMethodCtx('reserve', {
|
||||
description: 'Change the state of a ticket',
|
||||
accessType: 'WRITE',
|
||||
accepts: [{
|
||||
|
@ -22,8 +22,8 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.reserve = async params => {
|
||||
let thisTicketIsEditable = await Self.app.models.Ticket.isEditable(params.ticketFk);
|
||||
Self.reserve = async(ctx, params) => {
|
||||
let thisTicketIsEditable = await Self.app.models.Ticket.isEditable(ctx, params.ticketFk);
|
||||
if (!thisTicketIsEditable)
|
||||
throw new UserError(`The sales of this ticket can't be modified`);
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ describe('sale removes()', () => {
|
|||
});
|
||||
|
||||
it('should throw an error if the ticket of the given sales is not editable', async() => {
|
||||
let ctx = {req: {accessToken: {userId: 9}}};
|
||||
let error;
|
||||
|
||||
let params = {
|
||||
|
@ -21,7 +22,7 @@ describe('sale removes()', () => {
|
|||
};
|
||||
|
||||
try {
|
||||
await app.models.Sale.removes(params);
|
||||
await app.models.Sale.removes(ctx, params);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
|
@ -30,12 +31,13 @@ describe('sale removes()', () => {
|
|||
});
|
||||
|
||||
it('should delete the sales', async() => {
|
||||
let ctx = {req: {accessToken: {userId: 9}}};
|
||||
let params = {
|
||||
sales: [{id: newsale.id, instance: 0}],
|
||||
actualTicketFk: 16
|
||||
};
|
||||
|
||||
let res = await app.models.Sale.removes(params);
|
||||
let res = await app.models.Sale.removes(ctx, params);
|
||||
|
||||
expect(res).toEqual([{count: 1}]);
|
||||
});
|
||||
|
|
|
@ -2,6 +2,7 @@ const app = require('vn-loopback/server/server');
|
|||
|
||||
describe('sale reserve()', () => {
|
||||
afterAll(async done => {
|
||||
let ctx = {req: {accessToken: {userId: 9}}};
|
||||
let params = {
|
||||
sales: [
|
||||
{id: 7},
|
||||
|
@ -10,18 +11,19 @@ describe('sale reserve()', () => {
|
|||
reserved: false
|
||||
};
|
||||
|
||||
await app.models.Sale.reserve(params);
|
||||
await app.models.Sale.reserve(ctx, params);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should throw an error if the ticket can not be modified', async() => {
|
||||
let ctx = {req: {accessToken: {userId: 9}}};
|
||||
let error;
|
||||
let params = {ticketFk: 2,
|
||||
sales: [{id: 5}],
|
||||
reserved: false};
|
||||
|
||||
await app.models.Sale.reserve(params)
|
||||
await app.models.Sale.reserve(ctx, params)
|
||||
.catch(response => {
|
||||
expect(response).toEqual(new Error(`The sales of this ticket can't be modified`));
|
||||
error = response;
|
||||
|
@ -36,6 +38,7 @@ describe('sale reserve()', () => {
|
|||
expect(originalTicketSales[0].reserved).toEqual(0);
|
||||
expect(originalTicketSales[1].reserved).toEqual(0);
|
||||
|
||||
let ctx = {req: {accessToken: {userId: 9}}};
|
||||
let params = {
|
||||
sales: [
|
||||
{id: 7},
|
||||
|
@ -44,7 +47,7 @@ describe('sale reserve()', () => {
|
|||
reserved: true
|
||||
};
|
||||
|
||||
await app.models.Sale.reserve(params);
|
||||
await app.models.Sale.reserve(ctx, params);
|
||||
|
||||
let reservedTicketSales = await app.models.Ticket.getSales(11);
|
||||
|
||||
|
|
|
@ -26,10 +26,11 @@ describe('sale updatePrice()', () => {
|
|||
|
||||
|
||||
it('should throw an error if the ticket is not editable', async() => {
|
||||
let ctx = {req: {accessToken: {userId: 9}}};
|
||||
let immutableSaleId = 1;
|
||||
let price = 5;
|
||||
|
||||
await app.models.Sale.updatePrice(immutableSaleId, price)
|
||||
await app.models.Sale.updatePrice(ctx, immutableSaleId, price)
|
||||
.catch(response => {
|
||||
expect(response).toEqual(new Error(`The sales of this ticket can't be modified`));
|
||||
error = response;
|
||||
|
@ -39,27 +40,30 @@ describe('sale updatePrice()', () => {
|
|||
});
|
||||
|
||||
it('should return 0 if the price is an empty string', async() => {
|
||||
let ctx = {req: {accessToken: {userId: 9}}};
|
||||
let price = '';
|
||||
|
||||
await app.models.Sale.updatePrice(saleId, price);
|
||||
await app.models.Sale.updatePrice(ctx, saleId, price);
|
||||
let saleUpdated = await app.models.Sale.findById(saleId);
|
||||
|
||||
expect(saleUpdated.price).toEqual(0);
|
||||
});
|
||||
|
||||
it('should now set price as a decimal number in a string', async() => {
|
||||
let ctx = {req: {accessToken: {userId: 9}}};
|
||||
let price = '8';
|
||||
|
||||
await app.models.Sale.updatePrice(saleId, price);
|
||||
await app.models.Sale.updatePrice(ctx, saleId, price);
|
||||
let saleUpdated = await app.models.Sale.findById(saleId);
|
||||
|
||||
expect(saleUpdated.price).toEqual(8);
|
||||
});
|
||||
|
||||
it('should set price as a decimal number and check the sale has the mana component', async() => {
|
||||
let ctx = {req: {accessToken: {userId: 9}}};
|
||||
let price = 5.3;
|
||||
|
||||
await app.models.Sale.updatePrice(saleId, price);
|
||||
await app.models.Sale.updatePrice(ctx, saleId, price);
|
||||
let saleUpdated = await app.models.Sale.findById(saleId);
|
||||
createdSaleComponent = await app.models.SaleComponent.findOne({where: {saleFk: saleId, componentFk: manaComponentId}});
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
let UserError = require('vn-loopback/util/user-error');
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethod('updatePrice', {
|
||||
Self.remoteMethodCtx('updatePrice', {
|
||||
description: 'Changes the price of a sale',
|
||||
accessType: 'WRITE',
|
||||
accepts: [
|
||||
|
@ -28,7 +28,7 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.updatePrice = async(id, newPrice) => {
|
||||
Self.updatePrice = async(ctx, id, newPrice) => {
|
||||
let models = Self.app.models;
|
||||
let tx = await Self.beginTransaction({});
|
||||
|
||||
|
@ -51,7 +51,7 @@ module.exports = Self => {
|
|||
};
|
||||
let sale = await models.Sale.findById(id, filter, options);
|
||||
|
||||
let isEditable = await models.Ticket.isEditable(sale.ticketFk);
|
||||
let isEditable = await models.Ticket.isEditable(ctx, sale.ticketFk);
|
||||
if (!isEditable)
|
||||
throw new UserError(`The sales of this ticket can't be modified`);
|
||||
|
||||
|
|
|
@ -13,12 +13,12 @@ module.exports = Self => {
|
|||
arg: 'itemFk',
|
||||
type: 'Integer',
|
||||
required: true,
|
||||
description: 'The request observation',
|
||||
description: 'The requested item ID',
|
||||
}, {
|
||||
arg: 'quantity',
|
||||
type: 'Integer',
|
||||
required: true,
|
||||
description: 'The request observation',
|
||||
description: 'The requested item quantity',
|
||||
}],
|
||||
returns: {
|
||||
type: 'Object',
|
||||
|
@ -32,6 +32,7 @@ module.exports = Self => {
|
|||
|
||||
Self.confirm = async ctx => {
|
||||
const models = Self.app.models;
|
||||
let sale;
|
||||
let tx = await Self.beginTransaction({});
|
||||
|
||||
try {
|
||||
|
@ -52,32 +53,32 @@ module.exports = Self => {
|
|||
false
|
||||
]);
|
||||
|
||||
if (stock.available < quantity)
|
||||
if (stock.available < ctx.args.quantity)
|
||||
throw new UserError(`This item is not available`);
|
||||
|
||||
|
||||
if (request.saleFk) {
|
||||
let sale = await models.Sale.findById(request.saleFk);
|
||||
sale = await models.Sale.findById(request.saleFk);
|
||||
sale.updateAttributes({
|
||||
itemFk: ctx.args.itemFk,
|
||||
quantity: ctx.args.quantity,
|
||||
description: item.description
|
||||
concept: item.name,
|
||||
}, options);
|
||||
} else {
|
||||
params = {
|
||||
sale = await models.Sale.create({
|
||||
ticketFk: request.ticketFk,
|
||||
itemFk: ctx.args.itemFk,
|
||||
quantity: ctx.args.quantity
|
||||
};
|
||||
sale = await models.Sale.create(params, options);
|
||||
request.updateAttributes({saleFk: sale.id, itemFk: sale.itemFk}, options);
|
||||
quantity: ctx.args.quantity,
|
||||
concept: item.name
|
||||
}, options);
|
||||
request.updateAttributes({saleFk: sale.id, itemFk: sale.itemFk, isOk: true}, options);
|
||||
}
|
||||
|
||||
query = `CALL vn.ticketCalculateSale(?)`;
|
||||
params = [sale.id];
|
||||
await Self.rawSql(query, params, options);
|
||||
await Self.rawSql(query, [sale.id], options);
|
||||
|
||||
const message = `Se ha comprado ${params.quantity} unidades de "${item.description}" (#${params.itemFk}) `
|
||||
+ `para el ticket #${params.ticketFk}`;
|
||||
const message = `Se ha comprado ${sale.quantity} unidades de "${sale.concept}" (#${sale.itemFk}) `
|
||||
+ `para el ticket #${sale.ticketFk}`;
|
||||
|
||||
await models.Message.send(ctx, {
|
||||
recipientFk: request.requesterFk,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('deny', {
|
||||
description: 'Create a newticket and returns the new ID',
|
||||
description: 'sets a ticket request to denied and returns the changes',
|
||||
accessType: 'WRITE',
|
||||
accepts: [{
|
||||
arg: 'id',
|
||||
|
@ -30,7 +30,7 @@ module.exports = Self => {
|
|||
let params = {
|
||||
isOk: false,
|
||||
atenderFk: worker.id,
|
||||
observation: ctx.args.observation,
|
||||
response: ctx.args.observation,
|
||||
};
|
||||
|
||||
let request = await Self.app.models.TicketRequest.findById(ctx.args.id);
|
||||
|
|
|
@ -71,7 +71,7 @@ module.exports = Self => {
|
|||
switch (param) {
|
||||
case 'search':
|
||||
return /^\d+$/.test(value)
|
||||
? {'t.ticketFk': {inq: value}}
|
||||
? {'tr.ticketFk': {inq: value}}
|
||||
: {'t.nickname': {like: `%${value}%`}};
|
||||
case 'ticketFk':
|
||||
return {'t.id': value};
|
||||
|
@ -92,41 +92,47 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
if (!where)
|
||||
where = {};
|
||||
where['tw.ticketFk'] = null;
|
||||
|
||||
filter = mergeFilters(filter, {where});
|
||||
|
||||
let stmt;
|
||||
|
||||
stmt = new ParameterizedSQL(
|
||||
`SELECT
|
||||
tr.id,
|
||||
tr.ticketFk,
|
||||
tr.quantity,
|
||||
tr.price,
|
||||
tr.atenderFk,
|
||||
tr.description,
|
||||
tr.itemFk,
|
||||
tr.saleFk,
|
||||
tr.isOk,
|
||||
s.quantity AS saleQuantity,
|
||||
i.description AS itemDescription,
|
||||
t.shipped,
|
||||
t.nickname,
|
||||
t.warehouseFk,
|
||||
t.clientFk,
|
||||
w.name AS warehouse,
|
||||
u.nickname AS salesPersonNickname,
|
||||
ua.nickname AS atenderNickname,
|
||||
c.salesPersonFk
|
||||
FROM ticketRequest tr
|
||||
LEFT JOIN ticket t ON t.id = tr.ticketFk
|
||||
LEFT JOIN warehouse w ON w.id = t.warehouseFk
|
||||
LEFT JOIN client c ON c.id = t.clientFk
|
||||
LEFT JOIN item i ON i.id = tr.itemFk
|
||||
LEFT JOIN sale s ON s.id = tr.saleFk
|
||||
LEFT JOIN worker wk ON wk.id = c.salesPersonFk
|
||||
LEFT JOIN account.user u ON u.id = wk.userFk
|
||||
LEFT JOIN worker wka ON wka.id = tr.atenderFk
|
||||
LEFT JOIN account.user ua ON ua.id = wka.userFk`);
|
||||
tr.id,
|
||||
tr.ticketFk,
|
||||
tr.quantity,
|
||||
tr.price,
|
||||
tr.atenderFk,
|
||||
tr.description,
|
||||
tr.response,
|
||||
tr.saleFk,
|
||||
tr.isOk,
|
||||
s.quantity AS saleQuantity,
|
||||
s.itemFK,
|
||||
i.name AS itemDescription,
|
||||
t.shipped,
|
||||
t.nickname,
|
||||
t.warehouseFk,
|
||||
t.clientFk,
|
||||
w.name AS warehouse,
|
||||
u.nickname AS salesPersonNickname,
|
||||
ua.nickname AS atenderNickname,
|
||||
c.salesPersonFk
|
||||
FROM ticketRequest tr
|
||||
LEFT JOIN ticketWeekly tw on tw.ticketFk = tr.ticketFk
|
||||
LEFT JOIN ticket t ON t.id = tr.ticketFk
|
||||
LEFT JOIN warehouse w ON w.id = t.warehouseFk
|
||||
LEFT JOIN client c ON c.id = t.clientFk
|
||||
LEFT JOIN item i ON i.id = tr.itemFk
|
||||
LEFT JOIN sale s ON s.id = tr.saleFk
|
||||
LEFT JOIN worker wk ON wk.id = c.salesPersonFk
|
||||
LEFT JOIN account.user u ON u.id = wk.userFk
|
||||
LEFT JOIN worker wka ON wka.id = tr.atenderFk
|
||||
LEFT JOIN account.user ua ON ua.id = wka.userFk`);
|
||||
stmt.merge(conn.makeSuffix(filter));
|
||||
|
||||
let result = await conn.executeStmt(stmt);
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
|
||||
describe('ticket-request confirm()', () => {
|
||||
let request;
|
||||
let sale;
|
||||
let createdSaleId;
|
||||
|
||||
afterAll(async done => {
|
||||
const paramsForRequest = {
|
||||
saleFk: request.saleFk,
|
||||
isOk: request.isOk,
|
||||
itemFk: request.itemFk,
|
||||
ticketFk: request.ticketFk
|
||||
};
|
||||
|
||||
const paramsForSale = {
|
||||
itemFk: sale.itemFk,
|
||||
quantity: sale.quantity,
|
||||
concept: sale.concept,
|
||||
};
|
||||
|
||||
await request.updateAttributes(paramsForRequest);
|
||||
await sale.updateAttributes(paramsForSale);
|
||||
app.models.Sale.destroyById(createdSaleId);
|
||||
done();
|
||||
});
|
||||
|
||||
it(`should throw an error if the item doesn't exist`, async() => {
|
||||
let ctx = {req: {accessToken: {userId: 9}}, args: {itemFk: 999}};
|
||||
let error;
|
||||
|
||||
try {
|
||||
await app.models.TicketRequest.confirm(ctx);
|
||||
} catch (err) {
|
||||
error = err;
|
||||
}
|
||||
|
||||
expect(error.message).toEqual(`That item doesn't exists`);
|
||||
});
|
||||
|
||||
it(`should throw an error if the item is not available`, async() => {
|
||||
const requestId = 4;
|
||||
const itemId = 1;
|
||||
const quantity = 99999;
|
||||
|
||||
let ctx = {req: {accessToken: {userId: 9}}, args: {
|
||||
itemFk: itemId,
|
||||
id: requestId,
|
||||
quantity: quantity
|
||||
}};
|
||||
let error;
|
||||
|
||||
try {
|
||||
await app.models.TicketRequest.confirm(ctx);
|
||||
} catch (err) {
|
||||
error = err;
|
||||
}
|
||||
|
||||
expect(error.message).toEqual(`This item is not available`);
|
||||
});
|
||||
|
||||
it(`should update the sale details if the request already contains a sale id`, async() => {
|
||||
const requestId = 4;
|
||||
const saleId = 11;
|
||||
const itemId = 1;
|
||||
const quantity = 10;
|
||||
|
||||
request = await app.models.TicketRequest.findById(requestId);
|
||||
sale = await app.models.Sale.findById(saleId);
|
||||
|
||||
request.updateAttributes({saleFk: saleId});
|
||||
|
||||
let ctx = {req: {accessToken: {userId: 9}}, args: {
|
||||
itemFk: itemId,
|
||||
id: requestId,
|
||||
quantity: quantity
|
||||
}};
|
||||
|
||||
await app.models.TicketRequest.confirm(ctx);
|
||||
|
||||
let updatedSale = await app.models.Sale.findById(saleId);
|
||||
|
||||
expect(updatedSale.itemFk).toEqual(itemId);
|
||||
expect(updatedSale.quantity).toEqual(quantity);
|
||||
});
|
||||
|
||||
it(`should create a new sale for the the request if there's no sale id`, async() => {
|
||||
const requestId = 4;
|
||||
const itemId = 1;
|
||||
const quantity = 10;
|
||||
|
||||
request.updateAttributes({saleFk: null});
|
||||
|
||||
let ctx = {req: {accessToken: {userId: 9}}, args: {
|
||||
itemFk: itemId,
|
||||
id: requestId,
|
||||
quantity: quantity,
|
||||
ticketFk: 1
|
||||
}};
|
||||
|
||||
await app.models.TicketRequest.confirm(ctx);
|
||||
|
||||
let updatedRequest = await app.models.TicketRequest.findById(requestId);
|
||||
createdSaleId = updatedRequest.saleFk;
|
||||
|
||||
expect(updatedRequest.saleFk).toEqual(createdSaleId);
|
||||
expect(updatedRequest.isOk).toEqual(true);
|
||||
expect(updatedRequest.itemFk).toEqual(itemId);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,25 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
|
||||
describe('ticket-request deny()', () => {
|
||||
let request;
|
||||
afterAll(async done => {
|
||||
let params = {
|
||||
isOk: null,
|
||||
atenderFk: request.atenderFk,
|
||||
response: null,
|
||||
};
|
||||
|
||||
await request.updateAttributes(params);
|
||||
done();
|
||||
});
|
||||
|
||||
it('should return all ticket requests', async() => {
|
||||
let ctx = {req: {accessToken: {userId: 9}}, args: {id: 4, observation: 'my observation'}};
|
||||
|
||||
request = await app.models.TicketRequest.findById(ctx.args.id);
|
||||
|
||||
let result = await app.models.TicketRequest.deny(ctx);
|
||||
|
||||
expect(result.id).toEqual(4);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,83 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
|
||||
describe('ticket-request filter()', () => {
|
||||
it('should return all ticket requests', async() => {
|
||||
let ctx = {req: {accessToken: {userId: 9}}, args: {}};
|
||||
|
||||
let result = await app.models.TicketRequest.filter(ctx);
|
||||
|
||||
expect(result.length).toEqual(1);
|
||||
});
|
||||
|
||||
it('should return the ticket request matching a generic search value which is the ticket ID', async() => {
|
||||
let ctx = {req: {accessToken: {userId: 9}}, args: {search: 11}};
|
||||
|
||||
let result = await app.models.TicketRequest.filter(ctx);
|
||||
let requestId = result[0].id;
|
||||
|
||||
expect(requestId).toEqual(4);
|
||||
});
|
||||
|
||||
it('should return the ticket request matching a generic search value which is the client address alias', async() => {
|
||||
let ctx = {req: {accessToken: {userId: 9}}, args: {search: 'NY roofs'}};
|
||||
|
||||
let result = await app.models.TicketRequest.filter(ctx);
|
||||
let requestId = result[0].id;
|
||||
|
||||
expect(requestId).toEqual(4);
|
||||
});
|
||||
|
||||
it('should return the ticket request matching the ticket ID', async() => {
|
||||
let ctx = {req: {accessToken: {userId: 9}}, args: {ticketFk: 11}};
|
||||
|
||||
let result = await app.models.TicketRequest.filter(ctx);
|
||||
let requestId = result[0].id;
|
||||
|
||||
expect(requestId).toEqual(4);
|
||||
});
|
||||
|
||||
it('should return the ticket request matching the atender ID', async() => {
|
||||
let ctx = {req: {accessToken: {userId: 9}}, args: {atenderFk: 35}};
|
||||
|
||||
let result = await app.models.TicketRequest.filter(ctx);
|
||||
let requestId = result[0].id;
|
||||
|
||||
expect(requestId).toEqual(4);
|
||||
});
|
||||
|
||||
it('should return the ticket request matching the isOk triple-state', async() => {
|
||||
let ctx = {req: {accessToken: {userId: 9}}, args: {isOk: null}};
|
||||
|
||||
let result = await app.models.TicketRequest.filter(ctx);
|
||||
let requestId = result[0].id;
|
||||
|
||||
expect(requestId).toEqual(4);
|
||||
});
|
||||
|
||||
it('should return the ticket request matching the client ID', async() => {
|
||||
let ctx = {req: {accessToken: {userId: 9}}, args: {clientFk: 102}};
|
||||
|
||||
let result = await app.models.TicketRequest.filter(ctx);
|
||||
let requestId = result[0].id;
|
||||
|
||||
expect(requestId).toEqual(4);
|
||||
});
|
||||
|
||||
it('should return the ticket request matching the warehouse ID', async() => {
|
||||
let ctx = {req: {accessToken: {userId: 9}}, args: {warehouse: 1}};
|
||||
|
||||
let result = await app.models.TicketRequest.filter(ctx);
|
||||
let requestId = result[0].id;
|
||||
|
||||
expect(requestId).toEqual(4);
|
||||
});
|
||||
|
||||
it('should return the ticket request matching the salesPerson ID', async() => {
|
||||
let ctx = {req: {accessToken: {userId: 9}}, args: {salesPersonFk: 18}};
|
||||
|
||||
let result = await app.models.TicketRequest.filter(ctx);
|
||||
let requestId = result[0].id;
|
||||
|
||||
expect(requestId).toEqual(4);
|
||||
});
|
||||
});
|
|
@ -2,7 +2,7 @@
|
|||
const UserError = require('vn-loopback/util/user-error');
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethod('addSale', {
|
||||
Self.remoteMethodCtx('addSale', {
|
||||
description: 'Inserts a new sale for the current ticket',
|
||||
accessType: 'WRITE',
|
||||
accepts: [{
|
||||
|
@ -32,10 +32,10 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.addSale = async(id, itemId, quantity) => {
|
||||
Self.addSale = async(ctx, id, itemId, quantity) => {
|
||||
const models = Self.app.models;
|
||||
|
||||
const isEditable = await models.Ticket.isEditable(id);
|
||||
const isEditable = await models.Ticket.isEditable(ctx, id);
|
||||
if (!isEditable)
|
||||
throw new UserError(`The sales of this ticket can't be modified`);
|
||||
|
||||
|
|
|
@ -1,56 +1,116 @@
|
|||
const UserError = require('vn-loopback/util/user-error');
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethod('componentUpdate', {
|
||||
Self.remoteMethodCtx('componentUpdate', {
|
||||
description: 'Save ticket sale components',
|
||||
accessType: 'WRITE',
|
||||
accepts: [{
|
||||
arg: 'ticketFk',
|
||||
type: 'number',
|
||||
arg: 'id',
|
||||
type: 'Number',
|
||||
required: true,
|
||||
description: 'ticket id',
|
||||
description: 'The ticket id',
|
||||
http: {source: 'path'}
|
||||
}, {
|
||||
arg: 'data',
|
||||
type: 'Object',
|
||||
required: true,
|
||||
description: 'landed, addressFk, agencyModeFk, warehouseFk',
|
||||
http: {source: 'body'}
|
||||
arg: 'clientId',
|
||||
type: 'Number',
|
||||
description: 'The client id',
|
||||
required: true
|
||||
}, {
|
||||
arg: 'context',
|
||||
type: 'object',
|
||||
http: function(ctx) {
|
||||
return ctx;
|
||||
}
|
||||
arg: 'agencyModeId',
|
||||
type: 'Number',
|
||||
description: 'The agencyMode id',
|
||||
required: true
|
||||
}, {
|
||||
arg: 'addressId',
|
||||
type: 'Number',
|
||||
description: 'The address id',
|
||||
required: true
|
||||
}, {
|
||||
arg: 'zoneId',
|
||||
type: 'Number',
|
||||
description: 'The zone id',
|
||||
required: true
|
||||
}, {
|
||||
arg: 'warehouseId',
|
||||
type: 'Number',
|
||||
description: 'The warehouse id',
|
||||
required: true
|
||||
}, {
|
||||
arg: 'companyId',
|
||||
type: 'Number',
|
||||
description: 'The company id',
|
||||
required: true
|
||||
}, {
|
||||
arg: 'shipped',
|
||||
type: 'Date',
|
||||
description: 'The shipped date',
|
||||
required: true
|
||||
}, {
|
||||
arg: 'landed',
|
||||
type: 'Date',
|
||||
description: 'The landing date',
|
||||
required: true
|
||||
}, {
|
||||
arg: 'isDeleted',
|
||||
type: 'Boolean',
|
||||
description: 'Ticket is deleted',
|
||||
required: true
|
||||
}, {
|
||||
arg: 'hasToBeUnrouted',
|
||||
type: 'Boolean',
|
||||
description: 'Ticket should be removed from ticket',
|
||||
required: true
|
||||
}, {
|
||||
arg: 'option',
|
||||
type: 'Number',
|
||||
description: 'Action id',
|
||||
required: true
|
||||
}],
|
||||
returns: {
|
||||
type: ['Object'],
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/:ticketFk/componentUpdate`,
|
||||
path: `/:id/componentUpdate`,
|
||||
verb: 'post'
|
||||
}
|
||||
});
|
||||
|
||||
Self.componentUpdate = async(ticketFk, data, ctx) => {
|
||||
let userId = ctx.req.accessToken.userId;
|
||||
let hasDeliveryRole = await Self.app.models.Account.hasRole(userId, 'delivery');
|
||||
Self.componentUpdate = async(ctx, id, clientId, agencyModeId, addressId, zoneId, warehouseId,
|
||||
companyId, shipped, landed, isDeleted, hasToBeUnrouted, option) => {
|
||||
const userId = ctx.req.accessToken.userId;
|
||||
const models = Self.app.models;
|
||||
const isEditable = await models.Ticket.isEditable(ctx, id);
|
||||
|
||||
if (!isEditable)
|
||||
throw new UserError(`The sales of this ticket can't be modified`);
|
||||
|
||||
const hasDeliveryRole = await models.Account.hasRole(userId, 'delivery');
|
||||
if (!hasDeliveryRole)
|
||||
data.hasToBeUnrouted = true;
|
||||
hasToBeUnrouted = true;
|
||||
|
||||
let query = 'CALL vn.ticketComponentMakeUpdate(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
|
||||
const isProductionBoss = await models.Account.hasRole(userId, 'productionBoss');
|
||||
if (!isProductionBoss) {
|
||||
const zone = await models.Agency.getShipped(landed, addressId, agencyModeId, warehouseId);
|
||||
|
||||
if (zone.id != zoneId)
|
||||
throw new UserError(`You don't have privileges to change the zone`);
|
||||
}
|
||||
|
||||
let query = 'CALL vn.ticket_componentMakeUpdate(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
|
||||
let res = await Self.rawSql(query, [
|
||||
ticketFk,
|
||||
data.clientFk,
|
||||
data.agencyModeFk,
|
||||
data.addressFk,
|
||||
data.warehouseFk,
|
||||
data.companyFk,
|
||||
data.shipped,
|
||||
data.landed,
|
||||
data.isDeleted,
|
||||
data.hasToBeUnrouted,
|
||||
data.option
|
||||
id,
|
||||
clientId,
|
||||
agencyModeId,
|
||||
addressId,
|
||||
zoneId,
|
||||
warehouseId,
|
||||
companyId,
|
||||
shipped,
|
||||
landed,
|
||||
isDeleted,
|
||||
hasToBeUnrouted,
|
||||
option
|
||||
]);
|
||||
return res;
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
module.exports = Self => {
|
||||
Self.remoteMethod('isEditable', {
|
||||
Self.remoteMethodCtx('isEditable', {
|
||||
description: 'Check if a ticket is editable',
|
||||
accessType: 'READ',
|
||||
accepts: [{
|
||||
|
@ -19,10 +19,13 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.isEditable = async ticketFk => {
|
||||
Self.isEditable = async(ctx, ticketFk) => {
|
||||
const accessToken = ctx.req.accessToken;
|
||||
const userId = accessToken.userId;
|
||||
let state = await Self.app.models.TicketState.findOne({
|
||||
where: {ticketFk: ticketFk}
|
||||
});
|
||||
let isProductionBoss = await Self.app.models.Account.hasRole(userId, 'productionBoss');
|
||||
let alertLevel = state ? state.alertLevel : null;
|
||||
let ticket = await Self.app.models.Ticket.findById(ticketFk, {
|
||||
fields: ['isDeleted', 'clientFk', 'refFk'],
|
||||
|
@ -41,7 +44,7 @@ module.exports = Self => {
|
|||
const isNotNormalClient = ticket && ticket.client().type().code == 'normal';
|
||||
const isInvoiced = ticket && ticket.refFk;
|
||||
|
||||
if (!ticket || ((isDeleted || isOnDelivery) && isNotNormalClient) || isInvoiced)
|
||||
if (!ticket || (isOnDelivery && isNotNormalClient && !isProductionBoss) || isInvoiced || isDeleted)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
const UserError = require('vn-loopback/util/user-error');
|
||||
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
||||
|
||||
module.exports = function(Self) {
|
||||
Self.remoteMethodCtx('makeInvoice', {
|
||||
|
@ -25,6 +26,7 @@ module.exports = function(Self) {
|
|||
});
|
||||
|
||||
Self.makeInvoice = async(ctx, id) => {
|
||||
const conn = Self.dataSource.connector;
|
||||
let userId = ctx.req.accessToken.userId;
|
||||
let models = Self.app.models;
|
||||
let tx = await Self.beginTransaction({});
|
||||
|
@ -48,29 +50,32 @@ module.exports = function(Self) {
|
|||
let [result] = await Self.rawSql(query, [ticket.clientFk, ticket.companyFk, 'R'], options);
|
||||
let serial = result.serial;
|
||||
|
||||
query = `CALL vn.invoiceFromTicket(?)`;
|
||||
await Self.rawSql(query, [ticket.id], options);
|
||||
let stmts = [];
|
||||
|
||||
result = await Self.rawSql(
|
||||
`CALL vn.invoiceOutMake(?, ?, @invoiceId);
|
||||
SELECT @invoiceId AS invoiceId;`,
|
||||
[serial, null],
|
||||
options
|
||||
);
|
||||
let invoice = result[1][0].invoiceId;
|
||||
stmt = new ParameterizedSQL('CALL vn.invoiceOut_newFromTicket(?, ?, ?, @invoiceId)', [
|
||||
ticket.id,
|
||||
serial,
|
||||
null
|
||||
]);
|
||||
stmts.push(stmt);
|
||||
|
||||
if (serial != 'R' && invoice) {
|
||||
let invoiceIndex = stmts.push(`SELECT @invoiceId AS invoiceId`) - 1;
|
||||
|
||||
let sql = ParameterizedSQL.join(stmts, ';');
|
||||
result = await conn.executeStmt(sql);
|
||||
let invoiceId = result[invoiceIndex][0].invoiceId;
|
||||
if (serial != 'R' && invoiceId) {
|
||||
query = `CALL vn.invoiceOutBooking(?)`;
|
||||
await Self.rawSql(query, [invoice], options);
|
||||
await Self.rawSql(query, [invoiceId], options);
|
||||
}
|
||||
|
||||
let user = await models.Worker.findOne({where: {userFk: userId}}, options);
|
||||
|
||||
query = `INSERT INTO printServerQueue(reportFk, param1, workerFk) VALUES (?, ?, ?)`;
|
||||
await Self.rawSql(query, [3, invoice, user.id], options);
|
||||
await Self.rawSql(query, [3, invoiceId, user.id], options);
|
||||
await tx.commit();
|
||||
|
||||
return {invoiceFk: invoice, serial};
|
||||
return {invoiceFk: invoiceId, serial};
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
|
|
|
@ -61,21 +61,14 @@ module.exports = Self => {
|
|||
|
||||
try {
|
||||
if (!params.shipped && params.landed) {
|
||||
params.shipped = await models.Agency.getShipped(ctx, {
|
||||
landed: params.landed,
|
||||
addressFk: address.id,
|
||||
agencyModeFk: params.agencyModeFk,
|
||||
warehouseFk: params.warehouseFk
|
||||
});
|
||||
const shippedResult = await models.Agency.getShipped(params.landed,
|
||||
address.id, params.agencyModeFk, params.warehouseFk);
|
||||
params.shipped = shippedResult.shipped;
|
||||
}
|
||||
|
||||
if (params.shipped && !params.landed) {
|
||||
const landedResult = await models.Agency.getLanded(ctx, {
|
||||
shipped: params.shipped,
|
||||
addressFk: address.id,
|
||||
agencyModeFk: params.agencyModeFk,
|
||||
warehouseFk: params.warehouseFk
|
||||
});
|
||||
const landedResult = await models.Agency.getLanded(params.shipped,
|
||||
address.id, params.agencyModeFk, params.warehouseFk);
|
||||
params.landed = landedResult.landed;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
const UserError = require('vn-loopback/util/user-error');
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('priceDifference', {
|
||||
description: 'Returns sales with price difference if the ticket is editable',
|
||||
accessType: 'READ',
|
||||
accepts: [{
|
||||
arg: 'id',
|
||||
type: 'Number',
|
||||
required: true,
|
||||
description: 'The ticket id',
|
||||
http: {source: 'path'}
|
||||
},
|
||||
{
|
||||
arg: 'landed',
|
||||
type: 'Date',
|
||||
description: 'The landing date',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
arg: 'addressId',
|
||||
type: 'Number',
|
||||
description: 'The address id',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
arg: 'agencyModeId',
|
||||
type: 'Number',
|
||||
description: 'The agencyMode id',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
arg: 'zoneId',
|
||||
type: 'Number',
|
||||
description: 'The zone id',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
arg: 'warehouseId',
|
||||
type: 'Number',
|
||||
description: 'The warehouse id',
|
||||
required: true
|
||||
}],
|
||||
returns: {
|
||||
type: ['Object'],
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/:id/priceDifference`,
|
||||
verb: 'POST'
|
||||
}
|
||||
});
|
||||
|
||||
Self.priceDifference = async(ctx, id, landed, addressId, agencyModeId, zoneId, warehouseId) => {
|
||||
const models = Self.app.models;
|
||||
const isEditable = await models.Ticket.isEditable(ctx, id);
|
||||
const userId = ctx.req.accessToken.userId;
|
||||
|
||||
if (!isEditable)
|
||||
throw new UserError(`The sales of this ticket can't be modified`);
|
||||
|
||||
const isProductionBoss = await models.Account.hasRole(userId, 'productionBoss');
|
||||
if (!isProductionBoss) {
|
||||
const zone = await models.Agency.getShipped(landed, addressId, agencyModeId, warehouseId);
|
||||
|
||||
if (zone.id != zoneId)
|
||||
throw new UserError(`You don't have privileges to change the zone`);
|
||||
}
|
||||
|
||||
let salesObj = {};
|
||||
salesObj.items = await models.Sale.find({
|
||||
where: {
|
||||
ticketFk: id
|
||||
},
|
||||
order: 'concept ASC',
|
||||
include: [{
|
||||
relation: 'item'
|
||||
}]
|
||||
});
|
||||
salesObj.totalUnitPrice = 0.00;
|
||||
salesObj.totalNewPrice = 0.00;
|
||||
salesObj.totalDifference = 0.00;
|
||||
|
||||
const query = `CALL vn.ticket_priceDifference(?, ?, ?, ?, ?)`;
|
||||
const args = [id, landed, addressId, zoneId, warehouseId];
|
||||
const [difComponents] = await Self.rawSql(query, args);
|
||||
|
||||
const map = new Map();
|
||||
|
||||
difComponents.forEach(difComponent => {
|
||||
map.set(difComponent.saleFk, difComponent);
|
||||
});
|
||||
|
||||
salesObj.items.forEach(sale => {
|
||||
const difComponent = map.get(sale.id);
|
||||
|
||||
if (difComponent)
|
||||
sale.component = difComponent;
|
||||
|
||||
salesObj.totalUnitPrice += sale.price;
|
||||
salesObj.totalNewPrice += sale.component.newPrice;
|
||||
salesObj.totalDifference += sale.component.difference;
|
||||
salesObj.totalUnitPrice = Math.round(salesObj.totalUnitPrice * 100) / 100;
|
||||
salesObj.totalNewPrice = Math.round(salesObj.totalNewPrice * 100) / 100;
|
||||
salesObj.totalDifference = Math.round(salesObj.totalDifference * 100) / 100;
|
||||
});
|
||||
|
||||
return salesObj;
|
||||
};
|
||||
};
|
|
@ -12,19 +12,21 @@ describe('ticket addSale()', () => {
|
|||
});
|
||||
|
||||
it('should create a new sale for the ticket with id 13', async() => {
|
||||
let ctx = {req: {accessToken: {userId: 9}}};
|
||||
const itemId = 4;
|
||||
const quantity = 10;
|
||||
newSale = await app.models.Ticket.addSale(ticketId, itemId, quantity);
|
||||
newSale = await app.models.Ticket.addSale(ctx, ticketId, itemId, quantity);
|
||||
|
||||
expect(newSale.itemFk).toEqual(4);
|
||||
});
|
||||
|
||||
it('should not be able to add a sale if the item quantity is not available', async() => {
|
||||
let ctx = {req: {accessToken: {userId: 9}}};
|
||||
const itemId = 11;
|
||||
const quantity = 10;
|
||||
|
||||
let error;
|
||||
await app.models.Ticket.addSale(ticketId, itemId, quantity).catch(e => {
|
||||
await app.models.Ticket.addSale(ctx, ticketId, itemId, quantity).catch(e => {
|
||||
error = e;
|
||||
}).finally(() => {
|
||||
expect(error.message).toEqual(`This item is not available`);
|
||||
|
@ -34,11 +36,12 @@ describe('ticket addSale()', () => {
|
|||
});
|
||||
|
||||
it('should not be able to add a sale if the ticket is not editable', async() => {
|
||||
let ctx = {req: {accessToken: {userId: 9}}};
|
||||
const notEditableTicketId = 1;
|
||||
const itemId = 4;
|
||||
const quantity = 10;
|
||||
let error;
|
||||
await app.models.Ticket.addSale(notEditableTicketId, itemId, quantity).catch(e => {
|
||||
await app.models.Ticket.addSale(ctx, notEditableTicketId, itemId, quantity).catch(e => {
|
||||
error = e;
|
||||
}).finally(() => {
|
||||
expect(error.message).toEqual(`The sales of this ticket can't be modified`);
|
||||
|
|
|
@ -28,22 +28,22 @@ describe('ticket componentUpdate()', () => {
|
|||
});
|
||||
|
||||
it('should change the agencyMode to modify the sale components value', async() => {
|
||||
let data = {
|
||||
clientFk: 102,
|
||||
agencyModeFk: 8,
|
||||
addressFk: 122,
|
||||
warehouseFk: 1,
|
||||
companyFk: 442,
|
||||
shipped: today,
|
||||
landed: tomorrow,
|
||||
isDeleted: false,
|
||||
hasToBeUnrouted: false,
|
||||
option: 1
|
||||
};
|
||||
const clientId = 102;
|
||||
const addressId = 122;
|
||||
const agencyModeId = 8;
|
||||
const warehouseId = 1;
|
||||
const zoneId = 5;
|
||||
const shipped = today;
|
||||
const companyId = 442;
|
||||
const isDeleted = false;
|
||||
const landed = tomorrow;
|
||||
const hasToBeUnrouted = false;
|
||||
const option = 1;
|
||||
|
||||
let ctx = {req: {accessToken: {userId: 101}}};
|
||||
|
||||
await app.models.Ticket.componentUpdate(ticketId, data, ctx);
|
||||
await app.models.Ticket.componentUpdate(ctx, ticketId, clientId, agencyModeId, addressId,
|
||||
zoneId, warehouseId, companyId, shipped, landed, isDeleted, hasToBeUnrouted, option);
|
||||
|
||||
[componentValue] = await app.models.SaleComponent.rawSql(componentOfSaleSeven);
|
||||
let firstvalueAfterChange = componentValue.value;
|
||||
|
@ -56,21 +56,21 @@ describe('ticket componentUpdate()', () => {
|
|||
});
|
||||
|
||||
it('should change the agencyMode to go back to the originals sale components value', async() => {
|
||||
let data = {
|
||||
clientFk: 102,
|
||||
agencyModeFk: 7,
|
||||
addressFk: 122,
|
||||
warehouseFk: 1,
|
||||
companyFk: 442,
|
||||
shipped: today,
|
||||
landed: tomorrow,
|
||||
isDeleted: false,
|
||||
hasToBeUnrouted: false,
|
||||
option: 1
|
||||
};
|
||||
const clientId = 102;
|
||||
const addressId = 122;
|
||||
const agencyModeId = 7;
|
||||
const warehouseId = 1;
|
||||
const zoneId = 3;
|
||||
const shipped = today;
|
||||
const companyId = 442;
|
||||
const isDeleted = false;
|
||||
const landed = tomorrow;
|
||||
const hasToBeUnrouted = false;
|
||||
const option = 1;
|
||||
|
||||
let ctx = {req: {accessToken: {userId: 101}}};
|
||||
await app.models.Ticket.componentUpdate(ticketId, data, ctx);
|
||||
await app.models.Ticket.componentUpdate(ctx, ticketId, clientId, agencyModeId, addressId,
|
||||
zoneId, warehouseId, companyId, shipped, landed, isDeleted, hasToBeUnrouted, option);
|
||||
|
||||
[componentValue] = await app.models.SaleComponent.rawSql(componentOfSaleSeven);
|
||||
let firstvalueAfterChange = componentValue.value;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue