WIP: 6802-Clientes-gestionados-por-equipos #2516

Draft
carlosap wants to merge 6 commits from 6802-Clientes-gestionados-por-equipos into dev
132 changed files with 1164 additions and 1251 deletions

View File

@ -64,11 +64,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

@ -132,7 +132,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

@ -1314,7 +1314,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');
@ -1768,7 +1768,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

@ -1831,7 +1831,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');
@ -1846,7 +1845,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');
@ -2070,7 +2068,6 @@ INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','cmrpallet_add','P
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

@ -2743,7 +2743,7 @@ BEGIN
INSERT INTO claimLog
SET `action` = 'delete',
`changedModel` = 'ClaimBeginning',
`changedModelId` = OLD.id,
`userFk` = account.myUser_getId();
END */;;
DELIMITER ;

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
@ -1816,9 +1816,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
@ -1826,8 +1825,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

@ -12,7 +12,7 @@ BEGIN
INSERT INTO analisis_ventas (
Familia,
Reino,
Comercial,
salesDepartmentFk,
Comprador,
Provincia,
almacen,
@ -25,8 +25,8 @@ BEGIN
SELECT
it.name,
ic.name,
c.salesDepartmentFk,
w.code,
w2.code,
p.name,
wa.name,
tm.year,
@ -38,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

@ -1,24 +1,43 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `bi`.`defaultersFromDate`(IN vDate DATE)
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `bi`.`defaultersFromDate`(
IN vDated DATE
)
BEGIN
SELECT t1.*, c.name Cliente, w.code workerCode, c.payMethodFk pay_met_id, c.dueDay Vencimiento
FROM (
-- Filtramos aquellos clientes cuyo saldo se ha incrementado de ayer a hoy
select * from(
select today.client, today.amount todayAmount, yesterday.amount yesterdayAmount, round(yesterday.amount - today.amount,2) as difference, defaulterSince
from
(select client, amount, defaulterSince
from defaulters
where date = vDate and hasChanged) today
join
(select client, amount
from defaulters
where date = TIMESTAMPADD(DAY,-1,vDate)) yesterday using(client)
having today.amount > 0 and difference <> 0
) newDefaulters
)t1 left join vn.client c ON c.id = t1.client
left join vn.worker w ON w.id = c.salesPersonFk;
/**
* Retorna la info de clientes morosos a una fecha
*
* @param vDated Fecha a comprobar
*/
WITH todayDefaulters AS(
SELECT client, amount, defaulterSince
FROM bi.defaulters
WHERE date = vDated
AND hasChanged
), yesterdayDefaulters AS(
SELECT client, amount
FROM bi.defaulters
WHERE date = vDated - INTERVAL 1 DAY
), newDefaulters AS(
SELECT td.client,
td.amount todayAmount,
yd.amount yesterdayAmount,
ROUND(yd.amount - td.amount, 2) difference,
defaulterSince
FROM todayDefaulters td
JOIN yesterdayDefaulters yd ON yd.client = td.client
WHERE td.amount > 0
HAVING difference <> 0
) SELECT nd.client,
nd.todayAmount,
nd.yesterdayAmount,
nd.difference,
nd.defaulterSince,
c.name Cliente,
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.department d ON d.id = c.salesDepartmentFk;
END$$
DELIMITER ;

View File

@ -1,42 +0,0 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `bs`.`campaignComparative`(vDateFrom DATE, vDateTo DATE)
BEGIN
SELECT
workerName,
id,
name,
CAST(SUM(previousAmmount) AS DECIMAL(10, 0)) AS previousAmmount,
CAST(SUM(currentAmmount) AS DECIMAL(10, 0)) AS currentAmmount
FROM (
(SELECT
CONCAT(w.firstname, ' ', w.lastName) AS workerName,
c.id,
c.name,
SUM(v.importe) AS previousAmmount,
0 currentAmmount
FROM bs.ventas v
INNER JOIN vn.`client` c ON v.Id_Cliente = c.id
INNER JOIN vn.worker w ON c.salesPersonFk = w.id
WHERE v.fecha BETWEEN DATE_ADD(vDateFrom, INTERVAL - 1 YEAR)
AND DATE_ADD(vDateTo, INTERVAL - 1 YEAR)
GROUP BY w.id, v.Id_Cliente)
UNION ALL
(SELECT
CONCAT(w.firstname, ' ', w.lastName) AS workerName,
c.id,
c.name,
0 AS previousAmmount,
SUM(s.quantity * s.price) AS currentAmmount
FROM vn.sale s
JOIN vn.ticket t ON t.id = s.ticketFk
JOIN vn.client c ON c.id = t.clientFk
JOIN vn.worker w ON c.salesPersonFk = w.id
WHERE t.shipped BETWEEN vDateFrom
AND vDateTo
GROUP BY w.id, c.id)
) comparative
GROUP BY workerName, id
HAVING (previousAmmount <> 0 OR currentAmmount <> 0)
ORDER BY workerName, id;
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,7 +20,7 @@ BEGIN
DELETE FROM payMethodClientEvolution
WHERE dated < vFourYearsAgo;
DELETE FROM salesByclientSalesPerson
DELETE FROM salesByClientDepartment
WHERE dated < vFourYearsAgo;
DELETE FROM m3

View File

@ -0,0 +1,61 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `bs`.`clientDied_calc`(
vDays INT,
vCountryCode VARCHAR(2)
)
BEGIN
/**
* Recalcula los clientes inactivos y hace insert en la tabla clientDied
* estableciendo hasta 3 avisos en función del periodo y el código de país.
*
* @param vDays El número de días a considerar para la inactividad del cliente
* @param vCountryCode El código del país para filtrar los clientes
*/
DECLARE vFirstPeriod , vSecondPeriod, vThridPeriod DATE;
SET vFirstPeriod = util.VN_CURDATE() - INTERVAL vDays DAY;
SET vSecondPeriod = util.VN_CURDATE() - INTERVAL vDays * 2 DAY;
SET vThridPeriod = util.VN_CURDATE() - INTERVAL vDays * 3 DAY;
DELETE cd.* FROM clientDied cd
JOIN (
SELECT c.id FROM vn.client c
JOIN vn.country co ON co.id = c.countryFk
WHERE co.code = vCountryCode
) sub ON sub.id = cd.clientFk;
INSERT INTO clientDied (clientFk, lastInvoiced, warning)
SELECT c.id,
sub.lastShipped,
CASE
WHEN lastShipped < vThridPeriod OR lastShipped IS NULL THEN 'third'
WHEN lastShipped < vSecondPeriod THEN 'second'
WHEN lastShipped < vFirstPeriod THEN 'first'
END
FROM vn.client c
JOIN vn.country co ON co .id = c.countryFk
JOIN vn.department w ON w.id = c.salesDepartmentFk
JOIN vn.departmentMana dm ON dm.salesDepartmentFk = c.salesDepartmentFk
LEFT JOIN (
SELECT c.id, DATE(MAX(t.shipped)) lastShipped
FROM vn.client c
LEFT JOIN vn.ticket t ON t.clientFk = c.id
LEFT JOIN vn.country co ON co.id = c.countryFk
WHERE co.code = vCountryCode
AND (t.shipped <= util.VN_CURDATE() OR t.shipped IS NULL)
GROUP BY c.id
) sub ON sub.id = c.id
LEFT JOIN vn.clientObservation cob ON cob.clientFk = c.id
AND cob.created > vThridPeriod
WHERE (sub.lastShipped < vFirstPeriod OR sub.lastShipped IS NULL)
AND c.created < vThridPeriod
AND co.code = vCountryCode
AND cob.`text` IS NULL
AND c.id NOT IN (
SELECT DISTINCT clientFk
FROM vn.ticket
WHERE refFk IS NULL
AND shipped >= vFirstPeriod
)
GROUP BY c.id;
END$$
DELIMITER ;

View File

@ -33,9 +33,7 @@ BEGIN
END
FROM vn.client c
JOIN vn.country co ON co .id = c.countryFk
JOIN vn.worker w ON w.id = c.salesPersonFk
JOIN vn.worker b ON b.id = w.bossFk
JOIN vn.workerMana wm ON wm.workerFk = c.salesPersonFk
JOIN vn.departmentMana dm ON dm.salesDepartmentFk = c.salesDepartmentFk
LEFT JOIN (
SELECT c.id, DATE(MAX(t.shipped)) lastShipped
FROM vn.client c

View File

@ -0,0 +1,39 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root``localhost` PROCEDURE `bs`.`comparativeCampaign`(vDateFrom DATE, vDateTo DATE)
BEGIN
SELECT deparmentName,
id clientFk,
name clientName,
CAST(SUM(previousAmmount) AS DECIMAL(10, 0)) previousAmmount,
CAST(SUM(currentAmmount) AS DECIMAL(10, 0)) currentAmmount
FROM ((SELECT
d.name deparmentName,
c.id,
c.name,
SUM(s.amount) previousAmmount,
0 currentAmmount
FROM sale s
JOIN vn.`client` c ON s.clientFk = c.id
JOIN vn.department d ON d.id = c.salesDepartmentFk
WHERE s.dated BETWEEN DATE_ADD(vDateFrom, INTERVAL - 1 YEAR)
AND DATE_ADD(vDateTo, INTERVAL - 1 YEAR)
GROUP BY d.id, s.clientFk)
UNION ALL
(SELECT
d.name deparmentName,
c.id,
c.name,
0 AS previousAmmount,
SUM(s.quantity * s.price) currentAmmount
FROM vn.sale s
JOIN vn.ticket t ON t.id = s.ticketFk
JOIN vn.client c ON c.id = t.clientFk
JOIN vn.department d ON d.id = c.salesDepartmentFk
WHERE t.shipped BETWEEN vDateFrom AND vDateTo
GROUP BY d.id, c.id)
) comparative
GROUP BY deparmentName, id
HAVING previousAmmount OR currentAmmount
ORDER BY deparmentName, id;
END$$
DELIMITER ;

View File

@ -27,9 +27,9 @@ BEGIN
SELECT id INTO vManaGreugeTypeId
FROM vn.greugeType WHERE code = 'mana';
SELECT manaFromDays, manaToDays
INTO vManaFromDays, vManaToDays
FROM vn.salespersonConfig;
SELECT manaFromDays, manaToDays
INTO vManaFromDays, vManaToDays
FROM vn.salesDepartmentConfig;
SELECT MAX(dated) INTO vFromDated
FROM vn.clientManaCache;
@ -43,7 +43,7 @@ BEGIN
IF vFromDated IS NULL THEN
SELECT manaDateFrom
INTO vFromDated
FROM vn.salespersonConfig;
FROM vn.salesDepartmentConfig;
END IF;
WHILE vFromDated + INTERVAL vManaToDays DAY < util.VN_CURDATE() DO

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
JOIN vn.salespersonConfig spc
SET wm.pricesModifierRate =
GROUP BY c.lastSalesDepartmentFk
)avgPortfolioWeight ON avgPortfolioWeight.lastSalesDepartmentFk = dm.salesDepartmentFk
JOIN vn.salesDepartmentConfig sdc
SET dm.pricesModifierRate =
IFNULL(
GREATEST(
spc.manaMinRate,
sdc.manaMinRate,
LEAST(
spc.manaMaxRate,
ROUND( - wm.amount / avgPortfolioWeight.amount, 3)
sdc.manaMaxRate,
ROUND( - dm.amount / avgPortfolioWeight.amount, 3)
)
)
,0);

View File

@ -0,0 +1,27 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `bs`.`porfolio_add`()
BEGIN
/**
* Inserta en la tabla @bs.portfolio las ventas desde el año pasado
* agrupadas por equipo, año y mes
*/
DECLARE vYear INT DEFAULT YEAR(util.VN_CURDATE()) - 1;
CALL util.time_generate(
MAKEDATE(vYear, 1),
(SELECT MAX(dated) FROM sale)
);
INSERT INTO portfolio(yeared, monthed , saleDepartmentFk, Amount)
SELECT t.`year`, t.`month`, w.code, SUM(s.amount)
FROM tmp.time t
JOIN sale s on t.dated = s.dated
JOIN vn.client c on c.id = s.clientFk
JOIN vn.department d ON d.id = c.salesDepartmentFk
GROUP BY d.id, t.`year`, t.`month`;
DROP TEMPORARY TABLE tmp.time;
END$$
DELIMITER ;

View File

@ -1,20 +0,0 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `bs`.`salePersonEvolutionAdd`(IN vDateStart DATETIME)
BEGIN
DELETE FROM bs.salePersonEvolution
WHERE dated <= DATE_SUB(util.VN_CURDATE(), INTERVAL 1 YEAR);
INSERT INTO bs.salePersonEvolution (dated, amount, equalizationTax, salesPersonFk)
SELECT fecha dated,
CAST(SUM(importe) AS DECIMAL(10,2) ) amount,
CAST(SUM(recargo) AS DECIMAL(10,2) ) equalizationTax ,
IFNULL(salesPersonFk,0) salesPersonFk
FROM bs.ventas v
JOIN vn.client c ON v.Id_Cliente = c.id
JOIN vn.company co ON co.id = v.empresa_id
WHERE co.code = "VNL" AND fecha >= vDateStart
GROUP BY v.fecha,c.salesPersonFk
ORDER BY salesPersonFk,dated ASC;
END$$
DELIMITER ;

View File

@ -1,8 +1,8 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `bs`.`salesByclientSalesPerson_add`(vDatedFrom DATE)
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `bs`.`salesByClientDepartments_add`(vDatedFrom DATE)
BEGIN
/**
* Agrupa las ventas por cliente/comercial/fecha en la tabla bs.salesByclientSalesPerson
* Agrupa las ventas por cliente/departamento/fecha en la tabla bs.salesByClientDepartment
* 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
@ -12,31 +12,31 @@ BEGIN
SET vDatedFrom = util.VN_CURDATE() - INTERVAL 1 MONTH;
END IF;
UPDATE salesByclientSalesPerson
UPDATE salesByClientDepartment
SET amount = 0,
equalizationTax = 0,
amountNewBorn = 0
WHERE dated BETWEEN vDatedFrom AND util.yesterday();
INSERT INTO salesByclientSalesPerson(
INSERT INTO salesByClientDepartment(
dated,
salesPersonFk,
salesDepartmentFk,
clientFk,
amount,
equalizationTax)
SELECT s.dated,
c.salesPersonFk,
c.salesDepartmentFk,
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
GROUP BY s.dated, c.salesDepartmentFk, s.clientFk
ON DUPLICATE KEY UPDATE amount= VALUES(amount),
equalizationTax= VALUES(equalizationTax);
UPDATE salesByclientSalesPerson s
UPDATE salesByClientDepartment s
JOIN vn.newBornSales n ON n.dated = s.dated AND
n.clientFk = s.clientFk
SET s.amountNewBorn = n.amount

View File

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

@ -2,7 +2,7 @@ DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `bs`.`vendedores_add_launcher`()
BEGIN
CALL bs.salesByclientSalesPerson_add(util.VN_CURDATE()- INTERVAL 45 DAY);
CALL bs.salesByclientSalesDepartment_add(util.VN_CURDATE()- INTERVAL 45 DAY);
END$$
DELIMITER ;

View File

@ -1,8 +1,8 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` EVENT `vn`.`client_unassignSalesPerson`
CREATE OR REPLACE DEFINER=`root`@`localhost` EVENT `vn`.`client_unassignSalesDepartment`
ON SCHEDULE EVERY 1 DAY
STARTS '2023-06-01 03:30:00.000'
ON COMPLETION PRESERVE
ENABLE
DO CALL client_unassignSalesPerson$$
DO CALL client_unassignSalesDepartment$$
DELIMITER ;

View File

@ -69,10 +69,10 @@ BEGIN
-- Componente de maná automático, en función del maná acumulado por el comercial.
INSERT INTO tmp.catalog_component (warehouseFk, itemFk, componentFk, cost)
SELECT vWarehouse, vItem, vComponentMana, ROUND(wm.pricesModifierRate, 3)
SELECT vWarehouse, vItem, vComponentMana, ROUND(dm.pricesModifierRate, 3)
FROM client c
JOIN vn.workerMana wm ON c.salesPersonFk = wm.workerFk
WHERE wm.isPricesModifierActivated AND c.id = vCustomer LIMIT 1;
JOIN vn.departmentMana dm ON c.salesDepartmentFk = dm.salesDepartmentFk
WHERE dm.isPricesModifierActivated AND c.id = vCustomer LIMIT 1;
-- Reparto
INSERT INTO tmp.catalog_component (warehouseFk, itemFk, componentFk, cost)

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,26 +0,0 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` FUNCTION `vn`.`client_getSalesPersonCode`(vClientFk INT, vDated DATE)
RETURNS varchar(3) CHARSET utf8mb3 COLLATE utf8mb3_general_ci
DETERMINISTIC
BEGIN
/**
* Dado un id cliente y una fecha, 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 vWorkerCode CHAR(3);
DECLARE vSalesPersonFk INT;
SET vSalesPersonFk = client_getSalesPerson(vClientFk, vDated);
SELECT code
INTO vWorkerCode
FROM worker
WHERE id = vSalesPersonFk;
RETURN vWorkerCode;
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

@ -138,12 +138,12 @@ BEGIN
SELECT tcb.warehouseFk,
tcb.itemFk,
c2.id,
ROUND(base * wm.pricesModifierRate, 3) manaAuto
ROUND(base * dm.pricesModifierRate, 3) manaAuto
FROM tmp.ticketComponentBase tcb
JOIN `client` c on c.id = vClientFk
JOIN workerMana wm ON c.salesPersonFk = wm.workerFk
JOIN departmentMana dm ON c.salesDepartmentFk = dm.salesDepartmentFk
JOIN vn.component c2 ON c2.code = 'autoMana'
WHERE wm.isPricesModifierActivated
WHERE dm.isPricesModifierActivated
HAVING manaAuto <> 0;
-- Precios especiales

View File

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

View File

@ -1,7 +1,11 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`clientGreugeSpray`(IN vClientFk INT, IN onlyForHisOwner BOOL, IN vWorkerCode VARCHAR(3), IN vWithMana BOOLEAN)
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`clientGreugeSpray`(
IN vClientFk INT,
IN vIsOnlyForHisOwner BOOL,
IN vDepartmentCode VARCHAR(45),
IN vWithMana BOOLEAN
)
BEGIN
DECLARE vGreuge DECIMAL(10,2);
DECLARE vOwner INT;
DECLARE vTotalSale INT;
@ -9,65 +13,62 @@ BEGIN
DECLARE vGreugeTypeMana INT DEFAULT 3;-- Maná
DECLARE vMana DECIMAL(10,2);
SELECT vn.clientGetMana(vClientFk) INTO vMana;
SELECT clientGetMana(vClientFk) INTO vMana;
IF vWithMana AND vMana THEN
INSERT INTO vn.greuge( clientFk,
description,
amount,
shipped,
greugeTypeFk)
VALUES( vClientFk,
'Desasignación',
-1 * vMana,
util.VN_CURDATE(),
vGreugeTypeMana);
INSERT INTO greuge
SET clientFk = vClientFk,
description = 'Desasignación',
amount = - vMana,
shipped = util.VN_CURDATE(),
greugeTypeFk = vGreugeTypeMana;
END IF;
SELECT sum(amount) INTO vGreuge
FROM vn.greuge
SELECT SUM(amount) INTO vGreuge
FROM greuge
WHERE clientFk = vClientFk;
IF vGreuge != 0 THEN
IF LENGTH(vWorkerCode) = 0 THEN
SELECT salesPersonFk INTO vOwner
FROM vn.client
IF vGreuge THEN
IF LENGTH(vDepartmentCode) THEN
SELECT salesDepartmentFk INTO vOwner
FROM client
WHERE id = vClientFk;
ELSE
SELECT id INTO vOwner
FROM vn.worker
WHERE code = vWorkerCode COLLATE utf8_general_ci;
FROM department
WHERE code = vDepartmentCode;
END IF;
DROP TEMPORARY TABLE IF EXISTS tmp.clientList;
CREATE TEMPORARY TABLE tmp.clientList
SELECT DISTINCT t.clientFk, floor(cr.yearSale / 12) monthSale
IF vOwner IS NULL THEN
CALL util.throw('The department is incorrect');
END IF;
INSERT INTO greuge(clientFk, description, amount, shipped, greugeTypeFk)
WITH greuges AS(
SELECT DISTINCT t.clientFk, FLOOR(cr.yearSale / 12) monthSale
FROM vn.ticket t
JOIN vn.client c ON c.id = t.clientFk
JOIN vn.workerMana wm ON wm.workerFk = c.salesPersonFk
JOIN vn.departmentMana dm ON dm.salesDepartmentFk = c.salesDepartmentFk
JOIN vn.claimRatio cr ON cr.clientFk = c.id
WHERE wm.workerFk = IF(onlyForHisOwner, vOwner, wm.workerFk)
AND t.shipped >= TIMESTAMPADD(MONTH,-1,util.VN_CURDATE())
AND c.id != vClientFk
HAVING monthSale > 100;
SELECT SUM(monthSale) INTO vTotalSale
FROM tmp.clientList;
INSERT INTO vn.greuge(clientFk, description, amount, shipped, greugeTypeFk)
SELECT clientFk, CONCAT('Cliente: ',vClientFk), vGreuge * monthSale / vTotalSale, util.VN_CURDATE(), vGreugeTypeFk
FROM tmp.clientList
WHERE dm.salesDepartmentFk = IF(vIsOnlyForHisOwner, vOwner, dm.salesDepartmentFk)
AND t.shipped >= util.VN_CURDATE() - INTERVAL 1 MONTH
AND c.id <> vClientFk
HAVING monthSale > 100
), totalGreuge AS(
SELECT SUM(monthSale) totalSale FROM greuges
)SELECT g.clientFk,
CONCAT('Cliente: ', vClientFk),
vGreuge * g.monthSale / tgtotalSale,
util.VN_CURDATE(),
vGreugeTypeFk
FROM greuges g
JOIN totalGreuge tg
UNION ALL
SELECT vClientFk, 'Reparto greuge', -vGreuge, util.VN_CURDATE(), vGreugeTypeFk;
SELECT vClientFk,
'Reparto greuge',
-vGreuge,
util.VN_CURDATE(),
vGreugeTypeFk;
END IF;
END$$
DELIMITER ;

View File

@ -8,7 +8,7 @@ BEGIN
FROM tmp.clientGetDebt c
LEFT JOIN clientRisk r ON r.clientFk = c.clientFk
GROUP BY c.clientFk
HAVING SUM(IFNULL(r.amount,0)) = 0;
HAVING SUM(IFNULL(r.amount, 0)) = 0;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
@ -16,22 +16,26 @@ BEGIN
CREATE TEMPORARY TABLE tmp.clientGetDebt
SELECT cd.clientFk
FROM bs.clientDied cd
LEFT JOIN clientProtected cp ON cp.clientFk = cd.clientFk
JOIN client c ON c.id = cd.clientFk
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 co.code NOT IN ('PT')
AND a.name <> 'Canarias'
AND c.salesPersonFk IS NOT NULL;
LEFT JOIN clientProtected cp ON cp.clientFk = cd.clientFk
JOIN client c ON c.id = cd.clientFk
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 co.code NOT IN ('PT')
AND a.name <> 'Canarias'
AND c.salesDepartmentFk IS NOT NULL;
OPEN rs;
FETCH rs INTO vClientFk;
WHILE NOT vDone DO
CALL vn.clientGreugeSpray(vClientFk, TRUE, '',TRUE);
UPDATE vn.client SET salesPersonFk = NULL WHERE id = vClientFk;
UPDATE vn.client
SET salesDepartmentFk = NULL
WHERE id = vClientFk;
FETCH rs INTO vClientFk;
END WHILE;
CLOSE rs;

View File

@ -1,8 +1,8 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`client_unassignSalesPerson`()
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`client_unassignSalesDepartment`()
BEGIN
/**
* Elimina la asignación de salesPersonFk de la ficha del clientes
* Elimina la asignación de salesDepartmentFk 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
*/
@ -22,16 +22,15 @@ 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
JOIN bs.clientDiedPeriod cdp ON cdp.countryFk = co.id
WHERE cd.warning = 'third'
AND cp.clientFk IS NULL
AND sp.salesPersonFk IS NULL
AND a.name <> 'Canarias'
AND c.salesPersonFk IS NOT NULL;
AND c.salesDepartmentFk IS NOT NULL;
OPEN vCursor;
l: LOOP
@ -42,7 +41,7 @@ BEGIN
END IF;
CALL clientGreugeSpray(vClientFk, TRUE, '', TRUE);
UPDATE client
SET salesPersonFk = NULL
SET salesDepartmentFk = NULL
WHERE id = vClientFk;
END LOOP;
CLOSE vCursor;

View File

@ -1,10 +1,13 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`collection_getTickets`(vParamFk INT)
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`collection_getTickets`(
vParamFk INT
)
BEGIN
/**
* Selecciona los tickets de una colección/ticket/sectorCollection
* @param vParamFk ticketFk/collectionFk/sectorCollection
* @return Retorna ticketFk, level, agencyName, warehouseFk, salesPersonFk, observation
* @return Retorna (ticketFk, level, agencyName, warehouseFk, observation,
* rgb, salesDepartmentFk)
*/
DECLARE vItemPackingTypeFk VARCHAR(1);
DECLARE vYesterday DATE;
@ -29,7 +32,7 @@ BEGIN
IF(!(vItemPackingTypeFk <=> 'V'), cc.code, CONCAT(SUBSTRING('ABCDEFGH', tc.wagon, 1), '-', tc.`level`)) `level`,
am.name agencyName,
t.warehouseFk,
w.id salesPersonFk,
c.salesDepartmentFk,
IFNULL(ob.description,'') observaciones,
cc.rgb
FROM vn.ticket t
@ -51,7 +54,7 @@ BEGIN
IF(NOT(vItemPackingTypeFk <=> 'V'), cc.code, CONCAT(SUBSTRING('ABCDEFGH', tc.wagon, 1), '-', tc.`level`)) `level`,
am.name agencyName,
t.warehouseFk,
w.id salesPersonFk,
c.salesDepartmentFk,
ob.description,
IF(NOT (vItemPackingTypeFk <=> 'V'), cc.rgb, NULL) `rgb`
FROM vn.ticket t
@ -72,7 +75,7 @@ BEGIN
NULL `level`,
am.name agencyName,
t.warehouseFk,
c.salesPersonFk,
c.salesDepartmentFk,
ob.description,
NULL `rgb`
FROM vn.sectorCollection sc

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,14 +23,15 @@ BEGIN
tls.name stateName,
sb.buyFk,
s.id saleFk,
wk.id salesPersonFk
d.id salesDepartmentFk,
d.name salesDepartment
FROM sale s
JOIN ticket t ON t.id = s.ticketFk
JOIN warehouse w ON w.id = t.warehouseFk
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
LEFT JOIN buy b ON b.id = sb.buyFk

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

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

View File

@ -70,7 +70,7 @@ 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,
IFNULL(tls.alertLevel, al.id) alertLevel,
@ -91,7 +91,7 @@ proc: BEGIN
LEFT JOIN ticketStateToday tst ON tst.ticketFk = t.id
LEFT JOIN `state` st ON st.id = tst.state
LEFT JOIN client c ON c.id = t.clientFk
LEFT JOIN worker wk ON wk.id = c.salesPersonFk
LEFT JOIN department d ON d.id = c.salesDepartmentFk
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

@ -8,7 +8,7 @@ BEGIN
* @param vRouteFk
* @select Información de los tickets
*/
SELECT t.id Id,
SELECT t.id Id,
t.clientFk Client,
a.id Address,
a.nickname ClientName,
@ -23,7 +23,7 @@ SELECT t.id Id,
a.mobile AddressMobile,
d.longitude Longitude,
d.latitude Latitude,
wm.mediaValue SalePersonPhone,
CONCAT_WS(' - ', 'adfa', de.pbxQueue ) salesDepartmentPhone,
tob.description Note,
t.isSigned Signed,
t.priority,
@ -31,7 +31,8 @@ SELECT t.id Id,
FROM ticket t
JOIN client c ON t.clientFk = c.id
JOIN address a ON t.addressFk = a.id
LEFT JOIN workerMedia wm ON wm.workerFk = c.salesPersonFk
LEFT JOIN vn.department de ON de.id = c.salesDepartmentFk
LEFT JOIN vn.company co ON co.`code` = 'VNL'
LEFT JOIN (
SELECT t.addressFk, MAX(d.ticketFk) lastTicketFk
FROM ticket t

View File

@ -15,7 +15,7 @@ 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
JOIN saleGroupDetail sgd ON sgd.saleFk = s.id

View File

@ -1,5 +1,9 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_canAdvance`(vDateFuture DATE, vDateToAdvance DATE, vWarehouseFk INT)
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_canAdvance`(
vDateFuture DATE,
vDateToAdvance DATE,
vWarehouseFk INT
)
BEGIN
/**
* Devuelve los tickets y la cantidad de lineas de venta que se pueden adelantar.
@ -26,7 +30,7 @@ BEGIN
origin.futureState,
origin.futureIpt,
dest.ipt,
origin.workerFk,
origin.departmentFk,
origin.futureLiters,
origin.futureLines,
dest.shipped,
@ -55,7 +59,7 @@ BEGIN
FROM (
SELECT
s.ticketFk,
c.salesPersonFk workerFk,
c.salesDepartmentFk departmentFk,
t.shipped,
t.totalWithVat,
st.name futureState,

View File

@ -15,21 +15,21 @@ BEGIN
DECLARE vAgencyModeFk INT;
DECLARE vNewTicket INT;
DECLARE vYear INT;
DECLARE vSalesPersonFK INT;
DECLARE vObservationTypeFkForSalesPerson INT;
DECLARE vItemPicker INT;
DECLARE rsTicket CURSOR FOR
SELECT tt.ticketFk,
t.clientFk,
t.warehouseFk,
t.companyFk,
t.addressFk,
tt.agencyModeFk,
ti.dated
FROM ticketWeekly tt
JOIN ticket t ON tt.ticketFk = t.id
JOIN tmp.time ti
WHERE WEEKDAY(ti.dated) = tt.weekDay;
SELECT tt.ticketFk,
t.clientFk,
t.warehouseFk,
t.companyFk,
t.addressFk,
tt.agencyModeFk,
ti.dated
FROM ticketWeekly tt
JOIN ticket t ON tt.ticketFk = t.id
JOIN tmp.time ti
WHERE WEEKDAY(ti.dated) = tt.weekDay;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vIsDone = TRUE;
@ -38,7 +38,7 @@ BEGIN
OPEN rsTicket;
myLoop: LOOP
BEGIN
DECLARE vSalesPersonEmail VARCHAR(150);
DECLARE vSalesDepartmentEmail VARCHAR(150);
DECLARE vIsDuplicateMail BOOL;
DECLARE vSubject VARCHAR(150);
DECLARE vMessage TEXT;
@ -154,7 +154,7 @@ BEGIN
FROM ticketRequest
WHERE ticketFk =vTicketFk;
SELECT id INTO vSalesPersonFK
SELECT id INTO vObservationTypeFkForSalesPerson
FROM observationType
WHERE code = 'salesPerson';
@ -168,7 +168,7 @@ BEGIN
description)
VALUES(
vNewTicket,
vSalesPersonFK,
vObservationTypeFkForSalesPerson,
CONCAT('turno desde ticket: ',vTicketFk))
ON DUPLICATE KEY UPDATE description =
CONCAT(ticketObservation.description,VALUES(description),' ');
@ -185,9 +185,9 @@ BEGIN
IF (vLanding IS NULL) THEN
SELECT e.email INTO vSalesPersonEmail
SELECT d.notificationEmail INTO vSalesDepartmentEmail
FROM client c
JOIN account.emailUser e ON e.userFk = c.salesPersonFk
LEFT JOIN department d ON d.id = c.saleDepartmentFk
WHERE c.id = vClientFk;
SET vSubject = CONCAT('Turnos - No se ha podido clonar correctamente el ticket ',
@ -199,11 +199,11 @@ BEGIN
SELECT COUNT(*) INTO vIsDuplicateMail
FROM mail
WHERE receiver = vSalesPersonEmail
WHERE receiver = vSalesDepartmentEmail
AND subject = vSubject;
IF NOT vIsDuplicateMail THEN
CALL mail_insert(vSalesPersonEmail, NULL, vSubject, vMessage);
CALL mail_insert(vSalesDepartmentEmail, NULL, vSubject, vMessage);
END IF;
CALL ticket_setState(vNewTicket, 'FIXING');
ELSE

View File

@ -1,33 +1,28 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`workerDisable`(vUserId int)
mainLabel:BEGIN
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`workerDisable`(vUserFk INT)
l:BEGIN
IF (SELECT COUNT(*) FROM workerDisableExcluded WHERE workerFk = vUserId AND (dated > util.VN_CURDATE() OR dated IS NULL)) > 0 THEN
LEAVE mainLabel;
IF (SELECT COUNT(*)
FROM workerDisableExcluded
WHERE workerFk = vUserFk
AND (dated > util.VN_CURDATE() OR dated IS NULL)) > 0 THEN
LEAVE l;
END IF;
DELETE cp FROM clientProtected cp
JOIN client c ON c.id = cp.clientFk
WHERE c.salesPersonFk = vUserId;
DELETE FROM account.account
WHERE id = vUserId;
DELETE FROM account.account WHERE id = vUserFk;
UPDATE account.user
SET role = 2
WHERE id = vUserId;
WHERE id = vUserFk;
DELETE FROM pbx.sip
WHERE user_id = vUserId;
DELETE FROM pbx.sip WHERE user_id = vUserFk;
UPDATE `client` c
JOIN payMethod p ON p.name = 'CONTADO'
SET c.credit = 0, c.payMethodFk = p.id, hasCoreVnl = FALSE
WHERE c.id = vUserId;
UPDATE `client` c
SET c.salesPersonFk = null
WHERE c.salesPersonFk = vUserId;
JOIN payMethod p ON p.name = 'CONTADO'
SET c.credit = 0,
c.payMethodFk = p.id,
hasCoreVnl = FALSE
WHERE c.id = vUserFk;
UPDATE locker l
SET l.workerFk = NULL

View File

@ -29,13 +29,13 @@ BEGIN
c.name,
c.phone,
bt.description,
c.salesPersonFk,
u.name username,
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
JOIN vn.town t ON t.id = pc.townFk AND t.provinceFk = a.provinceFk

View File

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

View File

@ -45,18 +45,16 @@ BEGIN
IF vText IS NOT NULL
THEN
INSERT INTO mail(receiver, replyTo, `subject`, body)
SELECT
CONCAT(IF(ac.id,u.name, 'jgallego'), '@verdnatura.es'),
SELECT IFNULL(d.notificationEmail, '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;
FROM department d
WHERE d.id = NEW.salesDepartmentFk;
END IF;
IF NEW.salespersonFk IS NULL AND OLD.salespersonFk IS NOT NULL THEN
IF NEW.salesDepartmentFk IS NULL AND OLD.salesDepartmentFk IS NOT NULL THEN
IF (SELECT COUNT(clientFk)
FROM clientProtected
WHERE clientFk = NEW.id
@ -65,8 +63,9 @@ BEGIN
END IF;
END IF;
IF NOT (NEW.salesPersonFk <=> OLD.salesPersonFk) THEN
SET NEW.lastSalesPersonFk = IFNULL(NEW.salesPersonFk, OLD.salesPersonFk);
IF NOT (NEW.salesDepartmentFk <=> OLD.salesDepartmentFk) THEN
SET NEW.lastSalesDepartmentFk = IFNULL(NEW.salesDepartmentFk, OLD.salesDepartmentFk);
END IF;
IF NOT (NEW.businessTypeFk <=> OLD.businessTypeFk) AND (NEW.businessTypeFk = 'individual' OR OLD.businessTypeFk = 'individual') THEN

View File

@ -1,26 +1,16 @@
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`,
`v`.`fecha` 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`)
)
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')
AS SELECT
`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`.`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,7 @@ 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`,
`c`.`typeFk` AS `typeFk`

View File

@ -0,0 +1,126 @@
ALTER TABLE vn.client
ADD IF NOT EXISTS salesDepartmentFk INT(11) DEFAULT NULL NULL;
ALTER TABLE vn.client
ADD IF NOT EXISTS lastSalesDepartmentFk INT(11) DEFAULT NULL NULL;
ALTER TABLE vn.client
ADD CONSTRAINT client_department_FK FOREIGN KEY IF NOT EXISTS (salesDepartmentFk)
REFERENCES vn.department(id) ON DELETE RESTRICT ON UPDATE CASCADE;
ALTER TABLE vn.client
ADD CONSTRAINT client_lastDepartment_FK FOREIGN KEY IF NOT EXISTS (lastSalesDepartmentFk)
REFERENCES vn.department(id) ON DELETE RESTRICT ON UPDATE CASCADE;
UPDATE vn.client c
JOIN vn.worker w ON w.id = c.salesPersonFk
JOIN vn.business b ON b.id = w.businessFk
SET c.salesDepartmentFk = b.departmentFk;
UPDATE vn.client c
JOIN vn.worker w ON w.id = c.lastSalesPersonFk
JOIN vn.business b ON b.id = w.businessFk
SET c.lastSalesDepartmentFk = b.departmentFk;
DROP TABLE IF EXISTS 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,
`pricesModifierRate` double NOT NULL DEFAULT 0,
`isPricesModifierActivated` tinyint(1) NOT NULL DEFAULT 1,
PRIMARY KEY (`salesDepartmentFk`),
KEY `departmentMana_idx` (`salesDepartmentFk`),
CONSTRAINT `departmentMana_salesDepartment_FK` FOREIGN KEY (`salesDepartmentFk`)
REFERENCES `vn`.`department` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
DROP TABLE IF EXISTS 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,
`amount` decimal(10,3) NOT NULL DEFAULT 0.000,
`equalizationTax` decimal(10,3) NOT NULL DEFAULT 0.000,
`amountNewBorn` decimal(10,3) NOT NULL DEFAULT 0.000,
PRIMARY KEY (`dated`,`clientFk`),
KEY `salesByClientDepartment_clientFk` (`clientFk`),
KEY `salesByClientDepartment_salesDepartmentFk` (`salesDepartmentFk`),
KEY `salesByClientDepartment_dated` (`dated`,`clientFk`,`amount`),
CONSTRAINT `salesByClientDepartment_clientFk_FK`
FOREIGN KEY (`clientFk`) REFERENCES `vn`.`client` (`id`) ON UPDATE CASCADE,
CONSTRAINT `salesByClientDepartment_department_FK`
FOREIGN KEY (`salesDepartmentFk`) REFERENCES `vn`.`department` (`id`) ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci COMMENT='Ventas diarias por cliente y departamento';
INSERT INTO bs.salesByClientDepartment(
dated,
salesDepartmentFk,
clientFk,
amount,
equalizationTax,
amountNewBorn)
SELECT ss.dated, b.departmentFk, ss.clientFk, ss.amount, ss.equalizationTax, ss.amountNewBorn
FROM bs.salesByclientSalesPerson ss
JOIN vn.worker w ON w.id = ss.salesPersonFk
JOIN vn.business b ON b.id = w.businessFk;
DROP TABLE IF EXISTS `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
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci
COMMENT='Lista de departamentos comerciales que no se desasignarán automáticamente sus clientes';
UPDATE vn.observationType
SET description='Dto. Comercial',code='salesDepartment'
WHERE code = 'salesPerson';
DROP TABLE IF EXISTS `bs`.`portfolio`;
CREATE OR REPLACE TABLE `bs`.`portfolio` (
`salesDepartmentFk` int(10) NOT NULL,
`yeared` int(4) NOT NULL,
`monthed` int(2) NOT NULL,
`amount` decimal(10,2) DEFAULT NULL,
PRIMARY KEY (`salesDepartmentFk`,`yeared`,`monthed`),
KEY `portfolio_salesDepartmentFk` (`salesDepartmentFk`),
CONSTRAINT `portfolio_salesDepartment_department_FK`
FOREIGN KEY (`salesDepartmentFk`) REFERENCES `vn`.`department` (`id`) ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
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,
`amount` decimal(10,3) NOT NULL DEFAULT 0.000,
`equalizationTax` decimal(10,3) NOT NULL DEFAULT 0.000,
`amountNewBorn` decimal(10,3) NOT NULL DEFAULT 0.000,
PRIMARY KEY (`id`),
KEY `salesDepartmentEvolution_salesDepartment` (`salesDepartmentFk`),
CONSTRAINT `salesDepartmentEvolution_salesDepartment_department_FK` FOREIGN KEY (`salesDepartmentFk`)
REFERENCES `vn`.`department` (`id`) ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
RENAME TABLE vn.salespersonConfig TO vn.salesDepartmentConfig;
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

@ -41,7 +41,7 @@ module.exports = Self => {
relation: 'claimDestination',
fields: ['addressFk']
},
where: {claimFk: claimFk}
where: {claimFk}
}, myOptions);
for (let claimEnd of claimEnds) {
@ -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

@ -39,7 +39,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);
@ -55,8 +55,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, '@es5_equipo', 'Trash');
expect(chatModel.send).toHaveBeenCalledTimes(4);
await tx.rollback();
} catch (e) {
@ -71,7 +71,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);
@ -80,8 +80,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, '@es5_equipo', 'Bueno');
expect(chatModel.send).toHaveBeenCalledTimes(4);
await tx.rollback();
} catch (e) {
@ -96,7 +96,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);
@ -105,8 +105,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, '@es5_equipo', 'Bueno');
expect(chatModel.send).toHaveBeenCalledTimes(4);
await tx.rollback();
} catch (e) {

View File

@ -63,7 +63,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 = {
@ -83,7 +83,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) {
@ -101,7 +101,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 = {
@ -121,7 +121,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) {
@ -139,7 +139,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 = {
@ -162,7 +162,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,11 +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 salesDepartment = claim.client().salesDepartment();
const changedPickup = args.pickup && args.pickup != claim.pickup;
@ -84,14 +89,13 @@ module.exports = Self => {
delete args.ctx;
const updatedClaim = await claim.updateAttributes(args, myOptions);
const salesPerson = claim.client().salesPersonUser();
if (salesPerson) {
if (salesDepartment) {
if (changedPickup && updatedClaim.pickup)
await notifyPickUp(ctx, salesPerson.id, claim);
await notifyPickUp(ctx, salesDepartment, claim);
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);
}
@ -106,7 +110,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.__;
@ -117,10 +121,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
@ -131,6 +135,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.name 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

@ -9,6 +9,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

@ -133,7 +133,7 @@
"columnName": "businessTypeFk"
}
},
"salesPersonFk": {
"salesDepartmentFk": {
"type": "number"
},
"hasElectronicInvoice": {
@ -163,10 +163,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; // es5_equipo
const currentDepartmetnId = 94; // es2_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, '@es5_equipo', `Client assignment has changed`);
expect(chatModel.send).toHaveBeenCalledWith(ctx, '@es2_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, '@es2_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, '@es5_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

@ -41,7 +41,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);
@ -63,11 +69,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.name 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

@ -34,31 +34,24 @@ module.exports = Self => {
if (typeof options == 'object')
Object.assign(myOptions, options);
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)`,
[date]);
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`);
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`);

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};
@ -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

@ -6,7 +6,7 @@ describe('SalesMonitor clientsFilter()', () => {
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();
@ -20,7 +20,7 @@ describe('SalesMonitor clientsFilter()', () => {
};
const result = await models.SalesMonitor.clientsFilter(ctx, filter, options);
expect(result.length).toEqual(3);
expect(result.length).toEqual(1);
await tx.rollback();
} catch (e) {
@ -34,7 +34,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,13 +42,15 @@ 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);
expect(result.length).toEqual(2);
await tx.rollback();
} catch (e) {

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 {
@ -180,25 +180,6 @@ describe('SalesMonitor salesFilter()', () => {
}
});
it('should now return the tickets that are not from the worker team', async() => {
const tx = await models.SalesMonitor.beginTransaction({});
try {
const options = {transaction: tx};
const ctx = {req: {accessToken: {userId: 18}}, args: {myTeam: false}};
const filter = {};
const result = await models.SalesMonitor.salesFilter(ctx, filter, options);
expect(result.length).toEqual(4);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
it('should return the tickets sorted by problems descendant', async() => {
const tx = await models.SalesMonitor.beginTransaction({});

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']
}
}
}
@ -67,11 +67,10 @@ module.exports = Self => {
}
const deletedSales = await Promise.all(promises);
if (tx) await tx.commit();
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', {
@ -79,7 +78,7 @@ module.exports = Self => {
ticketUrl: `${url}ticket/${ticketId}/sale`,
deletions: deletions
});
await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message);
await models.Chat.send(ctx, `@${salesDepartment.chatName}`, message, myOptions);
}
return deletedSales;

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 change = $t('Changes in sales', {
itemId: sale.itemFk,
@ -85,8 +85,7 @@ module.exports = Self => {
changes: change,
ticketUrl: `${url}ticket/${sale.ticket().id}/sale`,
});
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));

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