refactor: refs #6802 refactor salesPerson to salesDepartment

This commit is contained in:
Carlos Andrés 2024-07-11 12:30:43 +02:00
parent 3be67f963c
commit 3b5f88fd33
122 changed files with 658 additions and 1176 deletions

View File

@ -63,11 +63,11 @@ module.exports = Self => {
let observations = ticket.observaciones.split(' ');
for (let observation of observations) {
const salesPerson = ticket.salesPersonFk;
const salesDepartment = ticket.salesDepartmentFk;
if (observation.startsWith('#') || observation.startsWith('@')) {
await models.Chat.send(ctx,
observation,
$t('ticketCommercial', {ticket: ticket.ticketFk, salesPerson})
$t('ticketCommercial', {ticket: ticket.ticketFk, salesDepartment})
);
}
}

View File

@ -92,7 +92,7 @@ module.exports = Self => {
$t('The ticket is in preparation', {
ticketId: ticketId,
ticketUrl: `${url}ticket/${ticketId}/summary`,
salesPersonId: ticket.salesPersonFk
salesDepartmentId: ticket.salesDepartmentFk
})));
}
}

View File

@ -1196,7 +1196,7 @@ INSERT INTO `ACL` VALUES (73,'Expedition','*','READ','ALLOW','ROLE','employee');
INSERT INTO `ACL` VALUES (74,'Expedition','*','WRITE','ALLOW','ROLE','deliveryAssistant');
INSERT INTO `ACL` VALUES (75,'Expedition','*','WRITE','ALLOW','ROLE','production');
INSERT INTO `ACL` VALUES (76,'AnnualAverageInvoiced','*','READ','ALLOW','ROLE','employee');
INSERT INTO `ACL` VALUES (77,'WorkerMana','*','READ','ALLOW','ROLE','employee');
INSERT INTO `ACL` VALUES (77,'DepartmentMana','*','READ','ALLOW','ROLE','employee');
INSERT INTO `ACL` VALUES (78,'TicketTracking','*','WRITE','ALLOW','ROLE','production');
INSERT INTO `ACL` VALUES (79,'Ticket','state','*','ALLOW','ROLE','employee');
INSERT INTO `ACL` VALUES (80,'Sale','deleteSales','*','ALLOW','ROLE','employee');
@ -1652,7 +1652,7 @@ INSERT INTO `ACL` VALUES (595,'Ticket','isEditable','READ','ALLOW','ROLE','emplo
INSERT INTO `ACL` VALUES (596,'Ticket','setDeleted','WRITE','ALLOW','ROLE','salesPerson');
INSERT INTO `ACL` VALUES (597,'Ticket','restore','WRITE','ALLOW','ROLE','employee');
INSERT INTO `ACL` VALUES (598,'Ticket','getSales','READ','ALLOW','ROLE','employee');
INSERT INTO `ACL` VALUES (599,'Ticket','getSalesPersonMana','READ','ALLOW','ROLE','employee');
INSERT INTO `ACL` VALUES (599,'Ticket','getSalesDepartmentMana','READ','ALLOW','ROLE','employee');
INSERT INTO `ACL` VALUES (600,'Ticket','filter','READ','ALLOW','ROLE','employee');
INSERT INTO `ACL` VALUES (601,'Ticket','makeInvoice','WRITE','ALLOW','ROLE','employee');
INSERT INTO `ACL` VALUES (602,'Ticket','updateEditableTicket','WRITE','ALLOW','ROLE','employee');

View File

@ -1699,7 +1699,6 @@ INSERT IGNORE INTO `procs_priv` VALUES ('','vn','marketingBoss','clientTaxArea'
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','administrative','clientTaxArea','FUNCTION','alexm@%','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','administrative','client_checkBalance','PROCEDURE','alexm@%','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','buyer','absoluteInventoryHistory','PROCEDURE','jenkins@db-proxy1.servers.dc.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','salesPerson','client_getSalesPersonByTicket','FUNCTION','alexm@%','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','pbx','developer','clientFromPhone','FUNCTION','juan@db-proxy1.servers.dc.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','util','production','log_addWithUser','PROCEDURE','juan@db-proxy2.servers.dc.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','adminBoss','balanceNestTree_addChild','PROCEDURE','jenkins@db-proxy1.servers.dc.verdnatura.es','Execute','0000-00-00 00:00:00');
@ -1714,7 +1713,6 @@ INSERT IGNORE INTO `procs_priv` VALUES ('','vn','claimManager','item_comparativ
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','entryEditor','item_getVolume','FUNCTION','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','employee','clientgetmana','FUNCTION','alexm@%','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','employee','buy_scan','PROCEDURE','alexm@%','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','buyer','client_getSalesPersonByTicket','FUNCTION','alexm@%','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','hr','client_create','PROCEDURE','guillermo@db-proxy2.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','entryEditor','entry_isintrastat','FUNCTION','guillermo@db-proxy2.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','manager','collection_make','PROCEDURE','alexm@%','Execute','0000-00-00 00:00:00');
@ -1946,7 +1944,6 @@ INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','itemtrash','PROCE
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','item_getbalance','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','expedition_checkroute','FUNCTION','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','addnotefromdelivery','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','employee','client_getSalesPerson','FUNCTION','guillermo@db-proxy2.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','buy_updatepacking','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','buy_updategrouping','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','srt','delivery','buffer_settypebyname','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');

View File

@ -995,27 +995,27 @@ DELIMITER ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `hedera`.`order_afterUpdate`
AFTER UPDATE ON `order`
FOR EACH ROW
BEGIN
CALL stock.log_add('order', NEW.id, OLD.id);
IF !(OLD.address_id <=> NEW.address_id)
OR !(OLD.company_id <=> NEW.company_id)
OR !(OLD.customer_id <=> NEW.customer_id) THEN
CALL order_requestRecalc(NEW.id);
END IF;
IF !(OLD.address_id <=> NEW.address_id) AND NEW.address_id = 2850 THEN
-- Fallo que se actualiza no se sabe como tickets en este cliente
CALL vn.mail_insert(
'jgallego@verdnatura.es',
'noreply@verdnatura.es',
'Actualizada order al address 2850',
CONCAT(account.myUser_getName(), ' ha creado la order ',NEW.id)
);
END IF;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `hedera`.`order_afterUpdate`
AFTER UPDATE ON `order`
FOR EACH ROW
BEGIN
CALL stock.log_add('order', NEW.id, OLD.id);
IF !(OLD.address_id <=> NEW.address_id)
OR !(OLD.company_id <=> NEW.company_id)
OR !(OLD.customer_id <=> NEW.customer_id) THEN
CALL order_requestRecalc(NEW.id);
END IF;
IF !(OLD.address_id <=> NEW.address_id) AND NEW.address_id = 2850 THEN
-- Fallo que se actualiza no se sabe como tickets en este cliente
CALL vn.mail_insert(
'jgallego@verdnatura.es',
'noreply@verdnatura.es',
'Actualizada order al address 2850',
CONCAT(account.myUser_getName(), ' ha creado la order ',NEW.id)
);
END IF;
END */;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
@ -2659,11 +2659,11 @@ DELIMITER ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`calendar_beforeUpdate`
BEFORE UPDATE ON `calendar`
FOR EACH ROW
BEGIN
SET NEW.editorFk = account.myUser_getId();
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`calendar_beforeUpdate`
BEFORE UPDATE ON `calendar`
FOR EACH ROW
BEGIN
SET NEW.editorFk = account.myUser_getId();
END */;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
@ -2679,15 +2679,15 @@ DELIMITER ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`calendar_afterDelete`
AFTER DELETE ON `calendar`
FOR EACH ROW
BEGIN
INSERT INTO workerLog
SET `action` = 'delete',
`changedModel` = 'Calendar',
`changedModelId` = OLD.id,
`userFk` = account.myUser_getId();
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`calendar_afterDelete`
AFTER DELETE ON `calendar`
FOR EACH ROW
BEGIN
INSERT INTO workerLog
SET `action` = 'delete',
`changedModel` = 'Calendar',
`changedModelId` = OLD.id,
`userFk` = account.myUser_getId();
END */;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
@ -2814,7 +2814,7 @@ BEGIN
INSERT INTO claimLog
SET `action` = 'delete',
`changedModel` = 'ClaimBeginning',
`changedModelId` = OLD.id,
`userFk` = account.myUser_getId();
END */;;
DELIMITER ;
@ -4498,31 +4498,31 @@ DELIMITER ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`dms_beforeUpdate`
BEFORE UPDATE ON `dms`
FOR EACH ROW
BEGIN
DECLARE vHardCopyNumber INT;
IF (NEW.hasFile <> 0) AND (OLD.hasFile = 0) AND (NEW.hardCopyNumber IS NULL)
OR
(NEW.hardCopyNumber = OLD.hardCopyNumber AND OLD.warehouseFk <> NEW.warehouseFk) THEN
IF (SELECT NOT hasDms FROM warehouse WHERE id = NEW.warehouseFk) THEN
SET NEW.warehouseFk = (SELECT id FROM warehouse WHERE name = 'Algemesi');
END IF;
SELECT 1 + MAX(hardCopyNumber) INTO vHardCopyNumber
FROM dms
WHERE warehouseFk = NEW.warehouseFk;
SET NEW.hardCopyNumber = IFNULL(vHardCopyNumber,1);
END IF;
IF ((NEW.hardCopyNumber = 0) OR NEW.hardCopyNumber IS NULL) AND (OLD.hardCopyNumber <> 0) THEN
SET NEW.hasFile = 0;
END IF;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`dms_beforeUpdate`
BEFORE UPDATE ON `dms`
FOR EACH ROW
BEGIN
DECLARE vHardCopyNumber INT;
IF (NEW.hasFile <> 0) AND (OLD.hasFile = 0) AND (NEW.hardCopyNumber IS NULL)
OR
(NEW.hardCopyNumber = OLD.hardCopyNumber AND OLD.warehouseFk <> NEW.warehouseFk) THEN
IF (SELECT NOT hasDms FROM warehouse WHERE id = NEW.warehouseFk) THEN
SET NEW.warehouseFk = (SELECT id FROM warehouse WHERE name = 'Algemesi');
END IF;
SELECT 1 + MAX(hardCopyNumber) INTO vHardCopyNumber
FROM dms
WHERE warehouseFk = NEW.warehouseFk;
SET NEW.hardCopyNumber = IFNULL(vHardCopyNumber,1);
END IF;
IF ((NEW.hardCopyNumber = 0) OR NEW.hardCopyNumber IS NULL) AND (OLD.hardCopyNumber <> 0) THEN
SET NEW.hasFile = 0;
END IF;
END */;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
@ -7277,19 +7277,19 @@ DELIMITER ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`province_afterUpdate`
AFTER UPDATE ON `province`
FOR EACH ROW
BEGIN
IF !(OLD.autonomyFk <=> NEW.autonomyFk) THEN
CALL zoneGeo_setParent(NEW.geoFk,
(SELECT geoFk FROM autonomy WHERE id = NEW.autonomyFk));
END IF;
IF !(OLD.`name` <=> NEW.`name`) THEN
UPDATE zoneGeo SET `name` = NEW.`name`
WHERE id = NEW.geoFk;
END IF;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`province_afterUpdate`
AFTER UPDATE ON `province`
FOR EACH ROW
BEGIN
IF !(OLD.autonomyFk <=> NEW.autonomyFk) THEN
CALL zoneGeo_setParent(NEW.geoFk,
(SELECT geoFk FROM autonomy WHERE id = NEW.autonomyFk));
END IF;
IF !(OLD.`name` <=> NEW.`name`) THEN
UPDATE zoneGeo SET `name` = NEW.`name`
WHERE id = NEW.geoFk;
END IF;
END */;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
@ -7389,20 +7389,20 @@ DELIMITER ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`receipt_beforeInsert`
BEFORE INSERT ON `receipt`
FOR EACH ROW
BEGIN
DECLARE vIsAutoConciliated BOOLEAN;
IF NEW.isConciliate = FALSE THEN
SELECT isAutoConciliated INTO vIsAutoConciliated
FROM accounting a
JOIN accountingType at2 ON at2.id = a.accountingTypeFk
WHERE a.id = NEW.bankFk;
SET NEW.isConciliate = vIsAutoConciliated;
END IF;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`receipt_beforeInsert`
BEFORE INSERT ON `receipt`
FOR EACH ROW
BEGIN
DECLARE vIsAutoConciliated BOOLEAN;
IF NEW.isConciliate = FALSE THEN
SELECT isAutoConciliated INTO vIsAutoConciliated
FROM accounting a
JOIN accountingType at2 ON at2.id = a.accountingTypeFk
WHERE a.id = NEW.bankFk;
SET NEW.isConciliate = vIsAutoConciliated;
END IF;
END */;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
@ -7458,18 +7458,18 @@ DELIMITER ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`receipt_afterUpdate`
AFTER UPDATE ON `receipt`
FOR EACH ROW
BEGIN
IF NEW.isConciliate = FALSE AND NEW.payed > OLD.payed THEN
CALL mail_insert(
'finanzas@verdnatura.es',
NULL,
CONCAT('Cambios de recibos del cliente: ', NEW.clientFk),
CONCAT('Se ha cambiado el recibo: ', NEW.Id, ' de ', OLD.payed, ' a ', NEW.payed)
);
END IF;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`receipt_afterUpdate`
AFTER UPDATE ON `receipt`
FOR EACH ROW
BEGIN
IF NEW.isConciliate = FALSE AND NEW.payed > OLD.payed THEN
CALL mail_insert(
'finanzas@verdnatura.es',
NULL,
CONCAT('Cambios de recibos del cliente: ', NEW.clientFk),
CONCAT('Se ha cambiado el recibo: ', NEW.Id, ' de ', OLD.payed, ' a ', NEW.payed)
);
END IF;
END */;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
@ -9165,31 +9165,31 @@ DELIMITER ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = 'NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER ticketCollection_afterDelete
AFTER DELETE
ON ticketCollection FOR EACH ROW
BEGIN
DECLARE vSalesRemaining INT;
SELECT count(*) INTO vSalesRemaining
FROM vn.ticketCollection tc
JOIN sale s ON s.ticketFk = tc.ticketFk
WHERE collectionFk = OLD.collectionFk
AND tc.id != OLD.id;
IF NOT vSalesRemaining THEN
DELETE FROM vn.collection WHERE id = OLD.collectionFk;
ELSE
UPDATE vn.collection
SET saleTotalCount = vSalesRemaining
WHERE id = OLD.collectionFk;
END IF;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER ticketCollection_afterDelete
AFTER DELETE
ON ticketCollection FOR EACH ROW
BEGIN
DECLARE vSalesRemaining INT;
SELECT count(*) INTO vSalesRemaining
FROM vn.ticketCollection tc
JOIN sale s ON s.ticketFk = tc.ticketFk
WHERE collectionFk = OLD.collectionFk
AND tc.id != OLD.id;
IF NOT vSalesRemaining THEN
DELETE FROM vn.collection WHERE id = OLD.collectionFk;
ELSE
UPDATE vn.collection
SET saleTotalCount = vSalesRemaining
WHERE id = OLD.collectionFk;
END IF;
END */;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
@ -10517,11 +10517,11 @@ DELIMITER ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`workerTimeControl_beforeInsert`
BEFORE INSERT ON `workerTimeControl`
FOR EACH ROW
BEGIN
SET NEW.editorFk = account.myUser_getId();
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`workerTimeControl_beforeInsert`
BEFORE INSERT ON `workerTimeControl`
FOR EACH ROW
BEGIN
SET NEW.editorFk = account.myUser_getId();
END */;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
@ -10559,11 +10559,11 @@ DELIMITER ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`workerTimeControl_beforeUpdate`
BEFORE UPDATE ON `workerTimeControl`
FOR EACH ROW
BEGIN
SET NEW.editorFk = account.myUser_getId();
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`workerTimeControl_beforeUpdate`
BEFORE UPDATE ON `workerTimeControl`
FOR EACH ROW
BEGIN
SET NEW.editorFk = account.myUser_getId();
END */;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
@ -10579,15 +10579,15 @@ DELIMITER ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`workerTimeControl_afterDelete`
AFTER DELETE ON `workerTimeControl`
FOR EACH ROW
BEGIN
INSERT INTO workerLog
SET `action` = 'delete',
`changedModel` = 'WorkerTimeControl',
`changedModelId` = OLD.id,
`userFk` = account.myUser_getId();
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`workerTimeControl_afterDelete`
AFTER DELETE ON `workerTimeControl`
FOR EACH ROW
BEGIN
INSERT INTO workerLog
SET `action` = 'delete',
`changedModel` = 'WorkerTimeControl',
`changedModelId` = OLD.id,
`userFk` = account.myUser_getId();
END */;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;

View File

@ -371,20 +371,20 @@ INSERT INTO `vn`.`contactChannel`(`id`, `name`)
(4, 'GCN Channel'),
(5, 'The Newspaper');
INSERT INTO `vn`.`client`(`id`,`name`,`fi`,`socialName`,`contact`,`street`,`city`,`postcode`,`phone`,`mobile`,`isRelevant`,`email`,`iban`,`dueDay`,`accountingAccount`,`isEqualizated`,`provinceFk`,`hasToInvoice`,`credit`,`countryFk`,`isActive`,`gestdocFk`,`quality`,`payMethodFk`,`created`,`isToBeMailed`,`contactChannelFk`,`hasSepaVnl`,`hasCoreVnl`,`hasCoreVnh`,`riskCalculated`, `hasToInvoiceByAddress`,`isTaxDataChecked`,`isFreezed`,`creditInsurance`,`isCreatedAsServed`,`hasInvoiceSimplified`,`salesPersonFk`,`isVies`,`businessTypeFk`,`typeFk`)
INSERT INTO `vn`.`client`(`id`,`name`,`fi`,`socialName`,`contact`,`street`,`city`,`postcode`,`phone`,`mobile`,`isRelevant`,`email`,`iban`,`dueDay`,`accountingAccount`,`isEqualizated`,`provinceFk`,`hasToInvoice`,`credit`,`countryFk`,`isActive`,`gestdocFk`,`quality`,`payMethodFk`,`created`,`isToBeMailed`,`contactChannelFk`,`hasSepaVnl`,`hasCoreVnl`,`hasCoreVnh`,`riskCalculated`, `hasToInvoiceByAddress`,`isTaxDataChecked`,`isFreezed`,`creditInsurance`,`isCreatedAsServed`,`hasInvoiceSimplified`,`salesPersonFk`,`isVies`,`businessTypeFk`,`typeFk`, `salesDepartmentFk`)
VALUES
(1101, 'Bruce Wayne', '84612325V', 'BATMAN', 'Alfred', '1007 MOUNTAIN DRIVE, GOTHAM', 'Gotham', 46460, 1111111111, 222222222, 1, 'BruceWayne@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, NULL, 0, 0, 18, 0, 'florist','normal'),
(1102, 'Petter Parker', '87945234L', 'SPIDER MAN', 'Aunt May', '20 INGRAM STREET, QUEENS, USA', 'Gotham', 46460, 1111111111, 222222222, 1, 'PetterParker@mydomain.com', NULL, 0, 1234567890, 0, 2, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, NULL, 0, 0, 18, 0, 'florist','normal'),
(1103, 'Clark Kent', '06815934E', 'SUPER MAN', 'lois lane', '344 CLINTON STREET, APARTAMENT 3-D', 'Gotham', 46460, 1111111111, 222222222, 1, 'ClarkKent@mydomain.com', NULL, 0, 1234567890, 0, 3, 1, 0, 19, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, NULL, 0, 0, 18, 0, 'florist','normal'),
(1104, 'Tony Stark', '06089160W', 'IRON MAN', 'Pepper Potts', '10880 MALIBU POINT, 90265', 'Gotham', 46460, 1111111111, 222222222, 1, 'TonyStark@mydomain.com', NULL, 0, 1234567890, 0, 2, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, NULL, 0, 0, 18, 0, 'florist','normal'),
(1105, 'Max Eisenhardt', '251628698', 'MAGNETO', 'Rogue', 'UNKNOWN WHEREABOUTS', 'Gotham', 46460, 1111111111, 222222222, 1, 'MaxEisenhardt@mydomain.com', NULL, 0, 1234567890, 0, 3, 1, 300, 8, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, NULL, 0, 0, 18, 0, 'florist','normal'),
(1106, 'DavidCharlesHaller', '53136686Q', 'LEGION', 'Charles Xavier', 'CITY OF NEW YORK, NEW YORK, USA', 'Gotham', 46460, 1111111111, 222222222, 1, 'DavidCharlesHaller@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 0, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, NULL, 0, 0, 19, 0, 'florist','normal'),
(1107, 'Hank Pym', '09854837G', 'ANT MAN', 'Hawk', 'ANTHILL, SAN FRANCISCO, CALIFORNIA', 'Gotham', 46460, 1111111111, 222222222, 1, 'HankPym@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 0, 0, NULL, 0, 0, 19, 0, 'florist','normal'),
(1108, 'Charles Xavier', '22641921P', 'PROFESSOR X', 'Beast', '3800 VICTORY PKWY, CINCINNATI, OH 45207, USA', 'Gotham', 46460, 1111111111, 222222222, 1, 'CharlesXavier@mydomain.com', NULL, 0, 1234567890, 0, 5, 1, 300, 13, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, NULL, 0, 0, 19, 0, 'florist','normal'),
(1109, 'Bruce Banner', '16104829E', 'HULK', 'Black widow', 'SOMEWHERE IN NEW YORK', 'Gotham', 46460, 1111111111, 222222222, 1, 'BruceBanner@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 0, 0, NULL, 0, 0, 9, 0, 'florist','normal'),
(1110, 'Jessica Jones', '58282869H', 'JESSICA JONES', 'Luke Cage', 'NYCC 2015 POSTER', 'Gotham', 46460, 1111111111, 222222222, 1, 'JessicaJones@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 0, 0, NULL, 0, 0, NULL, 0, 'florist','normal'),
(1111, 'Missing', NULL, 'MISSING MAN', 'Anton', 'THE SPACE, UNIVERSE FAR AWAY', 'Gotham', 46460, 1111111111, 222222222, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 0, 1, 0, NULL, 1, 0, NULL, 0, 'others','loses'),
(1112, 'Trash', NULL, 'GARBAGE MAN', 'Unknown name', 'NEW YORK CITY, UNDERGROUND', 'Gotham', 46460, 1111111111, 222222222, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 0, 1, 0, NULL, 1, 0, NULL, 0, 'others','loses');
(1101, 'Bruce Wayne', '84612325V', 'BATMAN', 'Alfred', '1007 MOUNTAIN DRIVE, GOTHAM', 'Gotham', 46460, 1111111111, 222222222, 1, 'BruceWayne@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, NULL, 0, 0, 18, 0, 'florist','normal', 80),
(1102, 'Petter Parker', '87945234L', 'SPIDER MAN', 'Aunt May', '20 INGRAM STREET, QUEENS, USA', 'Gotham', 46460, 1111111111, 222222222, 1, 'PetterParker@mydomain.com', NULL, 0, 1234567890, 0, 2, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, NULL, 0, 0, 18, 0, 'florist','normal', 80),
(1103, 'Clark Kent', '06815934E', 'SUPER MAN', 'lois lane', '344 CLINTON STREET, APARTAMENT 3-D', 'Gotham', 46460, 1111111111, 222222222, 1, 'ClarkKent@mydomain.com', NULL, 0, 1234567890, 0, 3, 1, 0, 19, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, NULL, 0, 0, 18, 0, 'florist','normal', 80),
(1104, 'Tony Stark', '06089160W', 'IRON MAN', 'Pepper Potts', '10880 MALIBU POINT, 90265', 'Gotham', 46460, 1111111111, 222222222, 1, 'TonyStark@mydomain.com', NULL, 0, 1234567890, 0, 2, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, NULL, 0, 0, 18, 0, 'florist','normal', 80),
(1105, 'Max Eisenhardt', '251628698', 'MAGNETO', 'Rogue', 'UNKNOWN WHEREABOUTS', 'Gotham', 46460, 1111111111, 222222222, 1, 'MaxEisenhardt@mydomain.com', NULL, 0, 1234567890, 0, 3, 1, 300, 8, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, NULL, 0, 0, 18, 0, 'florist','normal', 80),
(1106, 'DavidCharlesHaller', '53136686Q', 'LEGION', 'Charles Xavier', 'CITY OF NEW YORK, NEW YORK, USA', 'Gotham', 46460, 1111111111, 222222222, 1, 'DavidCharlesHaller@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 0, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, NULL, 0, 0, 19, 0, 'florist','normal', 80),
(1107, 'Hank Pym', '09854837G', 'ANT MAN', 'Hawk', 'ANTHILL, SAN FRANCISCO, CALIFORNIA', 'Gotham', 46460, 1111111111, 222222222, 1, 'HankPym@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 0, 0, NULL, 0, 0, 19, 0, 'florist','normal', 80),
(1108, 'Charles Xavier', '22641921P', 'PROFESSOR X', 'Beast', '3800 VICTORY PKWY, CINCINNATI, OH 45207, USA', 'Gotham', 46460, 1111111111, 222222222, 1, 'CharlesXavier@mydomain.com', NULL, 0, 1234567890, 0, 5, 1, 300, 13, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, NULL, 0, 0, 19, 0, 'florist','normal', 80),
(1109, 'Bruce Banner', '16104829E', 'HULK', 'Black widow', 'SOMEWHERE IN NEW YORK', 'Gotham', 46460, 1111111111, 222222222, 1, 'BruceBanner@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 0, 0, NULL, 0, 0, 9, 0, 'florist','normal', 80),
(1110, 'Jessica Jones', '58282869H', 'JESSICA JONES', 'Luke Cage', 'NYCC 2015 POSTER', 'Gotham', 46460, 1111111111, 222222222, 1, 'JessicaJones@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 0, 0, NULL, 0, 0, NULL, 0, 'florist','normal', 80),
(1111, 'Missing', NULL, 'MISSING MAN', 'Anton', 'THE SPACE, UNIVERSE FAR AWAY', 'Gotham', 46460, 1111111111, 222222222, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 0, 1, 0, NULL, 1, 0, NULL, 0, 'others','loses', 80),
(1112, 'Trash', NULL, 'GARBAGE MAN', 'Unknown name', 'NEW YORK CITY, UNDERGROUND', 'Gotham', 46460, 1111111111, 222222222, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 0, 1, 0, NULL, 1, 0, NULL, 0, 'others','loses', 80);
INSERT INTO `vn`.`client`(`id`, `name`, `fi`, `socialName`, `contact`, `street`, `city`, `postcode`, `isRelevant`, `email`, `iban`,`dueDay`,`accountingAccount`, `isEqualizated`, `provinceFk`, `hasToInvoice`, `credit`, `countryFk`, `isActive`, `gestdocFk`, `quality`, `payMethodFk`,`created`, `isTaxDataChecked`)
SELECT id, name, CONCAT(RPAD(CONCAT(id,9),8,id),'A'), UPPER(CONCAT(name, 'Social')), CONCAT(name, 'Contact'), CONCAT(name, 'Street'), 'GOTHAM', 46460, 1, CONCAT(name,'@mydomain.com'), NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5, util.VN_CURDATE(), 1
@ -1798,9 +1798,8 @@ INSERT INTO `vn`.`clientContact`(`id`, `clientFk`, `name`, `phone`)
(3, 1101, 'contact 3', 222333444),
(4, 1102, 'contact 1', 876543219);
INSERT INTO `vn`.`workerManaExcluded`(`workerFk`)
VALUES
(9);
INSERT INTO `vn`.`departmentManaExcluded`(`salesDepartmentFk`)
VALUES (31);
/*
el mana de los trabajadores lo podemos poner a mano en la tabla si lo calculamos antes,
pero si hazemos alguna modificacion en alguna tabla que utiliza para calcularlo ya no seria correcto
@ -1808,8 +1807,8 @@ INSERT INTO `vn`.`workerManaExcluded`(`workerFk`)
La otra manera es poner el calculo con los 2 trabajadores que utilizamos ahora mismo para los tickets
*/
call vn.manaSpellersRequery(19);
call vn.manaSpellersRequery(18);
call vn.manaSpellers_requery(80);
call vn.manaSpellers_requery(31);
INSERT INTO `vn`.`clientSample`(`id`, `clientFk`, `typeFk`, `created`, `workerFk`, `userFk`, `companyFk`)
VALUES

View File

@ -13,7 +13,6 @@ BEGIN
Familia,
Reino,
salesDepartmentFk,
Comercial,
Comprador,
Provincia,
almacen,
@ -28,7 +27,6 @@ BEGIN
ic.name,
c.salesDepartmentFk,
w.code,
w2.code,
p.name,
wa.name,
tm.year,
@ -40,8 +38,7 @@ BEGIN
LEFT JOIN vn.itemType it ON it.id = bt.tipo_id
LEFT JOIN vn.itemCategory ic ON ic.id = it.categoryFk
LEFT JOIN vn.client c on c.id = bt.Id_Cliente
LEFT JOIN vn.worker w ON w.id = c.salesPersonFk
LEFT JOIN vn.worker w2 ON w2.id = it.workerFk
LEFT JOIN vn.worker w ON w.id = it.workerFk
JOIN vn.time tm ON tm.dated = bt.fecha
JOIN vn.sale s ON s.id = bt.Id_Movimiento
LEFT JOIN vn.ticket t ON t.id = s.ticketFk

View File

@ -33,13 +33,11 @@ BEGIN
nd.difference,
nd.defaulterSince,
c.name Cliente,
w.code workerCode,
d.name salesDepartmentName,
c.payMethodFk pay_met_id,
c.dueDay Vencimiento
FROM newDefaulters nd
LEFT JOIN vn.client c ON c.id = nd.client
LEFT JOIN vn.worker w ON w.id = c.salesPersonFk
LEFT JOIN vn.department d ON d.id = c.salesDepartmentFk;
END$$
DELIMITER ;

View File

@ -1,27 +0,0 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `bs`.`carteras_add`()
BEGIN
/**
* Inserta en la tabla @bs.carteras las ventas desde el año pasado
* agrupadas por trabajador, año y mes
*/
DECLARE vYear INT DEFAULT YEAR(util.VN_CURDATE()) - 1;
DELETE FROM bs.carteras WHERE Año >= vYear;
CALL util.time_generate(
MAKEDATE(vYear, 1),
(SELECT MAX(fecha) FROM ventas)
);
INSERT INTO carteras(Año, Mes , CodigoTrabajador, Peso)
SELECT t.`year`, t.`month`, w.code, SUM(v.importe)
FROM tmp.time t
JOIN ventas v on t.dated = v.fecha
JOIN vn.client c on c.id = v.Id_Cliente
JOIN vn.worker w ON w.id = c.salesPersonFk
GROUP BY w.code, t.`year`, t.`month`;
DROP TEMPORARY TABLE tmp.time;
END$$
DELIMITER ;

View File

@ -20,9 +20,6 @@ BEGIN
DELETE FROM payMethodClientEvolution
WHERE dated < vFourYearsAgo;
DELETE FROM salesByclientSalesPerson
WHERE dated < vFourYearsAgo;
DELETE FROM salesByClientDepartment
WHERE dated < vFourYearsAgo;

View File

@ -5,23 +5,23 @@ BEGIN
* Recalcula el valor del campo con el modificador de precio
* para el componente de maná automático.
*/
UPDATE vn.workerMana wm
UPDATE vn.departmentMana dm
JOIN (
SELECT c.lastSalesPersonFk,
SELECT c.lastSalesDepartmentFk,
FLOOR(SUM(s.amount) / 12) amount
FROM salesByclientSalesPerson s
FROM salesByClientDepartment s
JOIN vn.client c ON c.id = s.clientFk
WHERE s.dated BETWEEN util.VN_CURDATE() - INTERVAL 1 YEAR AND util.VN_CURDATE()
GROUP BY c.lastSalesPersonFk
)avgPortfolioWeight ON avgPortfolioWeight.lastSalesPersonFk = wm.workerFk
GROUP BY c.lastSalesDepartmentFk
)avgPortfolioWeight ON avgPortfolioWeight.lastSalesDepartmentFk = dm.salesDepartmentFk
JOIN vn.salesDepartmentConfig sdc
SET wm.pricesModifierRate =
SET dm.pricesModifierRate =
IFNULL(
GREATEST(
sdc.manaMinRate,
LEAST(
sdc.manaMaxRate,
ROUND( - wm.amount / avgPortfolioWeight.amount, 3)
ROUND( - dm.amount / avgPortfolioWeight.amount, 3)
)
)
,0);

View File

@ -1,29 +0,0 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `bs`.`manaSpellers_recalc`()
BEGIN
/**
* Recalcula el valor del campo con el modificador de precio
* para el componente de maná automático.
*/
UPDATE vn.departmentMana dm
JOIN (
SELECT c.lastSalesDepartmentFk,
FLOOR(SUM(s.amount) / 12) amount
FROM salesByClientDepartment s
JOIN vn.client c ON c.id = s.clientFk
WHERE s.dated BETWEEN util.VN_CURDATE() - INTERVAL 1 YEAR AND util.VN_CURDATE()
GROUP BY c.lastSalesDepartmentFk
)avgPortfolioWeight ON avgPortfolioWeight.lastSalesDepartmentFk = dm.salesDepartmentFk
JOIN vn.salesDepartmentConfig sdc
SET dm.pricesModifierRate =
IFNULL(
GREATEST(
sdc.manaMinRate,
LEAST(
sdc.manaMaxRate,
ROUND( - dm.amount / avgPortfolioWeight.amount, 3)
)
)
,0);
END$$
DELIMITER ;

View File

@ -1,5 +1,5 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `bs`.`portfolio_add`()
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `bs`.`porfolio_add`()
BEGIN
/**
* Inserta en la tabla @bs.portfolio las ventas desde el año pasado

View File

@ -1,46 +0,0 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `bs`.`salesByclientSalesPerson_add`(vDatedFrom DATE)
BEGIN
/**
* Agrupa las ventas por cliente/comercial/fecha en la tabla bs.salesByclientSalesPerson
* El asociación cliente/comercial/fecha, se mantiene correcta en el tiempo
*
* @param vDatedFrom el cálculo se realizará desde la fecha introducida hasta ayer
*/
IF vDatedFrom IS NULL THEN
SET vDatedFrom = util.VN_CURDATE() - INTERVAL 1 MONTH;
END IF;
UPDATE salesByclientSalesPerson
SET amount = 0,
equalizationTax = 0,
amountNewBorn = 0
WHERE dated BETWEEN vDatedFrom AND util.yesterday();
INSERT INTO salesByclientSalesPerson(
dated,
salesPersonFk,
clientFk,
amount,
equalizationTax)
SELECT s.dated,
c.salesPersonFk,
s.clientFk,
SUM(s.amount),
SUM(s.surcharge)
FROM sale s
JOIN vn.client c on s.clientFk = c.id
WHERE s.dated BETWEEN vDatedFrom AND util.yesterday()
GROUP BY s.dated, c.salesPersonFk, s.clientFk
ON DUPLICATE KEY UPDATE amount= VALUES(amount),
equalizationTax= VALUES(equalizationTax);
UPDATE salesByclientSalesPerson s
JOIN vn.newBornSales n ON n.dated = s.dated AND
n.clientFk = s.clientFk
SET s.amountNewBorn = n.amount
WHERE n.dated BETWEEN vDatedFrom AND util.yesterday();
END$$
DELIMITER ;

View File

@ -1,65 +0,0 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `bs`.`salesPersonEvolution_add`()
BEGIN
/**
* Calcula los datos para los gráficos de evolución agrupado por salesPersonFk y día.
* Recalcula automáticamente los 3 últimos meses para comprobar si hay algún cambio.
*/
DECLARE vDated DATE;
DECLARE vCont INT DEFAULT 1;
SELECT MAX(dated) - INTERVAL 3 MONTH INTO vDated
FROM salesPersonEvolution;
DELETE FROM salesPersonEvolution
WHERE dated >= vDated;
IF ISNULL(vDated) THEN
SELECT MIN(dated) INTO vDated
FROM salesByclientSalesPerson;
INSERT INTO salesPersonEvolution(
salesPersonFk,
dated,
amount,
equalizationTax,
amountNewBorn
)
SELECT salesPersonFk,
dated,
amount,
equalizationTax,
amountNewBorn
FROM salesByclientSalesPerson
WHERE dated = vDated
GROUP BY salesPersonFk;
SET vDated = vDated + INTERVAL 1 DAY;
END IF;
WHILE vDated < util.VN_CURDATE() DO
SET vCont = vCont + 1;
REPLACE salesPersonEvolution(salesPersonFk, dated, amount)
SELECT salesPersonFk, vDated, amount
FROM(SELECT salesPersonFk, SUM(amount) amount
FROM(SELECT salesPersonFk, amount
FROM salesPersonEvolution
WHERE dated = vDated - INTERVAL 1 DAY
UNION ALL
SELECT salesPersonFk, amount
FROM salesByclientSalesPerson
WHERE dated = vDated
UNION ALL
SELECT salesPersonFk, - amount
FROM salesByclientSalesPerson
WHERE dated = vDated - INTERVAL 1 YEAR
)sub
GROUP BY salesPersonFk
)sub
GROUP BY salesPersonFk;
SET vDated = vDated + INTERVAL 1 DAY;
END WHILE;
END$$
DELIMITER ;

View File

@ -1,11 +0,0 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` FUNCTION `vn`.`clientGetSalesPerson`(vClientFk INT, vDated DATE)
RETURNS int(11)
DETERMINISTIC
BEGIN
/**
* DEPRECATED: use client_getSalesPerson
**/
RETURN client_getSalesPerson(vClientFk, vDated);
END$$
DELIMITER ;

View File

@ -1,74 +0,0 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` FUNCTION `vn`.`client_getSalesPerson`(vClientFk INT, vDated DATE)
RETURNS int(11)
DETERMINISTIC
BEGIN
/**
* Dado un id cliente y una fecha, devuelve su comercial para ese dia, teniendo
* en cuenta la jerarquía de las tablas: 1º la de sharingclient, 2º la de
* sharingcart y tercero la de clientes.
*
* @param vClientFk El id del cliente
* @param vDated Fecha a comprobar
* @return El id del comercial para la fecha dada
**/
DECLARE vSalesPersonFk INT DEFAULT NULL;
DECLARE vWorkerSubstituteFk INT DEFAULT NULL;
DECLARE vLoop BOOLEAN;
-- Obtiene el comercial original y el de sharingclient
SELECT c.salesPersonFk, s.workerFk
INTO vSalesPersonFk, vWorkerSubstituteFk
FROM client c
LEFT JOIN sharingClient s
ON c.id = s.clientFk
AND vDated BETWEEN s.started AND s.ended
WHERE c.id = vClientFk
ORDER BY s.id
LIMIT 1;
-- Si no hay ninguno en sharingclient busca en sharingcart
IF vWorkerSubstituteFk IS NOT NULL
THEN
SET vSalesPersonFk = vWorkerSubstituteFk;
ELSEIF vSalesPersonFk IS NOT NULL
THEN
DROP TEMPORARY TABLE IF EXISTS tmp.stack;
CREATE TEMPORARY TABLE tmp.stack
(INDEX (substitute))
ENGINE = MEMORY
SELECT vSalesPersonFk substitute;
l: LOOP
SELECT workerSubstitute INTO vWorkerSubstituteFk
FROM sharingCart
WHERE util.VN_CURDATE() BETWEEN started AND ended
AND workerFk = vSalesPersonFk
ORDER BY id
LIMIT 1;
IF vWorkerSubstituteFk IS NULL THEN
LEAVE l;
END IF;
SELECT COUNT(*) > 0 INTO vLoop
FROM tmp.stack WHERE substitute = vWorkerSubstituteFk;
IF vLoop THEN
LEAVE l;
END IF;
INSERT INTO tmp.stack SET
substitute = vWorkerSubstituteFk;
SET vSalesPersonFk = vWorkerSubstituteFk;
END LOOP;
DROP TEMPORARY TABLE tmp.stack;
END IF;
RETURN vSalesPersonFk;
END$$
DELIMITER ;

View File

@ -1,23 +0,0 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` FUNCTION `vn`.`client_getSalesPersonByTicket`(vTicketFk INT)
RETURNS int(11)
DETERMINISTIC
BEGIN
/**
* Dado un id ticket, devuelve su comercial.
* Para más información ir a client_getSalesPerson()
*
* @param vClientFk El id del cliente
* @param vDated Fecha a comprobar
* @return El id del comercial para la fecha dada
**/
DECLARE vClientFk INT;
DECLARE vDated DATE;
SELECT clientFk, shipped
INTO vClientFk, vDated
FROM ticket WHERE id = vTicketFk;
RETURN client_getSalesPerson(vClientFk, vDated);
END$$
DELIMITER ;

View File

@ -1,23 +0,0 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` FUNCTION `vn`.`client_getSalesPersonCodeByTicket`(vTicketFk INT)
RETURNS varchar(3) CHARSET utf8mb3 COLLATE utf8mb3_general_ci
DETERMINISTIC
BEGIN
/**
* Dado un id ticket, devuelve su comercial.
* Para más información ir a client_getSalesPerson()
*
* @param vClientFk El id del cliente
* @param vDated Fecha a comprobar
* @return El código del comercial para la fecha dada
**/
DECLARE vClientFk INT;
DECLARE vDated DATE;
SELECT clientFk, shipped
INTO vClientFk, vDated
FROM ticket WHERE id = vTicketFk;
RETURN client_getSalesPersonCode(vClientFk, vDated);
END$$
DELIMITER ;

View File

@ -22,8 +22,7 @@ BEGIN
WHERE clientFk = vClientFk;
UPDATE vn.client
SET salesPersonFk = NULL,
salesDepartmentFk = NULL
SET salesDepartmentFk = NULL
WHERE id = vClientFk;
END$$

View File

@ -25,7 +25,6 @@ BEGIN
AND cp.clientFk IS NULL
AND co.code NOT IN ('PT')
AND a.name <> 'Canarias'
AND c.salesPersonFk IS NOT NULL
AND c.salesDepartmentFk IS NOT NULL;
OPEN rs;
@ -34,8 +33,7 @@ BEGIN
CALL vn.clientGreugeSpray(vClientFk, TRUE, '',TRUE);
UPDATE vn.client
SET salesPersonFk = NULL,
salesDepartmentFk = NULL
SET salesDepartmentFk = NULL
WHERE id = vClientFk;
FETCH rs INTO vClientFk;

View File

@ -22,14 +22,12 @@ BEGIN
FROM bs.clientDied cd
JOIN client c ON c.id = cd.clientFk
LEFT JOIN clientProtected cp ON cp.clientFk = c.id
LEFT JOIN salesPersonProtected sp ON sp.salesPersonFk = c.salesPersonFk
LEFT JOIN salesDepartmentProtected sd ON sp.salesDepartmentFk = c.salesDepartmentFk
JOIN province p ON p.id = c.provinceFk
LEFT JOIN autonomy a ON a.id = p.autonomyFk
JOIN country co ON co.id = p.countryFk
WHERE cd.warning = 'third'
AND cp.clientFk IS NULL
AND sp.salesPersonFk IS NULL
AND a.name <> 'Canarias'
AND c.salesDepartmentFk IS NOT NULL;

View File

@ -1,51 +0,0 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`client_unassignSalesPerson`()
BEGIN
/**
* Elimina la asignación de salesPersonFk de la ficha del clientes
* que no han realizado una compra en los últimos 3 meses y reparte
* su greuge entre el resto de clientes
*/
DECLARE vDone BOOL DEFAULT FALSE;
DECLARE vClientFk INT;
DECLARE vCursor CURSOR FOR
SELECT c.clientFk
FROM tClientList c
LEFT JOIN clientRisk r ON r.clientFk = c.clientFk
GROUP BY c.clientFk
HAVING NOT SUM(IFNULL(r.amount, 0));
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
CREATE OR REPLACE TEMPORARY TABLE tClientList
SELECT c.id clientFk
FROM bs.clientDied cd
JOIN client c ON c.id = cd.clientFk
LEFT JOIN clientProtected cp ON cp.clientFk = c.id
LEFT JOIN salesPersonProtected sp ON sp.salesPersonFk = c.salesPersonFk
JOIN province p ON p.id = c.provinceFk
LEFT JOIN autonomy a ON a.id = p.autonomyFk
JOIN country co ON co.id = p.countryFk
WHERE cd.warning = 'third'
AND cp.clientFk IS NULL
AND sp.salesPersonFk IS NULL
AND a.name <> 'Canarias'
AND c.salesPersonFk IS NOT NULL;
OPEN vCursor;
l: LOOP
SET vDone = FALSE;
FETCH vCursor INTO vClientFk;
IF vDone THEN
LEAVE l;
END IF;
CALL clientGreugeSpray(vClientFk, TRUE, '', TRUE);
UPDATE client
SET salesPersonFk = NULL
WHERE id = vClientFk;
END LOOP;
CLOSE vCursor;
DROP TEMPORARY TABLE tClientList;
END$$
DELIMITER ;

View File

@ -6,8 +6,8 @@ BEGIN
/**
* Selecciona los tickets de una colección/ticket
* @param vParamFk ticketFk/collectionFk
* @return Retorna (ticketFk, level, agencyName, warehouseFk, salesPersonFk,
* observaciones, rgb, salesDepartmentFk)
* @return Retorna (ticketFk, level, agencyName, warehouseFk, observaciones,
* rgb, salesDepartmentFk)
*/
DECLARE vItemPackingTypeFk VARCHAR(1);
@ -22,7 +22,6 @@ BEGIN
CONCAT(SUBSTRING('ABCDEFGH',tc.wagon, 1),'-',tc.`level` )) `level`,
am.name agencyName,
t.warehouseFk,
c.salesPersonFk,
IFNULL(tob.description,'') observaciones,
cc.rgb,
c.salesDepartmentFk
@ -47,7 +46,6 @@ BEGIN
CONCAT(SUBSTRING('ABCDEFGH', tc.wagon, 1), '-', tc.`level`)) `level`,
am.name agencyName,
t.warehouseFk,
c.salesPersonFk,
IFNULL(tob.description, '') observaciones,
IF(NOT(vItemPackingTypeFk <=> 'V'), cc.rgb, NULL) `rgb`,
c.salesDepartmentFk

View File

@ -14,7 +14,6 @@ BEGIN
s.ticketFk,
t.nickname client,
am.name agencyName,
wk.code salesPerson,
s.itemFk,
IFNULL(CONCAT(ig.longName,' ',ig.`size`,' ',ig.subName), s.concept) AS concept,
s.quantity,
@ -24,7 +23,6 @@ BEGIN
tls.name stateName,
sb.buyFk,
s.id saleFk,
wk.id salesPersonFk,
d.id salesDepartmentFk,
d.name salesDepartment
FROM sale s
@ -33,7 +31,6 @@ BEGIN
JOIN address a ON a.id = t.addressFk
LEFT JOIN agencyMode am ON am.id = t.agencyModeFk
JOIN `client` c ON c.id = a.clientFk
LEFT JOIN worker wk ON wk.id = c.salesPersonFk
LEFT JOIN department d ON d.id = c.salesDepartmentFk
LEFT JOIN ticketLastState tls ON tls.ticketFk = t.id
LEFT JOIN saleBuy sb ON sb.saleFk = s.id

View File

@ -1,36 +0,0 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`manaSpellersRequery`(vWorkerFk INTEGER)
`whole_proc`:
BEGIN
/**
* Guarda en workerMana el mana consumido por un trabajador
*
* @param vWorkerFk Id Trabajador
*/
DECLARE vWorkerIsExcluded BOOLEAN;
SELECT COUNT(*) INTO vWorkerIsExcluded
FROM workerManaExcluded
WHERE workerFk = vWorkerFk;
IF vWorkerIsExcluded THEN
LEAVE whole_proc;
END IF;
CREATE OR REPLACE TEMPORARY TABLE tmp.client
SELECT id
FROM client
WHERE salesPersonFk = vWorkerFk;
CALL client_getMana();
INSERT INTO workerMana (workerFk, amount)
SELECT vWorkerFk, sum(mana)
FROM tmp.clientMana
ON DUPLICATE KEY UPDATE amount = VALUES(amount);
DROP TEMPORARY TABLE
tmp.client,
tmp.clientMana;
END$$
DELIMITER ;

View File

@ -1,19 +1,19 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`manaSpellers_requery`(
vDepartmentFk INTEGER
vSalesDepartmentFk INTEGER
)
`whole_proc`:
BEGIN
/**
* Guarda en departmentMana el mana consumido por un departamento
*
* @param vDepartmentFk Id department
* @param vSalesDepartmentFk Id department
*/
DECLARE vIsDepartmentExcluded BOOLEAN;
SELECT COUNT(*) INTO vIsDepartmentExcluded
FROM departmentManaExcluded
WHERE departmentFk = vSalesDepartmentFk;
WHERE salesDepartmentFk = vSalesDepartmentFk;
IF vIsDepartmentExcluded THEN
LEAVE whole_proc;
@ -22,12 +22,12 @@ BEGIN
CREATE OR REPLACE TEMPORARY TABLE tmp.client
SELECT id
FROM client
WHERE salesDepartmentFk = vDepartmentFk;
WHERE salesDepartmentFk = vSalesDepartmentFk;
CALL client_getMana();
INSERT INTO departmentMana (departmentFk, amount)
SELECT vDepartmentFk, SUM(mana)
INSERT INTO departmentMana (salesDepartmentFk, amount)
SELECT vSalesDepartmentFk, SUM(mana)
FROM tmp.clientMana
ON DUPLICATE KEY UPDATE amount = VALUES(amount);

View File

@ -64,7 +64,6 @@ proc: BEGIN
IFNULL(tls.state,2) state,
w.code workerCode,
DATE(t.shipped) shipped,
wk.code salesPersonCode,
d.code salesDepartmentCode,
p.id provinceFk,
tls.productionOrder,
@ -86,7 +85,6 @@ proc: BEGIN
LEFT JOIN `state` st ON st.id = tst.state
LEFT JOIN client c ON c.id = t.clientFk
LEFT JOIN department d ON d.id = c.salesDepartmentFk
LEFT JOIN worker wk ON wk.id = c.salesPersonFk
JOIN address a ON a.id = t.addressFk
LEFT JOIN province p ON p.id = a.provinceFk
JOIN agencyMode am ON am.id = t.agencyModeFk

View File

@ -23,7 +23,6 @@ BEGIN
a.mobile AddressMobile,
d.longitude Longitude,
d.latitude Latitude,
wm.mediaValue SalePersonPhone,
CONCAT_WS(' - ', 'adfa', de.pbxQueue ) salesDepartmentPhone,
tob.description Note,
t.isSigned Signed,
@ -34,7 +33,6 @@ BEGIN
JOIN address a ON t.addressFk = a.id
LEFT JOIN vn.department de ON de.id = c.salesDepartmentFk
LEFT JOIN vn.company co ON co.`code` = 'VNL'
LEFT JOIN workerMedia wm ON wm.workerFk = c.salesPersonFk
LEFT JOIN (
SELECT t.addressFk, MAX(d.ticketFk) lastTicketFk
FROM ticket t

View File

@ -15,7 +15,6 @@ BEGIN
w.code workerCode,
sgd.saleFk,
iss.quantity pickedQuantity,
c.salesPersonFk,
c.salesDepartmentFk
FROM vn.sale s
JOIN item i ON i.id = s.itemFk

View File

@ -30,7 +30,6 @@ BEGIN
origin.futureState,
origin.futureIpt,
dest.ipt,
origin.workerFk,
origin.departmentFk,
origin.futureLiters,
origin.futureLines,
@ -60,7 +59,6 @@ BEGIN
FROM (
SELECT
s.ticketFk,
c.salesPersonFk workerFk,
c.salesDepartmentFk departmentFk,
t.shipped,
t.totalWithVat,

View File

@ -35,7 +35,6 @@ BEGIN
OPEN rsTicket;
myLoop: LOOP
BEGIN
DECLARE vSalesPersonEmail VARCHAR(150);
DECLARE vSalesDepartmentEmail VARCHAR(150);
DECLARE vIsDuplicateMail BOOL;
DECLARE vSubject VARCHAR(150);
@ -170,9 +169,8 @@ BEGIN
IF (vLanding IS NULL) THEN
SELECT e.email, d.notificationEmail INTO vSalesPersonEmail, vSalesDepartmentEmail
SELECT d.notificationEmail INTO vSalesDepartmentEmail
FROM client c
LEFT JOIN account.emailUser e ON e.userFk = c.salesPersonFk
LEFT JOIN department d ON d.id = c.saleDepartmentFk
WHERE c.id = vClientFk;
@ -183,15 +181,6 @@ BEGIN
' porque no hay una zona de envío disponible. Se ha creado el ticket: ',
vNewTicket, ' pero ha que revisar las fechas y la agencia');
SELECT COUNT(*) INTO vIsDuplicateMail
FROM mail
WHERE receiver = vSalesPersonEmail
AND subject = vSubject;
IF NOT vIsDuplicateMail THEN
CALL mail_insert(vSalesPersonEmail, NULL, vSubject, vMessage);
END IF;
SELECT COUNT(*) INTO vIsDuplicateMail
FROM mail
WHERE receiver = vSalesDepartmentEmail

View File

@ -9,11 +9,6 @@ l:BEGIN
LEAVE l;
END IF;
DELETE cp
FROM clientProtected cp
JOIN client c ON c.id = cp.clientFk
WHERE c.salesPersonFk = vUserFk;
DELETE FROM account.account WHERE id = vUserFk;
UPDATE account.user
@ -28,10 +23,5 @@ l:BEGIN
c.payMethodFk = p.id,
hasCoreVnl = FALSE
WHERE c.id = vUserFk;
UPDATE `client` c
SET c.salesPersonFk = NULL,
c.salesDepartmentFk = NULL
WHERE c.salesPersonFk = vUserFk;
END$$
DELIMITER ;

View File

@ -29,15 +29,12 @@ BEGIN
c.name,
c.phone,
bt.description,
c.salesPersonFk,
u.name username,
d.salesDepartmentFk,
c.salesDepartmentFk,
d.name departmentName,
aai.invoiced,
cnb.lastShipped
FROM vn.client c
JOIN notHasTicket ON notHasTicket.id = c.id
LEFT JOIN account.`user` u ON u.id = c.salesPersonFk
LEFT JOIN vn.department d ON d.id = c.salesDepartmentFk
JOIN vn.`address` a ON a.clientFk = c.id
JOIN vn.postCode pc ON pc.code = a.postalCode

View File

@ -16,8 +16,6 @@ BEGIN
SET NEW.accountingAccount = 4300000000 + NEW.id;
SET NEW.lastSalesPersonFk = NEW.salesPersonFk;
SET NEW.lastSalesDepartmentFk = NEW.salesDepartmentFk ;
SET NEW.lastSalesDepartmentFk = NEW.salesDepartmentFk;
END$$
DELIMITER ;

View File

@ -45,18 +45,7 @@ BEGIN
IF vText IS NOT NULL
THEN
INSERT INTO mail(receiver, replyTo, `subject`, body)
SELECT
CONCAT(IF(ac.id, u.name, 'jgallego'), '@verdnatura.es'),
'administracion@verdnatura.es',
CONCAT('Cliente ', NEW.id),
CONCAT('Recibida la documentación: ', vText)
FROM worker w
LEFT JOIN account.user u ON w.id = u.id AND u.active
LEFT JOIN account.account ac ON ac.id = u.id
WHERE w.id = NEW.salesPersonFk;
INSERT INTO mail(receiver, replyTo, `subject`, body)
SELECT IFNULL(d.notificationEmail, CONCAT('jgallego', '@verdnatura.es')),
SELECT IFNULL(d.notificationEmail, 'jgallego@verdnatura.es'),
'administracion@verdnatura.es',
CONCAT('Cliente ', NEW.id),
CONCAT('Recibida la documentación: ', vText)
@ -64,14 +53,6 @@ BEGIN
WHERE d.id = NEW.salesDepartmentFk;
END IF;
IF NEW.salespersonFk IS NULL AND OLD.salespersonFk IS NOT NULL THEN
IF (SELECT COUNT(clientFk)
FROM clientProtected
WHERE clientFk = NEW.id
) > 0 THEN
CALL util.throw("HAS_CLIENT_PROTECTED");
END IF;
END IF;
IF NEW.salesDepartmentFk IS NULL AND OLD.salesDepartmentFk IS NOT NULL THEN
IF (SELECT COUNT(clientFk)
@ -82,9 +63,6 @@ BEGIN
END IF;
END IF;
IF !(NEW.salesPersonFk <=> OLD.salesPersonFk) THEN
SET NEW.lastSalesPersonFk = IFNULL(NEW.salesPersonFk, OLD.salesPersonFk);
END IF;
IF !(NEW.salesDepartmentFk <=> OLD.salesDepartmentFk) THEN
SET NEW.lastSalesDepartmentFk = IFNULL(NEW.salesDepartmentFk, OLD.salesDepartmentFk);

View File

@ -2,23 +2,15 @@ CREATE OR REPLACE DEFINER=`root`@`localhost`
SQL SECURITY DEFINER
VIEW `vn`.`newBornSales`
AS SELECT
`v`.`importe` AS `amount`,
`v`.`Id_Cliente` AS `clientFk`,
`c`.`salesPersonFk` AS `userFk`,
`c`.`salesDepartmentFk` AS `departmentFk`,
`v`.`fecha` AS `dated`,
`s`.`amount` AS `amount`,
`s`.`clientFk` AS `clientFk`,
`c`.`salesDepartmentFk` AS `salesDepartmentFk`,
`s`.`dated` AS `dated`,
`cn`.`firstShipped` AS `firstShipped`
FROM
((((`bs`.`clientNewBorn` `cn`
JOIN `bs`.`ventas` `v`ON
(`cn`.`firstShipped` + INTERVAL 1 YEAR > `v`.`fecha`
AND `v`.`Id_Cliente` = `cn`.`clientFk`))
JOIN `vn`.`client` `c`ON
(`c`.`id` = `v`.`Id_Cliente`))
LEFT JOIN `account`.`user` `u`ON
(`u`.`id` = `c`.`salesPersonFk`))
JOIN `account`.`role` `r`ON
(`r`.`id` = `u`.`role`))
WHERE
`r`.`name` = 'salesPerson'
AND `u`.`name` NOT IN ('ismaelalcolea', 'ruben');
((`bs`.`clientNewBorn` `cn`
JOIN `bs`.`sale` `s` ON
(`cn`.`firstShipped` + interval 1 year > `s`.`dated`
and `s`.`clientFk` = `cn`.`clientFk`))
JOIN `vn`.`client` `c` ON
(`c`.`id` = `s`.`clientFk`));

View File

@ -40,7 +40,6 @@ AS SELECT `c`.`id` AS `id_cliente`,
`c`.`creditInsurance` AS `creditInsurance`,
`c`.`isCreatedAsServed` AS `isCreatedAsServed`,
`c`.`hasInvoiceSimplified` AS `hasInvoiceSimplified`,
`c`.`salesPersonFk` AS `Id_Trabajador`,
`c`.`salesDepartmentFk` AS `salesDepartmentFk`,
`c`.`isVies` AS `vies`,
`c`.`bankEntityFk` AS `bankEntityFk`,

View File

@ -23,7 +23,7 @@ UPDATE vn.client c
SET c.lastSalesDepartmentFk = b.departmentFk;
DROP TABLE IF EXISTS vn.departmentMana;
CREATE TABLE `vn`.`departmentMana` (
CREATE OR REPLACE TABLE `vn`.`departmentMana` (
`salesDepartmentFk` int(10) NOT NULL,
`size` int(11) NOT NULL DEFAULT 300,
`amount` int(11) NOT NULL DEFAULT 0,
@ -36,7 +36,7 @@ CREATE TABLE `vn`.`departmentMana` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
DROP TABLE IF EXISTS bs.salesByClientDepartment;
CREATE TABLE `bs`.`salesByClientDepartment` (
CREATE OR REPLACE TABLE `bs`.`salesByClientDepartment` (
`dated` date NOT NULL DEFAULT '0000-00-00',
`salesDepartmentFk` int(10) DEFAULT NULL,
`clientFk` int(11) NOT NULL,
@ -67,7 +67,7 @@ INSERT INTO bs.salesByClientDepartment(
DROP TABLE IF EXISTS `vn`.`salesDepartmentProtected`;
CREATE TABLE `vn`.`salesDepartmentProtected` (
CREATE OR REPLACE TABLE `vn`.`salesDepartmentProtected` (
`salesDepartmentFk` int(10) NOT NULL,
PRIMARY KEY (`salesDepartmentFk`),
CONSTRAINT `salesDepartmentProtected_FK` FOREIGN KEY (`salesDepartmentFk`) REFERENCES `vn`.`department` (`id`) ON UPDATE CASCADE
@ -81,7 +81,7 @@ UPDATE vn.observationType
DROP TABLE IF EXISTS `bs`.`portfolio`;
CREATE TABLE `bs`.`portfolio` (
CREATE OR REPLACE TABLE `bs`.`portfolio` (
`salesDepartmentFk` int(10) NOT NULL,
`yeared` int(4) NOT NULL,
`monthed` int(2) NOT NULL,
@ -93,7 +93,7 @@ CREATE TABLE `bs`.`portfolio` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
CREATE TABLE `bs`.`salesDepartmentEvolution` (
CREATE OR REPLACE TABLE `bs`.`salesDepartmentEvolution` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`dated` date NOT NULL DEFAULT '0000-00-00',
`salesDepartmentFk` int(10) DEFAULT NULL,
@ -108,4 +108,19 @@ CREATE TABLE `bs`.`salesDepartmentEvolution` (
RENAME TABLE vn.salespersonConfig TO vn.salesDepartmentConfig;
ALTER TABLE vn.company ADD IF NOT EXISTS phone varchar(15) DEFAULT NULL NULL;
ALTER TABLE vn.company ADD IF NOT EXISTS phone varchar(15) DEFAULT NULL NULL;
CREATE OR REPLACE TABLE `vn`.`departmentManaExcluded` (
`salesDepartmentFk` int(10) NOT NULL,
PRIMARY KEY (`salesDepartmentFk`),
CONSTRAINT `departmentManaExcluded_FK` FOREIGN KEY (`salesDepartmentFk`)
REFERENCES `vn`.`department` (`id`) ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci
COMMENT='Departamentos de venta que tienen que estar excluidos del cálculo del maná';
RENAME TABLE vn.workerManaExcluded TO vn.workerManaExcluded__;
ALTER TABLE vn.workerManaExcluded__
COMMENT='Usuarios que tienen que estar excluidos del cálculo del maná
@deprecated 2024-07-16';

View File

@ -19,7 +19,7 @@
"That payment method requires a BIC": "El método de pago seleccionado requiere un BIC",
"State cannot be blank": "El estado no puede estar en blanco",
"Worker cannot be blank": "El trabajador no puede estar en blanco",
"Cannot change the payment method if no salesperson": "No se puede cambiar la forma de pago si no hay comercial asignado",
"Cannot change the payment method if no salesdepartment": "No se puede cambiar la forma de pago si no hay departamento comercial asignado",
"can't be blank": "El campo no puede estar vacío",
"Observation type must be unique": "El tipo de observación no puede repetirse",
"The credit must be an integer greater than or equal to zero": "The credit must be an integer greater than or equal to zero",

View File

@ -19,7 +19,7 @@
"That payment method requires a BIC": "Este método de pagamento requer um BIC",
"State cannot be blank": "O estado não pode ficar em branco",
"Worker cannot be blank": "O trabalhador não pode ficar em branco",
"Cannot change the payment method if no salesperson": "Não é possível alterar o método de pagamento se não houver vendedor",
"Cannot change the payment method if no salesdepartment": "Impossible de changer le mode de paiement s'il n'y a pas de service commercial",
"can't be blank": "Não pode ficar em branco",
"Observation type must be unique": "O tipo de observação deve ser único",
"The credit must be an integer greater than or equal to zero": "O crédito deve ser um inteiro maior ou igual a zero",

View File

@ -19,7 +19,7 @@
"That payment method requires a BIC": "Esse método de pagamento requer um BIC",
"State cannot be blank": "O estado não pode estar em branco",
"Worker cannot be blank": "O trabalhador não pode estar em branco",
"Cannot change the payment method if no salesperson": "Não é possível alterar o método de pagamento se não houver vendedor",
"Cannot change the payment method if no salesdepartment": "Não é possível alterar o método de pagamento se não houver departamento de vendas",
"can't be blank": "não pode estar em branco",
"Observation type must be unique": "O tipo de observação deve ser único",
"The credit must be an integer greater than or equal to zero": "O crédito deve ser um número inteiro maior ou igual a zero",

View File

@ -61,7 +61,13 @@ module.exports = Self => {
include: {
relation: 'client',
scope: {
fields: ['name', 'salesPersonFk']
fields: ['name', 'salesDepartmentFk'],
include: {
relation: 'salesDepartment',
scope: {
fields: ['id', 'chatName']
}
}
}
}
});
@ -71,9 +77,9 @@ module.exports = Self => {
clientName: claim.client().name,
claimUrl: `${url}claim/${args.id}/summary`,
});
const salesPersonId = claim.client().salesPersonFk;
if (salesPersonId)
await models.Chat.sendCheckingPresence(ctx, salesPersonId, message);
const salesDepartment = claim.client().salesDepartment();
if (salesDepartment)
await models.Chat.sendCheckingPresence(ctx, salesDepartment.chatName, message);
const email = new Email('claim-pickup-order', params);

View File

@ -47,10 +47,11 @@ module.exports = Self => {
include: {
relation: 'client',
scope: {
fields: ['id', 'salesDepartmentFk'],
include: {
relation: 'salesPersonUser',
relation: 'salesDepartment',
scope: {
fields: ['id', 'name']
fields: ['id', 'chatName']
}
}
}
@ -91,8 +92,8 @@ module.exports = Self => {
await Promise.all(promises);
const salesPerson = ticket.client().salesPersonUser();
if (salesPerson) {
const salesDepartment = ticket.client().salesDepartment();
if (salesDepartment) {
const url = await Self.app.models.Url.getUrl();
const message = $t('Created claim', {
@ -102,7 +103,7 @@ module.exports = Self => {
claimUrl: `${url}claim/${newClaim.id}/summary`,
changes: changesMade
});
await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message);
await models.Chat.send(ctx, `@${salesDepartment.chatName}`, message);
}
if (tx) await tx.commit();

View File

@ -51,9 +51,9 @@ module.exports = Self => {
http: {source: 'query'}
},
{
arg: 'salesPersonFk',
arg: 'salesDepartmetnFk',
type: 'number',
description: 'The salesPerson id',
description: 'The salesDepartment id',
http: {source: 'query'}
},
{
@ -164,8 +164,8 @@ module.exports = Self => {
return {'cl.id': {inq: claimIdsByItemFk}};
case 'claimResponsibleFk':
return {'cl.id': {inq: claimIdsByClaimResponsibleFk}};
case 'salesPersonFk':
return {'c.salesPersonFk': value};
case 'salesDepartmentFk':
return {'c.salesDepartmentFk': value};
case 'attenderFk':
return {'cl.workerFk': value};
case 'created':

View File

@ -53,9 +53,9 @@ module.exports = Self => {
{
relation: 'client',
scope: {
fields: ['salesPersonFk', 'name'],
fields: ['salesDepartmentFk', 'name'],
include: {
relation: 'salesPersonUser',
relation: 'salesDepartment',
scope: {
fields: ['id', 'name']
}

View File

@ -53,8 +53,8 @@ module.exports = Self => {
if (addressId)
address = await models.Address.findById(addressId, null, myOptions);
const salesPerson = sale.ticket().client().salesPersonUser();
if (salesPerson) {
const salesDepartment = sale.ticket().client().salesDepartment();
if (salesDepartment) {
const nickname = address && address.nickname || destination.description;
const url = await Self.app.models.Url.getUrl();
const message = $t('Sent units from ticket', {
@ -66,7 +66,7 @@ module.exports = Self => {
ticketUrl: `${url}ticket/${sale.ticketFk}/sale`,
itemUrl: `${url}item/${sale.itemFk}/summary`
});
await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message);
await models.Chat.send(ctx, `@${salesDepartment.chatName}`, message);
}
if (!address) continue;
@ -121,9 +121,9 @@ module.exports = Self => {
relation: 'client',
scope: {
include: {
relation: 'salesPersonUser',
relation: 'salesDepartment',
scope: {
fields: ['id', 'name']
fields: ['id', 'chatName']
}
}
}

View File

@ -60,7 +60,7 @@ describe('claim regularizeClaim()', () => {
try {
const options = {transaction: tx};
spyOn(chatModel, 'sendCheckingPresence').and.callThrough();
spyOn(chatModel, 'send').and.callThrough();
claimEnds = await importTicket(ticketId, claimId, userId, options);
@ -76,8 +76,8 @@ describe('claim regularizeClaim()', () => {
expect(trashTicket.addressFk).toEqual(trashAddress);
expect(claimBefore.claimStateFk).toEqual(pendentState);
expect(claimAfter.claimStateFk).toEqual(resolvedState);
expect(chatModel.sendCheckingPresence).toHaveBeenCalledWith(ctx, 18, 'Trash');
expect(chatModel.sendCheckingPresence).toHaveBeenCalledTimes(4);
expect(chatModel.send).toHaveBeenCalledWith(ctx, '@jvp_equipo', 'Trash');
expect(chatModel.send).toHaveBeenCalledTimes(4);
await tx.rollback();
} catch (e) {
@ -92,7 +92,7 @@ describe('claim regularizeClaim()', () => {
try {
const options = {transaction: tx};
spyOn(chatModel, 'sendCheckingPresence').and.callThrough();
spyOn(chatModel, 'send').and.callThrough();
claimEnds = await importTicket(ticketId, claimId, userId, options);
@ -101,8 +101,8 @@ describe('claim regularizeClaim()', () => {
await models.Claim.regularizeClaim(ctx, claimId, options);
expect(chatModel.sendCheckingPresence).toHaveBeenCalledWith(ctx, 18, 'Bueno');
expect(chatModel.sendCheckingPresence).toHaveBeenCalledTimes(4);
expect(chatModel.send).toHaveBeenCalledWith(ctx, '@jvp_equipo', 'Bueno');
expect(chatModel.send).toHaveBeenCalledTimes(4);
await tx.rollback();
} catch (e) {
@ -117,7 +117,7 @@ describe('claim regularizeClaim()', () => {
try {
const options = {transaction: tx};
spyOn(chatModel, 'sendCheckingPresence').and.callThrough();
spyOn(chatModel, 'send').and.callThrough();
claimEnds = await importTicket(ticketId, claimId, userId, options);
@ -126,8 +126,8 @@ describe('claim regularizeClaim()', () => {
await models.Claim.regularizeClaim(ctx, claimId, options);
expect(chatModel.sendCheckingPresence).toHaveBeenCalledWith(ctx, 18, 'Bueno');
expect(chatModel.sendCheckingPresence).toHaveBeenCalledTimes(4);
expect(chatModel.send).toHaveBeenCalledWith(ctx, '@jvp_equipo', 'Bueno');
expect(chatModel.send).toHaveBeenCalledTimes(4);
await tx.rollback();
} catch (e) {

View File

@ -75,7 +75,7 @@ describe('Update Claim', () => {
const newClaim = await app.models.Claim.create(originalData, options);
const chatModel = app.models.Chat;
spyOn(chatModel, 'sendCheckingPresence').and.callThrough();
spyOn(chatModel, 'send').and.callThrough();
const pendingState = claimStatesMap.pending;
const ctx = {
@ -95,7 +95,7 @@ describe('Update Claim', () => {
let updatedClaim = await app.models.Claim.findById(newClaim.id, null, options);
expect(updatedClaim.observation).toEqual(ctx.args.observation);
expect(chatModel.sendCheckingPresence).toHaveBeenCalled();
expect(chatModel.send).toHaveBeenCalled();
await tx.rollback();
} catch (e) {
@ -113,7 +113,7 @@ describe('Update Claim', () => {
const newClaim = await app.models.Claim.create(originalData, options);
const chatModel = app.models.Chat;
spyOn(chatModel, 'sendCheckingPresence').and.callThrough();
spyOn(chatModel, 'send').and.callThrough();
const canceledState = claimStatesMap.canceled;
const ctx = {
@ -133,7 +133,7 @@ describe('Update Claim', () => {
let updatedClaim = await app.models.Claim.findById(newClaim.id, null, options);
expect(updatedClaim.observation).toEqual(ctx.args.observation);
expect(chatModel.sendCheckingPresence).toHaveBeenCalledTimes(2);
expect(chatModel.send).toHaveBeenCalledTimes(2);
await tx.rollback();
} catch (e) {
@ -151,7 +151,7 @@ describe('Update Claim', () => {
const newClaim = await app.models.Claim.create(originalData, options);
const chatModel = app.models.Chat;
spyOn(chatModel, 'sendCheckingPresence').and.callThrough();
spyOn(chatModel, 'send').and.callThrough();
const claimManagerId = 72;
const ctx = {
@ -174,7 +174,7 @@ describe('Update Claim', () => {
expect(updatedClaim.observation).toEqual(ctx.args.observation);
expect(updatedClaim.claimStateFk).toEqual(ctx.args.claimStateFk);
expect(updatedClaim.workerFk).toEqual(ctx.args.workerFk);
expect(chatModel.sendCheckingPresence).toHaveBeenCalled();
expect(chatModel.send).toHaveBeenCalled();
await tx.rollback();
} catch (e) {

View File

@ -64,13 +64,16 @@ module.exports = Self => {
relation: 'client',
scope: {
include: {
relation: 'salesPersonUser'
relation: 'salesDepartment',
scope: {
fields: ['id', 'chatName']
}
}
}
}
}, myOptions);
// Get sales person from claim client
const salesPerson = claim.client().salesPersonUser();
const salesDepartment = claim.client().salesDepartment();
const changedPickup = args.pickup != claim.pickup;
@ -88,13 +91,13 @@ module.exports = Self => {
const updatedClaim = await claim.updateAttributes(args, myOptions);
// When pickup has been changed
if (salesPerson && changedPickup && updatedClaim.pickup)
await notifyPickUp(ctx, salesPerson.id, claim);
if (salesDepartment && changedPickup && updatedClaim.pickup)
await notifyPickUp(ctx, salesDepartment, claim);
// When claimState has been changed
if (args.claimStateFk) {
const newState = await models.ClaimState.findById(args.claimStateFk, null, myOptions);
await notifyStateChange(ctx, salesPerson.id, claim, newState.description);
await notifyStateChange(ctx, salesDepartment, claim, newState.description);
if (newState.code == 'canceled')
await notifyStateChange(ctx, claim.workerFk, claim, newState.description);
}
@ -108,7 +111,7 @@ module.exports = Self => {
}
};
async function notifyStateChange(ctx, workerId, claim, newState) {
async function notifyStateChange(ctx, salesDepartment, claim, newState) {
const models = Self.app.models;
const url = await models.Url.getUrl();
const $t = ctx.req.__; // $translate
@ -119,10 +122,10 @@ module.exports = Self => {
claimUrl: `${url}claim/${claim.id}/summary`,
newState
});
await models.Chat.sendCheckingPresence(ctx, workerId, message);
await models.Chat.send(ctx, `@${salesDepartment.chatName}`, message);
}
async function notifyPickUp(ctx, workerId, claim) {
async function notifyPickUp(ctx, salesDepartment, claim) {
const models = Self.app.models;
const url = await models.Url.getUrl();
const $t = ctx.req.__; // $translate
@ -133,6 +136,6 @@ module.exports = Self => {
claimUrl: `${url}claim/${claim.id}/summary`,
claimPickup: $t(claim.pickup)
});
await models.Chat.sendCheckingPresence(ctx, workerId, message);
await models.Chat.send(ctx, `@${salesDepartment.chatName}`, message);
}
};

View File

@ -35,7 +35,7 @@ columns:
sageTaxTypeFk: sage tax type
sageTransactionTypeFk: sage transaction type
businessTypeFk: business type
salesPersonFk: sales person
salesDepartmentFk: sales department
hasElectronicInvoice: electronic invoice
payMethodFk: pay method
provinceFk: province
@ -50,6 +50,6 @@ columns:
isCreatedAsServed: created as served
hasInvoiceSimplified: simplified invoice
typeFk: type
lastSalesPersonFk: last salesperson
lastSalesDepartmentFk: last sales department
rating: rating
recommendedCredit: recommended credit

View File

@ -35,7 +35,7 @@ columns:
sageTaxTypeFk: tipo impuesto sage
sageTransactionTypeFk: tipo transacción Sage
businessTypeFk: tipo negocio
salesPersonFk: comercial
salesDepartmentFk: departamento comercial
hasElectronicInvoice: factura electrónica
payMethodFk: método pago
provinceFk: provincia
@ -50,6 +50,6 @@ columns:
isCreatedAsServed: creado como servido
hasInvoiceSimplified: factura simple
typeFk: tipo
lastSalesPersonFk: último comercial
lastSalesDepartmentFk: último departmaneto comercial
rating: clasificación
recommendedCredit: crédito recomendado

View File

@ -29,26 +29,26 @@ module.exports = Self => {
const clients = await Self.rawSql(`
SELECT
c.id AS clientFk,
c.email AS clientEmail,
eu.email salesPersonEmail
FROM client c
JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk
JOIN ticket t ON t.clientFk = c.id
JOIN sale s ON s.ticketFk = t.id
JOIN item i ON i.id = s.itemFk
JOIN itemType it ON it.id = i.typeFk
WHERE c.id IN(?)
AND it.isPackaging = FALSE
AND DATE(t.shipped) BETWEEN ? AND ?
GROUP BY c.id`, [params.clients, params.from, params.to]);
c.id clientFk,
c.email clientEmail,
d.notificationEmail salesDepartmentEmail
FROM client c
JOIN department d ON d.id = c.salesDepartmentFk
JOIN ticket t ON t.clientFk = c.id
JOIN sale s ON s.ticketFk = t.id
JOIN item i ON i.id = s.itemFk
JOIN itemType it ON it.id = i.typeFk
WHERE c.id IN(?)
AND NOT it.isPackaging
AND DATE(t.shipped) BETWEEN ? AND ?
GROUP BY c.id`, [params.clients, params.from, params.to]);
for (const client of clients) {
try {
const args = {
id: client.clientFk,
recipient: client.clientEmail,
replyTo: client.salesPersonEmail,
replyTo: client.salesDepartmentEmail,
from: params.from,
to: params.to
};

View File

@ -50,7 +50,7 @@ module.exports = function(Self) {
fi: data.fi,
socialName: data.socialName,
email: data.email,
salesPersonFk: data.salesPersonFk,
salesDepartmentFk: data.salesDepartmentFk,
postcode: data.postcode,
street: data.street,
city: data.city,

View File

@ -23,7 +23,7 @@ module.exports = Self => {
description: 'The client name',
},
{
arg: 'salesPersonFk',
arg: 'salesDepartmentFk',
type: 'number',
},
{
@ -80,7 +80,7 @@ module.exports = Self => {
? {'c.id': {inq: value}}
: {'c.name': {like: `%${value}%`}};
case 'name':
case 'salesPersonFk':
case 'salesDepartmentFk':
case 'fi':
case 'socialName':
case 'city':
@ -126,8 +126,8 @@ module.exports = Self => {
ct.country,
p.id AS provinceFk,
p.name AS province,
u.id AS salesPersonFk,
u.name AS salesPerson,
d.id salesDepartmentFk,
d.name salesDeparment,
bt.code AS businessTypeFk,
bt.description AS businessType,
pm.id AS payMethodFk,
@ -137,7 +137,7 @@ module.exports = Self => {
stt.CodigoTransaccion AS sageTransactionTypeFk,
stt.Transaccion AS sageTransactionType
FROM client c
LEFT JOIN account.user u ON u.id = c.salesPersonFk
LEFT JOIN department d ON d.id = c.salesDepartmentFk
LEFT JOIN country ct ON ct.id = c.countryFk
LEFT JOIN province p ON p.id = c.provinceFk
LEFT JOIN businessType bt ON bt.code = c.businessTypeFk

View File

@ -23,7 +23,7 @@ module.exports = Self => {
description: 'The client name',
},
{
arg: 'salesPersonFk',
arg: 'salesDeparmentFk',
type: 'number',
},
{
@ -127,7 +127,7 @@ module.exports = Self => {
{'a.provinceFk': value}
]};
case 'name':
case 'salesPersonFk':
case 'salesDepartmentFk':
case 'fi':
case 'socialName':
case 'email':
@ -147,7 +147,6 @@ module.exports = Self => {
c.socialName,
c.phone,
a.phone,
c.mobile,
c.city,
a.city,
c.postcode,
@ -155,13 +154,13 @@ module.exports = Self => {
c.email,
c.isActive,
c.isFreezed,
p.id AS provinceClientFk,
a.provinceFk AS provinceAddressFk,
p.name AS province,
u.id AS salesPersonFk,
u.name AS salesPerson
p.id provinceClientFk,
a.provinceFk provinceAddressFk,
p.name province,
d.id salesDepartmentFk,
d.name salesDepartment
FROM client c
LEFT JOIN account.user u ON u.id = c.salesPersonFk
LEFT JOIN department d ON d.id = c.salesDepartmentFk
LEFT JOIN province p ON p.id = c.provinceFk
JOIN address a ON a.clientFk = c.id
`

View File

@ -42,7 +42,7 @@ module.exports = function(Self) {
}
},
{
relation: 'salesPersonUser',
relation: 'salesDepartment',
scope: {
fields: ['id', 'name']
}

View File

@ -11,6 +11,7 @@ describe('Client Create', () => {
street: 'WALL STREET',
city: 'New York',
businessTypeFk: 'florist',
salesDepartmentFk: 80,
provinceFk: 1
};
const newAccountWithoutEmail = JSON.parse(JSON.stringify(newAccount));

View File

@ -86,14 +86,14 @@ describe('client extendedListFilter()', () => {
}
});
it('should return the clients matching the "salesPersonFk" argument', async() => {
it('should return the clients matching the "salesDepartmementFk" argument', async() => {
const tx = await models.Client.beginTransaction({});
const salesPersonId = 18;
const salesDepartmementId = 80;
try {
const options = {transaction: tx};
const ctx = {req: {accessToken: {userId: 1}}, args: {salesPersonFk: salesPersonId}};
const ctx = {req: {accessToken: {userId: 1}}, args: {salesDepartmentFk: salesDepartmementId}};
const filter = {};
const result = await models.Client.extendedListFilter(ctx, filter, options);
@ -101,7 +101,7 @@ describe('client extendedListFilter()', () => {
const randomResultClient = result[randomIndex];
expect(result.length).toBeGreaterThanOrEqual(5);
expect(randomResultClient.salesPersonFk).toEqual(salesPersonId);
expect(randomResultClient.salesDepartmentFk).toEqual(salesDepartmementId);
await tx.rollback();
} catch (e) {

View File

@ -86,14 +86,14 @@ describe('client filter()', () => {
}
});
it('should return the clients matching the "salesPersonFk" argument', async() => {
it('should return the clients matching the "salesDepartmentFk" argument', async() => {
const tx = await models.Client.beginTransaction({});
const salesPersonId = 18;
const salesDepartmentId = 80;
try {
const options = {transaction: tx};
const ctx = {req: {accessToken: {userId: 1}}, args: {salesPersonFk: salesPersonId}};
const ctx = {req: {accessToken: {userId: 1}}, args: {salesDepartmentFk: salesDepartmentId}};
const filter = {};
const result = await models.Client.filter(ctx, filter, options);
@ -101,7 +101,7 @@ describe('client filter()', () => {
const randomResultClient = result[randomIndex];
expect(result.length).toBeGreaterThanOrEqual(5);
expect(randomResultClient.salesPersonFk).toEqual(salesPersonId);
expect(randomResultClient.salesDepartmentFk).toEqual(salesDepartmentId);
await tx.rollback();
} catch (e) {

View File

@ -46,7 +46,7 @@ module.exports = Self => {
}
},
{
relation: 'salesPersonUser',
relation: 'salesDepartment',
scope: {
fields: ['id', 'name']
}

View File

@ -59,9 +59,9 @@ module.exports = Self => {
SELECT
DISTINCT c.id clientFk,
c.name clientName,
c.salesPersonFk,
c.salesDepartmentFk,
c.businessTypeFk,
u.name salesPersonName,
de.name salesDepartmentName,
d.amount,
co.created,
co.text observation,
@ -77,7 +77,7 @@ module.exports = Self => {
JOIN vn.country cn ON cn.id = c.countryFk
JOIN vn.payMethod pm ON pm.id = c.payMethodFk
LEFT JOIN vn.clientObservation co ON co.clientFk = c.id
LEFT JOIN account.user u ON u.id = c.salesPersonFk
LEFT JOIN department de ON de.id = c.salesDepartmentFk
LEFT JOIN account.user uw ON uw.id = co.workerFk
WHERE
d.created = ?

View File

@ -126,12 +126,12 @@ module.exports = Self => {
done();
}
Self.validate('payMethod', hasSalesMan, {
message: 'Cannot change the payment method if no salesperson'
Self.validate('payMethod', hasSalesDepartment, {
message: 'Cannot change the payment method if no salesdepartment'
});
function hasSalesMan(err) {
if (this.payMethod && !this.salesPersonUser)
function hasSalesDepartment(err) {
if (this.payMethod && !this.salesDepartment)
err();
}
@ -356,18 +356,18 @@ module.exports = Self => {
const $t = httpRequest.__;
const url = await Self.app.models.Url.getUrl();
const salesPersonId = instance.salesPersonFk;
const salesDepartmentId = instance.salesDepartmentFk;
if (salesPersonId) {
if (salesDepartmentId) {
// Send email to client
if (instance.email) {
const {Email} = require('vn-print');
const worker = await models.EmailUser.findById(salesPersonId);
const salesDepartment = await models.department.findById(salesDepartmentId);
const params = {
id: instance.id,
recipientId: instance.id,
recipient: instance.email,
replyTo: worker.email
replyTo: salesDepartment.notificationEmail
};
const email = new Email('payment-update', params);
await email.send();
@ -379,19 +379,16 @@ module.exports = Self => {
clientName: instance.name,
url: fullUrl
});
await models.Chat.sendCheckingPresence(httpCtx, salesPersonId, message);
await models.Chat.send(httpCtx, `@${salesDepartment.chatName}`, message);
}
}
const workerIdBefore = oldInstance.salesPersonFk;
const workerIdAfter = newInstance.salesPersonFk;
const assignmentChanged = workerIdBefore != workerIdAfter;
if (assignmentChanged)
await Self.notifyAssignment(instance, workerIdBefore, workerIdAfter);
if (oldInstance.salesDepartmentFk != newInstance.salesDepartmentFk)
await Self.notifyAssignment(instance, oldInstance.salesDepartmentFk, newInstance.salesDepartmentFk);
});
// Send notification on client worker assignment
Self.notifyAssignment = async function notifyAssignment(client, previousWorkerId, currentWorkerId) {
// Send notification on client department assignment
Self.notifyAssignment = async function notifyAssignment(client, previousDepartmentId, currentDepartmentId) {
const loopBackContext = LoopBackContext.getCurrentContext();
const httpCtx = {req: loopBackContext.active};
const httpRequest = httpCtx.req.http.req;
@ -399,38 +396,38 @@ module.exports = Self => {
const url = await Self.app.models.Url.getUrl();
const models = Self.app.models;
let previousWorker = {name: $t('None')};
let currentWorker = {name: $t('None')};
if (previousWorkerId) {
const worker = await models.Worker.findById(previousWorkerId, {
include: {relation: 'user'}
let previousDepartment = {name: $t('None'), chatName: $t('None')};
let currentDepartment = {name: $t('None'), chatName: $t('None')};
if (previousDepartmentId) {
previousDepartment = await models.Department.findOne({
field: ['name', 'chatName'],
where: {
id: previousDepartmentId
}
});
previousWorker.user = worker && worker.user().name;
previousWorker.name = worker && worker.user().nickname;
}
if (currentWorkerId) {
const worker = await models.Worker.findById(currentWorkerId, {
include: {relation: 'user'}
if (currentDepartmentId) {
currentDepartment = await models.Department.findOne({
field: ['name', 'chatName'],
where: {
id: currentDepartmentId
}
});
currentWorker.user = worker && worker.user().name;
currentWorker.name = worker && worker.user().nickname;
}
const fullUrl = `${url}client/${client.id}/basic-data`;
const message = $t('Client assignment has changed', {
clientId: client.id,
clientName: client.name,
url: fullUrl,
previousWorkerName: previousWorker.name,
currentWorkerName: currentWorker.name
previousDepartmentName: previousDepartment.name,
currentDepartmentName: currentDepartment.name
});
if (previousWorkerId)
await models.Chat.send(httpCtx, `@${previousWorker.user}`, message);
if (previousDepartmentId)
await models.Chat.send(httpCtx, `@${previousDepartment.chatName}`, message);
if (currentWorkerId)
await models.Chat.send(httpCtx, `@${currentWorker.user}`, message);
if (currentDepartmentId)
await models.Chat.send(httpCtx, `@${currentDepartment.chatName}`, message);
};
// Credit change validations

View File

@ -136,7 +136,7 @@
"columnName": "businessTypeFk"
}
},
"salesPersonFk": {
"salesDepartmentFk": {
"type": "number"
},
"hasElectronicInvoice": {
@ -166,10 +166,10 @@
"model": "PayMethod",
"foreignKey": "payMethodFk"
},
"salesPersonUser": {
"salesDepartment": {
"type": "belongsTo",
"model": "VnUser",
"foreignKey": "salesPersonFk"
"model": "Department",
"foreignKey": "salesDepartmentFk"
},
"province": {
"type": "belongsTo",

View File

@ -51,9 +51,9 @@ module.exports = function(Self) {
const data = ctx.instance;
const insurance = await Self.findById(data.id, null, options);
const client = insurance.classification().customer();
const salesPerson = client.salesPersonUser();
const salesDepartment = client.salesDepartment();
if (!salesPerson) return;
if (!salesDepartment) return;
const httpRequest = httpCtx.req.http.req;
const $t = httpRequest.__;
@ -65,6 +65,6 @@ module.exports = function(Self) {
credit: data.credit,
url: fullPath
});
await models.Chat.sendCheckingPresence(httpCtx, salesPerson.id, message);
await models.Chat.send(httpCtx, `@${salesDepartment.chatName}`, message);
});
};

View File

@ -41,11 +41,11 @@
"include": {
"relation": "customer",
"scope": {
"fields": ["name", "salesPersonFk"],
"fields": ["name", "salesDepartmentFk"],
"include": {
"relation": "salesPersonUser",
"relation": "salesDepartment",
"scope": {
"fields": ["id", "name"]
"fields": ["id", "chatName"]
}
}
}

View File

@ -16,8 +16,8 @@ describe('Client Model', () => {
const ctx = {req: activeCtx};
const chatModel = models.Chat;
const instance = {id: 1101, name: 'Bruce Banner'};
const previousWorkerId = 1106; // DavidCharlesHaller
const currentWorkerId = 1107; // HankPym
const previousDepartmetnId = 80; // jvp_equipo
const currentDepartmetnId = 94; // jes_equipo
beforeEach(() => {
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
@ -29,26 +29,26 @@ describe('Client Model', () => {
it('should call to the Chat send() method for both workers', async() => {
spyOn(chatModel, 'send').and.callThrough();
await models.Client.notifyAssignment(instance, previousWorkerId, currentWorkerId);
await models.Client.notifyAssignment(instance, previousDepartmetnId, currentDepartmetnId);
expect(chatModel.send).toHaveBeenCalledWith(ctx, '@davidcharleshaller', `Client assignment has changed`);
expect(chatModel.send).toHaveBeenCalledWith(ctx, '@hankpym', `Client assignment has changed`);
expect(chatModel.send).toHaveBeenCalledWith(ctx, '@jvp_equipo', `Client assignment has changed`);
expect(chatModel.send).toHaveBeenCalledWith(ctx, '@jes_equipo', `Client assignment has changed`);
});
it('should call to the Chat send() method for the previous worker', async() => {
spyOn(chatModel, 'send').and.callThrough();
await models.Client.notifyAssignment(instance, null, currentWorkerId);
await models.Client.notifyAssignment(instance, null, currentDepartmetnId);
expect(chatModel.send).toHaveBeenCalledWith(ctx, '@hankpym', `Client assignment has changed`);
expect(chatModel.send).toHaveBeenCalledWith(ctx, '@jes_equipo', `Client assignment has changed`);
});
it('should call to the Chat send() method for the current worker', async() => {
spyOn(chatModel, 'send').and.callThrough();
await models.Client.notifyAssignment(instance, previousWorkerId, null);
await models.Client.notifyAssignment(instance, previousDepartmetnId, null);
expect(chatModel.send).toHaveBeenCalledWith(ctx, '@davidcharleshaller', `Client assignment has changed`);
expect(chatModel.send).toHaveBeenCalledWith(ctx, '@jvp_equipo', `Client assignment has changed`);
});
});

View File

@ -35,7 +35,7 @@ module.exports = Self => {
description: 'The item description',
},
{
arg: 'salesPersonFk',
arg: 'buyerFkFk',
type: 'integer',
description: 'The buyer of the item',
},
@ -118,7 +118,7 @@ module.exports = Self => {
return {'i.description': {like: `%${value}%`}};
case 'categoryFk':
return {'ic.id': value};
case 'salesPersonFk':
case 'buyerFk':
return {'it.workerFk': value};
case 'supplierFk':
return {'s.id': value};

View File

@ -42,7 +42,13 @@ module.exports = Self => {
include: {
relation: 'client',
scope: {
fields: ['id', 'email', 'isToBeMailed', 'salesPersonFk']
fields: ['id', 'email', 'isToBeMailed', 'salesDepartmentFk'],
include: {
relation: 'salesDepartment',
scope: {
fields: ['id', 'chatName']
}
}
}
}
}, options);
@ -64,11 +70,10 @@ module.exports = Self => {
clientId: client.id,
clientUrl: `${url}claim/${id}/summary`
});
const salesPersonId = client.salesPersonFk;
if (salesPersonId)
await models.Chat.sendCheckingPresence(ctx, salesPersonId, message);
const salesDepartment = ticket.client().salesDepartment();
if (salesDepartment)
await models.Chat.send(ctx, `@${salesDepartment.chatName}`, message);
throw new UserError('Error when sending mail to client', 'mailNotSent');
}
} else {

View File

@ -62,22 +62,20 @@ module.exports = Self => {
cou.country,
c.id clientId,
c.socialName clientSocialName,
u.nickname workerSocialName,
SUM(s.quantity * s.price * ( 100 - s.discount ) / 100) amount,
negativeBase.taxableBase,
negativeBase.ticketFk,
c.isActive,
c.hasToInvoice,
c.isTaxDataChecked,
w.id comercialId,
u.name workerName
c.salesDepartmentFk,
d.name salesDepartmentName
FROM vn.ticket t
JOIN vn.company co ON co.id = t.companyFk
JOIN vn.sale s ON s.ticketFk = t.id
JOIN vn.client c ON c.id = t.clientFk
JOIN vn.country cou ON cou.id = c.countryFk
LEFT JOIN vn.worker w ON w.id = c.salesPersonFk
JOIN account.user u ON u.id = w.id
JOIN vn.department d ON d.id = c.salesDepartmentFk
LEFT JOIN (
SELECT ticketFk, taxableBase
FROM tmp.ticketAmount

View File

@ -37,33 +37,32 @@ module.exports = Self => {
const date = Date.vnNew();
date.setHours(0, 0, 0, 0);
const stmt = new ParameterizedSQL(`
SELECT
v.id,
u.name AS salesPerson,
IFNULL(sc.workerSubstitute, c.salesPersonFk) AS salesPersonFk,
c.id AS clientFk,
c.name AS clientName,
TIME(v.stamp) AS hour,
DATE(v.stamp) AS dated,
wtc.workerFk
FROM hedera.visitUser v
JOIN client c ON c.id = v.userFk
JOIN account.user u ON c.salesPersonFk = u.id
LEFT JOIN sharingCart sc ON sc.workerFk = c.salesPersonFk
AND ? BETWEEN sc.started AND sc.ended
LEFT JOIN workerTeamCollegues wtc
ON wtc.collegueFk = IFNULL(sc.workerSubstitute, c.salesPersonFk)`,
SELECT v.id,
d.name salesDepartment,
c.salesDepartmentFk,
c.id clientFk,
c.name clientName,
TIME(v.stamp) hour,
DATE(v.stamp) dated,
wd.workerFk
FROM hedera.visitUser v
JOIN client c ON c.id = v.userFk
LEFT JOIN department d ON d.id = c.salesDepartmentFk
LEFT JOIN workerDepartment wd ON wd.departmentFk = d.id
LEFT JOIN sharingCart sc ON sc.workerFk = wd.workerFk
AND ? BETWEEN sc.started AND sc.ended`,
[date]);
if (!filter.where) filter.where = {};
const where = filter.where;
where['wtc.workerFk'] = userId;
where['wd.workerFk'] = userId;
stmt.merge(conn.makeWhere(filter.where));
stmt.merge(`GROUP BY clientFk, v.stamp`);
stmt.merge(conn.makePagination(filter));
console.log('stmt: ', stmt);
return conn.executeStmt(stmt, myOptions);
};
};

View File

@ -36,32 +36,30 @@ module.exports = Self => {
const stmt = new ParameterizedSQL(`
SELECT
c.id AS clientFk,
c.name AS clientName,
c.id clientFk,
c.name clientName,
a.nickname,
o.id,
o.date_make,
o.date_send,
o.customer_id,
COUNT(item_id) AS totalRows,
ROUND(SUM(amount * price)) * 1 AS import,
u.id AS salesPersonFk,
u.name AS salesPerson,
am.name AS agencyName
COUNT(item_id) totalRows,
ROUND(SUM(amount * price)) * 1 import,
c.salesDepartmentFk,
d.name salesDepartment,
am.name agencyName
FROM hedera.order o
JOIN hedera.order_row orw ON o.id = orw.order_id
JOIN client c ON c.id = o.customer_id
JOIN address a ON a.id = o.address_id
JOIN agencyMode am ON am.id = o.agency_id
JOIN account.user u ON u.id = c.salesPersonFk
JOIN workerTeamCollegues wtc ON c.salesPersonFk = wtc.collegueFk`);
LEFT JOIN department d ON d.id = c.salesDepartmentFk`);
if (!filter.where) filter.where = {};
const where = filter.where;
where['o.confirmed'] = false;
where['o.date_send'] = {gt: '2001-01-01'};
where['wtc.workerFk'] = userId;
stmt.merge(conn.makeWhere(filter.where));
stmt.merge(conn.makeGroupBy('o.id'));

View File

@ -49,9 +49,9 @@ module.exports = Self => {
type: 'number',
description: `The warehouse id filter`
}, {
arg: 'salesPersonFk',
arg: 'salesDepartmentFk',
type: 'number',
description: `The salesperson id filter`
description: `The salesDepartment id filter`
}, {
arg: 'provinceFk',
type: 'number',
@ -60,10 +60,6 @@ module.exports = Self => {
arg: 'stateFk',
type: 'number',
description: `The state id filter`
}, {
arg: 'myTeam',
type: 'boolean',
description: `Whether to show only tickets for the current logged user team (currently user tickets)`
}, {
arg: 'problems',
type: 'boolean',
@ -112,22 +108,6 @@ module.exports = Self => {
if (typeof options == 'object')
Object.assign(myOptions, options);
// Apply filter by team
const teamMembersId = [];
if (args.myTeam != null) {
const worker = await models.Worker.findById(userId, {
include: {
relation: 'collegues'
}
}, myOptions);
const collegues = worker.collegues() || [];
for (let collegue of collegues)
teamMembersId.push(collegue.collegueFk);
if (teamMembersId.length == 0)
teamMembersId.push(userId);
}
if (ctx.args && args.to) {
const dateTo = args.to;
dateTo.setHours(23, 59, 0, 0);
@ -143,15 +123,8 @@ module.exports = Self => {
return {'t.shipped': {gte: value}};
case 'to':
return {'t.shipped': {lte: value}};
case 'salesPersonFk':
return {'c.salesPersonFk': value};
case 'mine':
case 'myTeam':
if (value)
return {'c.salesPersonFk': {inq: teamMembersId}};
else
return {'c.salesPersonFk': {nin: teamMembersId}};
case 'id':
case 'salesDepartmentFk':
return value ? {'c.salesDepartmentFk': value} : {};
case 'clientFk':
param = `t.${param}`;
return {[param]: value};
@ -162,7 +135,7 @@ module.exports = Self => {
const stmts = [];
let stmt;
stmts.push(`SET @_optimizer_search_depth = @@optimizer_search_depth`);
stmts.push(`SET SESSION optimizer_search_depth = 0`);
@ -187,12 +160,11 @@ module.exports = Self => {
am.name agencyMode,
am.id agencyModeFk,
st.name state,
wk.lastName salesPerson,
d.name salesDepartmentName,
ts.stateFk stateFk,
ts.alertLevel alertLevel,
ts.code alertLevelCode,
u.name userName,
c.salesPersonFk,
c.salesDepartmentFk,
c.credit,
z.hour zoneLanding,
z.name zoneName,
@ -211,8 +183,7 @@ module.exports = Self => {
LEFT JOIN ticketState ts ON ts.ticketFk = t.id
LEFT JOIN state st ON st.id = ts.stateFk
LEFT JOIN client c ON c.id = t.clientFk
LEFT JOIN worker wk ON wk.id = c.salesPersonFk
LEFT JOIN account.user u ON u.id = wk.id
LEFT JOIN department d ON d.id = c.salesDepartmentFk
LEFT JOIN (
SELECT zoneFk,
CAST(

View File

@ -1,12 +1,12 @@
const models = require('vn-loopback/server/server').models;
describe('SalesMonitor clientsFilter()', () => {
it('should return the clients web activity', async() => {
fit('should return the clients web activity', async() => {
const tx = await models.SalesMonitor.beginTransaction({});
try {
const options = {transaction: tx};
const ctx = {req: {accessToken: {userId: 18}}, args: {}};
const ctx = {req: {accessToken: {}}, args: {}};
const from = Date.vnNew();
const to = Date.vnNew();
@ -19,6 +19,8 @@ describe('SalesMonitor clientsFilter()', () => {
}
};
const result = await models.SalesMonitor.clientsFilter(ctx, filter, options);
console.log('result: ', result);
console.log('filter: ', from, to);
expect(result.length).toEqual(3);
@ -34,7 +36,7 @@ describe('SalesMonitor clientsFilter()', () => {
try {
const options = {transaction: tx};
const ctx = {req: {accessToken: {userId: 18}}, args: {}};
const ctx = {req: {accessToken: {}}, args: {}};
const yesterday = Date.vnNew();
yesterday.setDate(yesterday.getDate() - 1);
const today = Date.vnNew();
@ -42,10 +44,12 @@ describe('SalesMonitor clientsFilter()', () => {
today.setHours(23, 59, 59, 59);
const filter = {
where: {
'v.stamp': {between: [yesterday, today]}
}
};
const result = await models.SalesMonitor.clientsFilter(ctx, filter, options);
expect(result.length).toEqual(5);

View File

@ -11,7 +11,7 @@ describe('SalesMonitor ordersFilter()', () => {
const filter = {order: 'date_make DESC'};
const result = await models.SalesMonitor.ordersFilter(ctx, filter, options);
expect(result.length).toEqual(12);
expect(result.length).toEqual(15);
await tx.rollback();
} catch (e) {

View File

@ -161,7 +161,7 @@ describe('SalesMonitor salesFilter()', () => {
}
});
it('should now return the tickets from the worker team', async() => {
it('should now return the tickets from the worker department', async() => {
const tx = await models.SalesMonitor.beginTransaction({});
try {

View File

@ -44,13 +44,9 @@ module.exports = Self => {
type: 'integer',
description: 'The agency mode id'
}, {
arg: 'workerFk',
arg: 'departmentFk',
type: 'integer',
description: 'The salesperson id'
}, {
arg: 'myTeam',
type: 'boolean',
description: 'Whether to show only tickets for the current logged user team (currently user tickets)'
description: 'The department id'
}, {
arg: 'isConfirmed',
type: 'boolean',
@ -79,26 +75,6 @@ module.exports = Self => {
Object.assign(myOptions, options);
const args = ctx.args;
// Apply filter by team
const teamMembersId = [];
if (args.myTeam != null) {
const worker = await models.Worker.findById(userId, {
include: {
relation: 'collegues'
}
}, myOptions);
const collegues = worker.collegues() || [];
for (let collegue of collegues)
teamMembersId.push(collegue.collegueFk);
if (teamMembersId.length == 0)
teamMembersId.push(userId);
}
if (args && args.myTeam)
args.teamIds = teamIds;
const where = buildFilter(args, (param, value) => {
switch (param) {
case 'search':
@ -111,8 +87,8 @@ module.exports = Self => {
return {'o.date_send': {gte: value}};
case 'to':
return {'o.date_send': {lte: value}};
case 'workerFk':
return {'c.salesPersonFk': value};
case 'departmentFk':
return {'c.salesDepartmentFk': value};
case 'clientFk':
return {'o.customer_id': value};
case 'agencyModeFk':
@ -123,11 +99,6 @@ module.exports = Self => {
return {'o.id': value};
case 'isConfirmed':
return {'o.confirmed': value ? 1 : 0};
case 'myTeam':
if (value)
return {'c.salesPersonFk': {inq: teamMembersId}};
else
return {'c.salesPersonFk': {nin: teamMembersId}};
case 'showEmpty':
return {'o.total': {neq: value}};
case 'id':
@ -157,9 +128,8 @@ module.exports = Self => {
o.source_app sourceApp,
o.confirmed isConfirmed,
c.name clientName,
c.salesPersonFk,
u.nickname workerNickname,
u.name name,
c.salesDepartmentFk,
d.name salesDepartmentName,
co.code companyCode,
zed.zoneFk,
zed.hourTheoretical,
@ -169,11 +139,10 @@ module.exports = Self => {
LEFT JOIN address a ON a.id = o.address_id
LEFT JOIN agencyMode am ON am.id = o.agency_id
LEFT JOIN client c ON c.id = o.customer_id
LEFT JOIN worker wk ON wk.id = c.salesPersonFk
LEFT JOIN account.user u ON u.id = wk.id
LEFT JOIN company co ON co.id = o.company_id
LEFT JOIN orderTicket ot ON ot.orderFk = o.id
LEFT JOIN ticket t ON t.id = ot.ticketFk
LEFT JOIN department d ON d.id = c.salesDepartmentFk
LEFT JOIN (
SELECT zoneFk,
CAST(

View File

@ -41,9 +41,9 @@ module.exports = Self => {
{
relation: 'client',
scope: {
fields: ['salesPersonFk', 'name'],
fields: ['salesDepartmentFk', 'name'],
include: {
relation: 'salesPersonUser',
relation: 'salesDepartment',
scope: {
fields: ['id', 'name']
}

View File

@ -51,7 +51,7 @@ module.exports = Self => {
a.city,
am.name agencyModeName,
u.nickname userNickname,
vn.ticketTotalVolume(t.id) volume,
ticketTotalVolume(t.id) volume,
GROUP_CONCAT(DISTINCT i.itemPackingTypeFk ORDER BY i.itemPackingTypeFk) ipt,
c.phone clientPhone,
c.mobile clientMobile,
@ -59,14 +59,14 @@ module.exports = Self => {
a.mobile addressMobile,
a.longitude,
a.latitude,
wm.mediaValue salePersonPhone,
d.pbxQueue saleDepartmentPhone,
t.cmrFk,
t.isSigned signed
FROM vn.route r
JOIN ticket t ON t.routeFk = r.id
JOIN client c ON t.clientFk = c.id
LEFT JOIN vn.sale s ON s.ticketFk = t.id
LEFT JOIN vn.item i ON i.id = s.itemFk
LEFT JOIN sale s ON s.ticketFk = t.id
LEFT JOIN item i ON i.id = s.itemFk
LEFT JOIN ticketState ts ON ts.ticketFk = t.id
LEFT JOIN state st ON st.id = ts.stateFk
LEFT JOIN warehouse wh ON wh.id = t.warehouseFk
@ -80,7 +80,7 @@ module.exports = Self => {
LEFT JOIN agencyMode am ON am.id = t.agencyModeFk
LEFT JOIN account.user u ON u.id = r.workerFk
LEFT JOIN vehicle v ON v.id = r.vehicleFk
LEFT JOIN workerMedia wm ON wm.workerFk = c.salesPersonFk`
LEFT JOIN department d ON d.id = c.salesDepartmentFk`
);
if (!filter.where) filter.where = {};

View File

@ -48,9 +48,9 @@ module.exports = Self => {
relation: 'client',
scope: {
include: {
relation: 'salesPersonUser',
relation: 'salesDepartment',
scope: {
fields: ['id', 'name']
fields: ['id', 'chatName']
}
}
}
@ -66,8 +66,8 @@ module.exports = Self => {
promises.push(deletedSale);
}
const salesPerson = ticket.client().salesPersonUser();
if (salesPerson) {
const salesDepartment = ticket.client().salesDepartment();
if (salesDepartment) {
const url = await Self.app.models.Url.getUrl();
const message = $t('Deleted sales from ticket', {
@ -75,7 +75,7 @@ module.exports = Self => {
ticketUrl: `${url}ticket/${ticketId}/sale`,
deletions: deletions
});
await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message, myOptions);
await models.Chat.send(ctx, `@${salesDepartment.chatName}`, message, myOptions);
}
const deletedSales = await Promise.all(promises);

View File

@ -50,7 +50,7 @@ module.exports = Self => {
saldo: sale.quantity,
trabajador: sale.workerCode,
idMovimiento: sale.saleFk,
salesPersonFk: sale.salesPersonFk,
salesDepartmentFk: sale.salesDepartmentFk,
picked: sale.pickedQuantity,
carros
});

View File

@ -74,17 +74,17 @@ module.exports = Self => {
relation: 'client',
scope: {
include: {
relation: 'salesPersonUser',
relation: 'salesDepartment',
scope: {
fields: ['id', 'name']
fields: ['id', 'chatName']
}
}
}
}
}, myOptions);
const salesPerson = ticket.client().salesPersonUser();
if (salesPerson) {
const salesDepartment = ticket.client().salesDepartment();
if (salesDepartment) {
const url = await Self.app.models.Url.getUrl();
const message = $t('Changed sale reserved state', {
@ -92,7 +92,7 @@ module.exports = Self => {
ticketUrl: `${url}ticket/${ticketId}/sale`,
changes: changesMade
});
await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message, myOptions);
await models.Chat.send(ctx, `@${salesDepartment.chatName.chatName}`, message, myOptions);
}
if (tx) await tx.commit();

View File

@ -1,4 +1,5 @@
const models = require('vn-loopback/server/server').models;
const {ConsoleReporter} = require('jasmine');
const LoopBackContext = require('loopback-context');
describe('sale updatePrice()', () => {
@ -85,14 +86,16 @@ describe('sale updatePrice()', () => {
}
});
it('should set price as a decimal number and check the sale has the mana component changing the salesPersonMana', async() => {
it(`should set price as a decimal number and check the sale
has the mana component changing the SalesDepartmentMana`, async() => {
const tx = await models.Sale.beginTransaction({});
try {
const options = {transaction: tx};
const departmentId = 80;
const price = 5.4;
const originalSalesPersonMana = await models.WorkerMana.findById(18, null, options);
const originalSalesDepartmentMana = await models.DepartmentMana.findById(departmentId, null, options);
const manaComponent = await models.Component.findOne({where: {code: 'mana'}}, options);
const teamOne = 96;
const userId = ctx.req.accessToken.userId;
@ -110,9 +113,9 @@ describe('sale updatePrice()', () => {
expect(updatedSale.price).toBe(price);
expect(createdSaleComponent.value).toEqual(-2.34);
const updatedSalesPersonMana = await models.WorkerMana.findById(18, null, options);
const updatedSalesDepartmentMana = await models.DepartmentMana.findById(departmentId, null, options);
expect(updatedSalesPersonMana.amount).not.toEqual(originalSalesPersonMana.amount);
expect(updatedSalesDepartmentMana?.amount).not.toEqual(originalSalesDepartmentMana?.amount);
await tx.rollback();
} catch (e) {

View File

@ -1,7 +1,7 @@
const models = require('vn-loopback/server/server').models;
describe('sale usesMana()', () => {
const ctx = {req: { accessToken: {userId: 18}}};
const ctx = {req: {accessToken: {userId: 18}}};
it('should return that the worker uses mana', async() => {
const tx = await models.Sale.beginTransaction({});
@ -45,14 +45,13 @@ describe('sale usesMana()', () => {
it('should return that the worker does not use mana because it is excluded', async() => {
const tx = await models.Sale.beginTransaction({});
const buyerId = 35;
const franceDepartmentId = 133;
const buyerCtx = {req: {accessToken: {userId: buyerId}}};
try {
const options = {transaction: tx}
const options = {transaction: tx};
await models.WorkerManaExcluded.create({workerFk: buyerId}, options);
await models.Business.updateAll({workerFk: buyerId}, {departmentFk: franceDepartmentId}, options);
const {departmentFk} = await models.WorkerDepartment.findById(buyerId, null, options);
await models.DepartmentManaExcluded.create({'salesDepartmentFk': departmentFk}, options);
const usesMana = await models.Sale.usesMana(buyerCtx, options);

View File

@ -48,11 +48,10 @@ module.exports = Self => {
include: {
relation: 'client',
scope: {
fields: ['salesPersonFk'],
include: {
relation: 'salesPersonUser',
relation: 'salesDepartment',
scope: {
fields: ['id', 'name']
fields: ['id', 'chatName']
}
}
}
@ -63,22 +62,16 @@ module.exports = Self => {
};
const sale = await models.Sale.findById(id, filter, myOptions);
await models.Sale.canEdit(ctx, [id], myOptions);
const oldPrice = sale.price;
const userId = ctx.req.accessToken.userId;
const usesMana = await models.Sale.usesMana(ctx, myOptions);
const componentCode = usesMana ? 'mana' : 'buyerDiscount';
const discount = await models.Component.findOne({where: {code: componentCode}}, myOptions);
const componentId = discount.id;
const componentValue = newPrice - sale.price;
const where = {
componentFk: componentId,
saleFk: id
};
const where = {componentFk: componentId, saleFk: id};
const saleComponent = await models.SaleComponent.findOne({where}, myOptions);
if (saleComponent) {
await models.SaleComponent.updateAll(where, {
@ -92,12 +85,12 @@ module.exports = Self => {
}, myOptions);
}
await sale.updateAttributes({price: newPrice}, myOptions);
const salesDepartment = sale.ticket().client().salesDepartment();
await Self.rawSql('CALL vn.manaSpellersRequery(?)', [userId], myOptions);
await Self.rawSql('CALL vn.manaSpellers_requery(?)', [salesDepartment.id], myOptions);
await Self.rawSql('CALL vn.ticket_recalc(?, NULL)', [sale.ticketFk], myOptions);
const salesPerson = sale.ticket().client().salesPersonUser();
if (salesPerson) {
if (salesDepartment) {
const url = await Self.app.models.Url.getUrl();
const message = $t('Changed sale price', {
ticketId: sale.ticket().id,
@ -109,7 +102,7 @@ module.exports = Self => {
ticketUrl: `${url}ticket/${sale.ticket().id}/sale`,
itemUrl: `${url}item/${sale.itemFk}/summary`
});
await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message, myOptions);
await models.Chat.send(ctx, `@${salesDepartment.chatName}`, message, myOptions);
}
if (tx) await tx.commit();

View File

@ -50,9 +50,9 @@ module.exports = Self => {
relation: 'client',
scope: {
include: {
relation: 'salesPersonUser',
relation: 'salesDepartment',
scope: {
fields: ['id', 'name']
fields: ['id', 'chatName']
}
}
}
@ -69,8 +69,8 @@ module.exports = Self => {
originalQuantity: newQuantity
}, myOptions);
const salesPerson = sale.ticket().client().salesPersonUser();
if (salesPerson) {
const salesDepartment = sale.ticket().client().salesDepartment();
if (salesDepartment) {
const url = await Self.app.models.Url.getUrl();
const message = $t('Changed sale quantity', {
ticketId: sale.ticket().id,
@ -81,8 +81,7 @@ module.exports = Self => {
ticketUrl: `${url}ticket/${sale.ticket().id}/sale`,
itemUrl: `${url}item/${sale.itemFk}/summary`
});
await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message, myOptions);
await models.Chat.send(ctx, `@${salesDepartment.chatName}`, message, myOptions);
}
if (tx) await tx.commit();

View File

@ -21,15 +21,16 @@ module.exports = Self => {
if (typeof options == 'object')
Object.assign(myOptions, options);
const isManaExcluded = await models.WorkerManaExcluded.findById(userId, null, myOptions);
const {departmentFk} = await models.WorkerDepartment.findById(userId, null, myOptions);
const isManaExcluded = await models.DepartmentManaExcluded.findById(departmentFk, null, myOptions);
if (isManaExcluded) return false;
const salesDepartment = await models.Department.findOne({where: {code: 'VT'}, fields: 'id'}, myOptions);
const departments = await models.Department.getLeaves(ctx, salesDepartment.id, null, myOptions);
const workerDepartment = await models.WorkerDepartment.findById(userId, null, myOptions);
if (!workerDepartment) return false;
if (!departmentFk) return false;
const usesMana = departments.find(department => department.id == workerDepartment.departmentFk);
const usesMana = departments.find(department => department.id == departmentFk);
return usesMana ? true : false;
};

View File

@ -111,8 +111,8 @@ module.exports = Self => {
return {'t.shipped': {lte: value}};
case 'warehouse':
return {'w.id': value};
case 'salesPersonFk':
return {'c.salesPersonFk': value};
case 'salesDepartmentFk':
return {'c.salesDepartmentFk': value};
}
});
@ -143,9 +143,9 @@ module.exports = Self => {
t.warehouseFk,
t.clientFk,
w.name warehouse,
u.nickname salesPersonNickname,
d.name salesDepartmentName,
ua.name attenderName,
c.salesPersonFk,
c.salesDepartmentFk,
ua2.name requesterName
FROM ticketRequest tr
LEFT JOIN ticketWeekly tw on tw.ticketFk = tr.ticketFk
@ -154,8 +154,7 @@ module.exports = Self => {
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.id
LEFT JOIN department d ON d.id = c.salesDepartmentFk
LEFT JOIN worker wka ON wka.id = tr.attenderFk
LEFT JOIN account.user ua ON ua.id = wka.id
LEFT JOIN account.user ua2 ON ua2.id = tr.requesterFk`);

View File

@ -53,13 +53,13 @@ module.exports = Self => {
const stmts = [];
const stmt = new ParameterizedSQL(
`SELECT t.id AS ticketFk, c.id AS clientFk, c.name AS clientName, tw.weekDay,
wh.name AS warehouseName, u.id AS workerFk, u.name AS userName, u.nickName, tw.agencyModeFk
`SELECT t.id ticketFk, c.id clientFk, c.name clientName, tw.weekDay,
wh.name warehouseName, d.id AS departmentFk, d.name departmentName, tw.agencyModeFk
FROM ticketWeekly tw
JOIN ticket t ON t.id = tw.ticketFk
JOIN client c ON c.id = t.clientFk
JOIN account.user u ON u.id = c.salesPersonFk
JOIN warehouse wh ON wh.id = t.warehouseFk`
JOIN warehouse wh ON wh.id = t.warehouseFk
LEFT JOIN department d ON d.id = c.salesDepartmentFk`
);
stmt.merge(conn.makeSuffix(filter));

View File

@ -52,9 +52,9 @@ module.exports = Self => {
relation: 'client',
scope: {
include: {
relation: 'salesPersonUser',
relation: 'salesDepartment',
scope: {
fields: ['id', 'name']
fields: ['id', 'chatName']
}
}
}
@ -79,8 +79,8 @@ module.exports = Self => {
const addition = `\r\n-${sale.itemFk}: ${sale.concept} (${sale.quantity})`;
const salesPerson = ticket.client().salesPersonUser();
if (salesPerson) {
const salesDepartment = ticket.client().salesDepartment();
if (salesDepartment) {
const url = await Self.app.models.Url.getUrl();
const message = $t('Added sale to ticket', {
@ -88,7 +88,7 @@ module.exports = Self => {
ticketUrl: `${url}ticket/${id}/sale`,
addition: addition
});
await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message);
await models.Chat.send(ctx, `@${salesDepartment.chatName}`, message);
}
if (tx) await tx.commit();

View File

@ -38,11 +38,11 @@ module.exports = Self => {
c.id clientFk,
c.name clientName,
c.email recipient,
c.salesPersonFk,
c.salesDepartmentFk,
c.isToBeMailed,
c.hasToInvoice,
co.hasDailyInvoice,
eu.email salesPersonEmail,
d.notificationEmail salesDepartmentEmail,
t.addressFk
FROM ticket t
JOIN agencyMode am ON am.id = t.agencyModeFk
@ -52,7 +52,7 @@ module.exports = Self => {
JOIN client c ON c.id = t.clientFk
JOIN province p ON p.id = c.provinceFk
JOIN country co ON co.id = p.countryFk
LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk
LEFT JOIN department d ON d.id = c.salesDepartmentFk
WHERE (al.code = 'PACKED' OR (am.code = 'refund' AND al.code <> 'delivered'))
AND DATE(t.shipped) BETWEEN ? - INTERVAL 2 DAY AND util.dayEnd(?)
AND t.refFk IS NULL
@ -107,7 +107,6 @@ module.exports = Self => {
JOIN province p ON p.id = c.provinceFk
LEFT JOIN autonomy a ON a.id = p.autonomyFk
JOIN country co ON co.id = p.countryFk
LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk
LEFT JOIN itemTaxCountry itc ON itc.itemFk = i.id
AND itc.countryFk = su.countryFk
LEFT JOIN vn.invoiceOutSerial ios ON ios.taxAreaFk = 'WORLD'

View File

@ -44,11 +44,11 @@ module.exports = Self => {
t.companyFk,
c.name clientName,
c.email recipient,
c.salesPersonFk,
c.salesDepartmentFk,
c.isToBeMailed,
c.hasToInvoice,
co.hasDailyInvoice,
eu.email salesPersonEmail
d.notificationEmail salesDepartmentEmail
FROM expedition e
JOIN ticket t ON t.id = e.ticketFk
JOIN ticketState ts ON ts.ticketFk = t.id
@ -56,7 +56,7 @@ module.exports = Self => {
JOIN client c ON c.id = t.clientFk
JOIN province p ON p.id = c.provinceFk
JOIN country co ON co.id = p.countryFk
LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk
LEFT JOIN department d ON d.id = c.salesDepartmentFk
WHERE al.code = 'PACKED'
AND t.agencyModeFk IN(?)
AND t.warehouseFk = ?

View File

@ -33,11 +33,11 @@ module.exports = Self => {
t.companyFk,
c.name clientName,
c.email recipient,
c.salesPersonFk,
c.salesDepartmentFk,
c.isToBeMailed,
c.hasToInvoice,
co.hasDailyInvoice,
eu.email salesPersonEmail
d.notificationEmail salesDepartmentEmail
FROM expedition e
JOIN ticket t ON t.id = e.ticketFk
JOIN ticketState ts ON ts.ticketFk = t.id
@ -45,7 +45,7 @@ module.exports = Self => {
JOIN client c ON c.id = t.clientFk
JOIN province p ON p.id = c.provinceFk
JOIN country co ON co.id = p.countryFk
LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk
LEFT JOIN department d ON d.id = c.salesDepartmentFk
WHERE al.code = 'PACKED'
AND t.routeFk = ?
AND t.refFk IS NULL

View File

@ -33,11 +33,11 @@ module.exports = Self => {
t.companyFk,
c.name clientName,
c.email recipient,
c.salesPersonFk,
c.salesDepartmentFk,
c.isToBeMailed,
c.hasToInvoice,
co.hasDailyInvoice,
eu.email salesPersonEmail
d.notificationEmail salesDepartmentEmail
FROM expedition e
JOIN ticket t ON t.id = e.ticketFk
JOIN ticketState ts ON ts.ticketFk = t.id
@ -45,7 +45,7 @@ module.exports = Self => {
JOIN client c ON c.id = t.clientFk
JOIN province p ON p.id = c.provinceFk
JOIN country co ON co.id = p.countryFk
LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk
LEFT JOIN department d ON d.id = c.salesDepartmentFk
WHERE al.code = 'PACKED'
AND t.id = ?
AND t.refFk IS NULL

View File

@ -38,7 +38,7 @@ module.exports = async function(ctx, Self, tickets, reqArgs = {}) {
attachments: [],
};
const isToBeMailed = ticket.recipient && ticket.salesPersonFk && ticket.isToBeMailed;
const isToBeMailed = ticket.recipient && ticket.salesDepartmentFk && ticket.isToBeMailed;
if (invoiceOut) {
const args = {

View File

@ -182,16 +182,14 @@ module.exports = Self => {
{
relation: 'client',
scope: {
fields: 'salesPersonFk'
fields: 'salesDepartmentFk'
},
include: [
{
relation: 'address',
scope: {
fields: 'nickname'
}
include: {
relation: 'salesDepartment',
scope: {
fields: ['id', 'chatName']
}
]
}
},
]
}, myOptions);
@ -261,8 +259,8 @@ module.exports = Self => {
const oldProperties = await loggable.translateValues(Self, changes.old);
const newProperties = await loggable.translateValues(Self, changes.new);
const salesPersonId = ticketToChange.client().salesPersonFk;
if (salesPersonId) {
const salesDepartment = ticketToChange.client().salesDepartment();
if (salesDepartment) {
const url = await Self.app.models.Url.getUrl();
let changesMade = '';
@ -278,7 +276,7 @@ module.exports = Self => {
ticketUrl: `${url}ticket/${args.id}/sale`,
changes: changesMade
});
await models.Chat.sendCheckingPresence(ctx, salesPersonId, message);
await models.Chat.send(ctx, `@${salesDepartment.chatName}`, message);
}
}

View File

@ -59,9 +59,9 @@ module.exports = Self => {
description: `The warehouse id filter`
},
{
arg: 'salesPersonFk',
arg: 'salesDepartmentFk',
type: 'number',
description: `The salesperson id filter`
description: `The salesDepartment id filter`
},
{
arg: 'provinceFk',
@ -73,11 +73,6 @@ module.exports = Self => {
type: 'number',
description: `The state id filter`
},
{
arg: 'myTeam',
type: 'boolean',
description: `Whether to show only tickets for the current logged user team (For now it shows only the current user tickets)`
},
{
arg: 'problems',
type: 'boolean',
@ -183,8 +178,8 @@ module.exports = Self => {
return {'t.nickname': {like: `%${value}%`}};
case 'refFk':
return {'t.refFk': value};
case 'salesPersonFk':
return {'c.salesPersonFk': value};
case 'salesDepartmentFk':
return {'c.salesDepartmentFk': value};
case 'provinceFk':
return {'a.provinceFk': value};
case 'stateFk':
@ -194,9 +189,9 @@ module.exports = Self => {
case 'mine':
case 'myTeam':
if (value)
return {'c.salesPersonFk': {inq: teamMembersId}};
return {'c.salesDepartmentFk': {inq: teamMembersId}};
else
return {'c.salesPersonFk': {nin: teamMembersId}};
return {'c.salesDepartmentFk': {nin: teamMembersId}};
case 'alertLevel':
return {'ts.alertLevel': value};
@ -249,12 +244,11 @@ module.exports = Self => {
am.id AS agencyModeFk,
st.name AS state,
st.classColor,
wk.lastName AS salesPerson,
d.name AS salesDepartment,
ts.stateFk AS stateFk,
ts.alertLevel AS alertLevel,
ts.code AS alertLevelCode,
u.name AS userName,
c.salesPersonFk,
c.salesDepartmentFk,
z.hour AS zoneLanding,
HOUR(z.hour) AS zoneHour,
MINUTE(z.hour) AS zoneMinute,
@ -271,8 +265,7 @@ module.exports = Self => {
LEFT JOIN ticketState ts ON ts.ticketFk = t.id
LEFT JOIN state st ON st.id = ts.stateFk
LEFT JOIN client c ON c.id = t.clientFk
LEFT JOIN worker wk ON wk.id = c.salesPersonFk
LEFT JOIN account.user u ON u.id = wk.id
LEFT JOIN department d ON d.id = c.salesDepartmentFk
LEFT JOIN route r ON r.id = t.routeFk`);
if (args.orderFk) {

View File

@ -1,6 +1,6 @@
module.exports = Self => {
Self.remoteMethod('getSalesPersonMana', {
description: 'Returns the mana amount of a salesperson for a ticket',
Self.remoteMethod('getSalesDepartmentMana', {
description: 'Returns the mana amount of a salesDepartment for a ticket',
accessType: 'READ',
accepts: [{
arg: 'id',
@ -13,12 +13,12 @@ module.exports = Self => {
root: true
},
http: {
path: `/:id/getSalesPersonMana`,
path: `/:id/getSalesDepartmentMana`,
verb: 'GET'
}
});
Self.getSalesPersonMana = async(ticketId, options) => {
Self.getSalesDepartmentMana = async(ticketId, options) => {
const myOptions = {};
const models = Self.app.models;
@ -29,7 +29,7 @@ module.exports = Self => {
include: [{
relation: 'client',
scope: {
fields: ['salesPersonFk']
fields: ['salesDepartmentFk']
}
}],
fields: ['id', 'clientFk']
@ -37,10 +37,7 @@ module.exports = Self => {
if (!ticket) return 0;
const mana = await models.WorkerMana.findOne({
where: {
workerFk: ticket.client().salesPersonFk
},
const mana = await models.DepartmentMana.findOne({
fields: 'amount'
}, myOptions);

View File

@ -42,7 +42,13 @@ module.exports = Self => {
include: [{
relation: 'client',
scope: {
fields: ['id', 'salesPersonFk']
fields: ['id', 'salesDepartmentFk'],
include: {
relation: 'salesDepartment',
scope: {
fields: ['id', 'chatName']
}
}
}
}]
}, myOptions);
@ -53,15 +59,15 @@ module.exports = Self => {
if (!ticketLog || now > maxDate)
throw new UserError(`You can only restore a ticket within the first hour after deletion`);
// Send notification to salesPerson
const salesPersonId = ticket.client().salesPersonFk;
if (salesPersonId) {
// Send notification to department
const salesDepartment = ticket.client().salesDepartment();
if (salesDepartment) {
const url = await Self.app.models.Url.getUrl();
const message = $t(`I have restored the ticket id`, {
id: id,
url: `${url}ticket/${id}/summary`
});
await models.Chat.sendCheckingPresence(ctx, salesPersonId, message);
await models.Chat.send(ctx, `@${salesDepartment.chatName}`, message);
}
const fullYear = Date.vnNew().getFullYear();

View File

@ -105,26 +105,26 @@ module.exports = Self => {
include: [{
relation: 'client',
scope: {
fields: ['id', 'salesPersonFk'],
fields: ['id', 'salesDepartmentFk'],
include: {
relation: 'salesPersonUser',
relation: 'salesDepartment',
scope: {
fields: ['id', 'name']
fields: ['id', 'chatName']
}
}
}
}]
}, myOptions);
// Send notification to salesPerson
const salesPersonUser = ticket.client().salesPersonUser();
if (salesPersonUser && sales.length) {
// Send notification to salesDepartment
const salesDepartment = ticket.client().salesDepartment();
if (salesDepartment && sales.length) {
const url = await Self.app.models.Url.getUrl();
const message = $t(`I have deleted the ticket id`, {
id: id,
url: `${url}ticket/${id}/summary`
});
await models.Chat.send(ctx, `@${salesPersonUser.name}`, message);
await models.Chat.send(ctx, `@${salesDepartment.chatName}`, message);
}
const updatedTicket = await ticket.updateAttribute('isDeleted', true, myOptions);

Some files were not shown because too many files have changed in this diff Show More