Merge branch '6824-itemShelvingSaleNoDelete' of https://gitea.verdnatura.es/verdnatura/salix into 6824-itemShelvingSaleNoDelete
gitea/salix/pipeline/pr-dev This commit looks good
Details
gitea/salix/pipeline/pr-dev This commit looks good
Details
This commit is contained in:
commit
1ae60f51dd
|
@ -4,7 +4,7 @@ USE `util`;
|
|||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||
|
||||
INSERT INTO `version` VALUES ('vn-database','11196','91ee956fbd1557848e4ab522bc5d39b2ec10e9b2','2024-09-18 07:28:14','11245');
|
||||
INSERT INTO `version` VALUES ('vn-database','11278','fe10f03459a153fc213bf64e352804c043f94590','2024-10-03 07:47:47','11281');
|
||||
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','10107','00-firstScript.sql','jenkins@10.0.2.69','2022-04-23 10:53:53',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','10112','00-firstScript.sql','jenkins@10.0.2.69','2022-05-09 09:14:53',NULL,NULL);
|
||||
|
@ -862,6 +862,7 @@ INSERT INTO `versionLog` VALUES ('vn-database','11083','00-firstScript.sql','jen
|
|||
INSERT INTO `versionLog` VALUES ('vn-database','11084','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-06-25 08:38:13',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11086','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-06-27 10:02:02',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11087','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-06-25 08:38:13',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11088','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:44:48',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11089','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-06-25 08:39:16',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11090','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-06-11 08:32:35',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11092','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-06-07 08:21:23',NULL,NULL);
|
||||
|
@ -875,12 +876,37 @@ INSERT INTO `versionLog` VALUES ('vn-database','11103','00-firstScript.sql','jen
|
|||
INSERT INTO `versionLog` VALUES ('vn-database','11104','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-07-09 07:39:38',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11105','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-06-20 15:36:07',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11106','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-06-25 08:39:49',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11107','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:44:48',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11107','01-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:44:48',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11107','02-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:44:48',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11107','03-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:44:48',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11107','04-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:44:49',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11107','05-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:44:49',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11107','06-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:45:04',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11107','07-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:45:41',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11107','08-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:45:41',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11107','09-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:45:47',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11107','10-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:45:48',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11107','11-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:45:59',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11107','12-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:46:00',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11107','14-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:46:00',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11107','15-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:46:06',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11107','17-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:46:06',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11107','18-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:46:06',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11107','19-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:46:19',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11107','20-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:46:19',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11107','21-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:47:34',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11107','22-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:47:34',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11107','23-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:47:35',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11107','24-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:47:35',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11108','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-09-17 07:38:39',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11109','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-06-18 19:09:56',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11110','00-clientUnpaid.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-07-09 07:39:38',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11111','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-07-09 07:39:38',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11112','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-09-17 07:38:40',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11113','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:47:35',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11114','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-06-25 08:39:49',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11115','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:47:35',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11116','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-07-09 07:39:38',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11117','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-07-09 07:39:38',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11118','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-07-19 12:28:49',NULL,NULL);
|
||||
|
@ -942,6 +968,7 @@ INSERT INTO `versionLog` VALUES ('vn-database','11172','14-firstScript.sql','jen
|
|||
INSERT INTO `versionLog` VALUES ('vn-database','11172','15-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-09-03 08:57:44',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11175','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-09-03 08:57:44',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11177','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-07-30 12:42:28',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11178','00-aclSetWeight.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:47:35',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11179','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-08-20 08:34:43',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11180','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-08-20 08:34:43',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11182','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-08-09 08:19:36',NULL,NULL);
|
||||
|
@ -967,12 +994,45 @@ INSERT INTO `versionLog` VALUES ('vn-database','11205','00-firstScript.sql','jen
|
|||
INSERT INTO `versionLog` VALUES ('vn-database','11206','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-09-17 07:38:42',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11207','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-09-17 07:38:42',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11209','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-09-03 08:58:01',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11210','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:47:35',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11210','01-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:47:35',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11210','02-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:47:40',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11210','03-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:47:41',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11211','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-09-17 07:38:42',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11213','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-09-06 06:31:13',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11215','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-09-17 07:38:42',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11216','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:47:41',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11217','00-hederaMessages.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-09-09 12:21:45',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11219','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:47:41',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11221','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:47:41',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11222','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:47:41',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11223','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:47:41',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11224','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:47:41',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11225','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:47:41',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11225','01-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:47:41',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11225','02-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:47:41',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11227','00-addWorkerTimeControlMailAcl.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:47:41',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11229','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-09-16 08:24:17',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11234','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:47:42',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11235','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:47:43',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11236','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:47:43',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11236','01-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:47:43',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11237','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:47:43',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11239','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-09-17 12:57:06',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11240','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:47:43',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11241','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-09-20 09:08:25',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11246','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-09-18 12:39:53',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11247','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-09-19 12:10:08',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11248','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-09-23 11:12:17',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11249','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:47:43',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11253','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-09-20 14:41:27',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11255','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:47:43',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11256','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-09-23 12:18:24',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11262','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:47:43',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11263','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-09-27 12:05:32',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11278','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-03 07:47:43',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11279','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-10-02 08:05:24',NULL,NULL);
|
||||
INSERT INTO `versionLog` VALUES ('vn-database','11280','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-02 08:46:50',NULL,NULL);
|
||||
|
||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||
|
@ -1345,6 +1405,8 @@ INSERT INTO `roleInherit` VALUES (373,131,2,19295);
|
|||
INSERT INTO `roleInherit` VALUES (375,120,131,1437);
|
||||
INSERT INTO `roleInherit` VALUES (376,124,21,19336);
|
||||
INSERT INTO `roleInherit` VALUES (377,47,49,19295);
|
||||
INSERT INTO `roleInherit` VALUES (378,101,15,19294);
|
||||
INSERT INTO `roleInherit` VALUES (379,103,121,19294);
|
||||
|
||||
INSERT INTO `userPassword` VALUES (1,7,1,0,2,1);
|
||||
|
||||
|
@ -1445,7 +1507,7 @@ INSERT INTO `ACL` VALUES (112,'Defaulter','*','READ','ALLOW','ROLE','employee',N
|
|||
INSERT INTO `ACL` VALUES (113,'ClientRisk','*','READ','ALLOW','ROLE','trainee',NULL);
|
||||
INSERT INTO `ACL` VALUES (114,'Receipt','*','READ','ALLOW','ROLE','trainee',NULL);
|
||||
INSERT INTO `ACL` VALUES (115,'Receipt','*','WRITE','ALLOW','ROLE','administrative',NULL);
|
||||
INSERT INTO `ACL` VALUES (116,'BankEntity','*','*','ALLOW','ROLE','employee',NULL);
|
||||
INSERT INTO `ACL` VALUES (116,'BankEntity','*','READ','ALLOW','ROLE','employee',10578);
|
||||
INSERT INTO `ACL` VALUES (117,'ClientSample','*','*','ALLOW','ROLE','employee',NULL);
|
||||
INSERT INTO `ACL` VALUES (118,'WorkerTeam','*','*','ALLOW','ROLE','salesPerson',NULL);
|
||||
INSERT INTO `ACL` VALUES (119,'Travel','*','READ','ALLOW','ROLE','employee',NULL);
|
||||
|
@ -1541,8 +1603,6 @@ INSERT INTO `ACL` VALUES (234,'WorkerLog','find','READ','ALLOW','ROLE','hr',NULL
|
|||
INSERT INTO `ACL` VALUES (235,'CustomsAgent','*','*','ALLOW','ROLE','employee',NULL);
|
||||
INSERT INTO `ACL` VALUES (236,'Buy','*','*','ALLOW','ROLE','buyer',NULL);
|
||||
INSERT INTO `ACL` VALUES (237,'WorkerDms','filter','*','ALLOW','ROLE','employee',NULL);
|
||||
INSERT INTO `ACL` VALUES (238,'Town','*','WRITE','ALLOW','ROLE','deliveryAssistant',NULL);
|
||||
INSERT INTO `ACL` VALUES (239,'Province','*','WRITE','ALLOW','ROLE','deliveryAssistant',NULL);
|
||||
INSERT INTO `ACL` VALUES (241,'SupplierContact','*','WRITE','ALLOW','ROLE','administrative',NULL);
|
||||
INSERT INTO `ACL` VALUES (248,'RoleMapping','*','READ','ALLOW','ROLE','account',NULL);
|
||||
INSERT INTO `ACL` VALUES (249,'UserPassword','*','READ','ALLOW','ROLE','account',NULL);
|
||||
|
@ -1556,7 +1616,7 @@ INSERT INTO `ACL` VALUES (257,'FixedPrice','*','*','ALLOW','ROLE','buyer',NULL);
|
|||
INSERT INTO `ACL` VALUES (258,'PayDem','*','READ','ALLOW','ROLE','employee',NULL);
|
||||
INSERT INTO `ACL` VALUES (259,'Client','createReceipt','*','ALLOW','ROLE','salesAssistant',NULL);
|
||||
INSERT INTO `ACL` VALUES (260,'PrintServerQueue','*','WRITE','ALLOW','ROLE','employee',NULL);
|
||||
INSERT INTO `ACL` VALUES (261,'SupplierAccount','*','*','ALLOW','ROLE','administrative',NULL);
|
||||
INSERT INTO `ACL` VALUES (261,'SupplierAccount','*','WRITE','ALLOW','ROLE','administrative',783);
|
||||
INSERT INTO `ACL` VALUES (262,'Entry','*','*','ALLOW','ROLE','administrative',NULL);
|
||||
INSERT INTO `ACL` VALUES (263,'InvoiceIn','*','READ','ALLOW','ROLE','administrative',NULL);
|
||||
INSERT INTO `ACL` VALUES (264,'StarredModule','*','*','ALLOW','ROLE','$authenticated',NULL);
|
||||
|
@ -1931,7 +1991,7 @@ INSERT INTO `ACL` VALUES (699,'TicketSms','find','READ','ALLOW','ROLE','salesPer
|
|||
INSERT INTO `ACL` VALUES (701,'Docuware','upload','WRITE','ALLOW','ROLE','deliveryAssistant',NULL);
|
||||
INSERT INTO `ACL` VALUES (702,'Ticket','docuwareDownload','READ','ALLOW','ROLE','salesPerson',NULL);
|
||||
INSERT INTO `ACL` VALUES (703,'Worker','search','READ','ALLOW','ROLE','employee',NULL);
|
||||
INSERT INTO `ACL` VALUES (704,'ExpeditionState','addExpeditionState','WRITE','ALLOW','ROLE','delivery',NULL);
|
||||
INSERT INTO `ACL` VALUES (704,'ExpeditionState','addExpeditionState','WRITE','ALLOW','ROLE','production',19294);
|
||||
INSERT INTO `ACL` VALUES (705,'SaleGroupDetail','deleteById','WRITE','ALLOW','ROLE','employee',NULL);
|
||||
INSERT INTO `ACL` VALUES (706,'Ticket','setDeleted','WRITE','ALLOW','ROLE','buyer',NULL);
|
||||
INSERT INTO `ACL` VALUES (707,'DeviceLog','create','WRITE','ALLOW','ROLE','employee',NULL);
|
||||
|
@ -2134,9 +2194,25 @@ INSERT INTO `ACL` VALUES (915,'ACL','*','WRITE','ALLOW','ROLE','developerBoss',1
|
|||
INSERT INTO `ACL` VALUES (916,'Entry','getBuysCsv','READ','ALLOW','ROLE','supplier',10578);
|
||||
INSERT INTO `ACL` VALUES (917,'InvoiceOut','refundAndInvoice','WRITE','ALLOW','ROLE','administrative',10578);
|
||||
INSERT INTO `ACL` VALUES (918,'Worker','__get__descriptor','READ','ALLOW','ROLE','employee',10578);
|
||||
INSERT INTO `ACL` VALUES (919,'Worker','findById','READ','ALLOW','ROLE','$subordinate',10578);
|
||||
INSERT INTO `ACL` VALUES (919,'Worker','findById','READ','ALLOW','ROLE','employee',10578);
|
||||
INSERT INTO `ACL` VALUES (920,'QuadmindsApiConfig','*','*','ALLOW','ROLE','delivery',19295);
|
||||
INSERT INTO `ACL` VALUES (921,'Worker','findById','READ','ALLOW','ROLE','employee',NULL);
|
||||
INSERT INTO `ACL` VALUES (922,'SaleGroup','*','WRITE','ALLOW','ROLE','production',19294);
|
||||
INSERT INTO `ACL` VALUES (923,'Worker','__get__advancedSummary','READ','ALLOW','ROLE','hr',10578);
|
||||
INSERT INTO `ACL` VALUES (924,'Worker','__get__summary','READ','ALLOW','ROLE','employee',10578);
|
||||
INSERT INTO `ACL` VALUES (925,'Postcode','*','WRITE','ALLOW','ROLE','administrative',10578);
|
||||
INSERT INTO `ACL` VALUES (926,'Province','*','WRITE','ALLOW','ROLE','administrative',10578);
|
||||
INSERT INTO `ACL` VALUES (927,'Town','*','WRITE','ALLOW','ROLE','administrative',10578);
|
||||
INSERT INTO `ACL` VALUES (928,'ExpeditionStateType','*','READ','ALLOW','ROLE','employee',19294);
|
||||
INSERT INTO `ACL` VALUES (929,'ExpeditionState','addExpeditionState','WRITE','ALLOW','ROLE','delivery',19294);
|
||||
INSERT INTO `ACL` VALUES (930,'SupplierAccount','*','READ','ALLOW','ROLE','buyer',783);
|
||||
INSERT INTO `ACL` VALUES (931,'StockBought','*','READ','ALLOW','ROLE','buyer',10578);
|
||||
INSERT INTO `ACL` VALUES (932,'StockBought','*','WRITE','ALLOW','ROLE','buyer',10578);
|
||||
INSERT INTO `ACL` VALUES (933,'Buyer','*','READ','ALLOW','ROLE','buyer',10578);
|
||||
INSERT INTO `ACL` VALUES (934,'Ticket','setWeight','WRITE','ALLOW','ROLE','salesPerson',10578);
|
||||
INSERT INTO `ACL` VALUES (935,'BankEntity','*','WRITE','ALLOW','ROLE','financial',10578);
|
||||
INSERT INTO `ACL` VALUES (936,'Device','handleUser','*','ALLOW','ROLE','employee',10578);
|
||||
INSERT INTO `ACL` VALUES (937,'WorkerTimeControlMail','count','READ','ALLOW','ROLE','employee',10578);
|
||||
INSERT INTO `ACL` VALUES (938,'Worker','__get__mail','READ','ALLOW','ROLE','hr',10578);
|
||||
|
||||
INSERT INTO `fieldAcl` VALUES (1,'Client','name','update','employee');
|
||||
INSERT INTO `fieldAcl` VALUES (2,'Client','contact','update','employee');
|
||||
|
@ -2437,6 +2513,7 @@ INSERT INTO `component` VALUES (45,'maná reclamacion',7,4,NULL,0,'manaClaim',0)
|
|||
INSERT INTO `component` VALUES (46,'recargo a particular',2,NULL,0.25,0,'individual',0);
|
||||
INSERT INTO `component` VALUES (48,'fusión de lineas',4,NULL,NULL,1,'lineFusion',0);
|
||||
INSERT INTO `component` VALUES (49,'sustitución',4,NULL,NULL,1,'substitution',0);
|
||||
INSERT INTO `component` VALUES (50,'bonus',4,NULL,NULL,1,'bonus',0);
|
||||
|
||||
INSERT INTO `componentType` VALUES (1,'cost','coste',1,0);
|
||||
INSERT INTO `componentType` VALUES (2,NULL,'com ventas',1,1);
|
||||
|
@ -2511,7 +2588,7 @@ INSERT INTO `department` VALUES (136,'heavyVehicles','VEHICULOS PESADOS',110,111
|
|||
INSERT INTO `department` VALUES (137,'sorter','SORTER',112,113,NULL,0,0,0,1,0,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL,NULL,NULL);
|
||||
INSERT INTO `department` VALUES (139,'spainTeam4','EQUIPO ESPAÑA 4',67,68,3803,0,0,0,2,0,43,'/1/43/','es4_equipo',1,'es4@verdnatura.es',0,0,0,0,NULL,NULL,'5400',NULL);
|
||||
INSERT INTO `department` VALUES (140,'hollandTeam','EQUIPO HOLANDA',69,70,NULL,0,0,0,2,0,43,'/1/43/','nl_equipo',1,NULL,0,0,0,0,NULL,NULL,NULL,NULL);
|
||||
INSERT INTO `department` VALUES (141,NULL,'PREVIA',35,36,NULL,0,1,0,2,0,37,'/1/37/',NULL,0,NULL,0,0,0,1,NULL,NULL,NULL,NULL);
|
||||
INSERT INTO `department` VALUES (141,NULL,'PREVIA',35,36,NULL,0,1,0,2,0,37,'/1/37/',NULL,0,NULL,0,0,0,1,NULL,NULL,NULL,'PREVIOUS');
|
||||
INSERT INTO `department` VALUES (146,NULL,'VERDNACOLOMBIA',3,4,NULL,72,0,0,2,0,22,'/1/22/',NULL,0,NULL,0,0,0,0,NULL,NULL,NULL,NULL);
|
||||
INSERT INTO `department` VALUES (147,'spainTeamAsia','EQUIPO ESPAÑA ASIA',71,72,40214,0,0,0,2,0,43,'/1/43/','esA_equipo',0,'esA@verdnatura.es',0,0,0,0,NULL,NULL,'5500',NULL);
|
||||
|
||||
|
@ -2568,7 +2645,7 @@ INSERT INTO `sample` VALUES (16,'letter-debtor-nd','Aviso reiterado por saldo de
|
|||
INSERT INTO `sample` VALUES (17,'client-lcr','Email de solicitud de datos bancarios LCR',0,1,1,0,NULL);
|
||||
INSERT INTO `sample` VALUES (18,'client-debt-statement','Extracto del cliente',1,0,1,1,'Clients');
|
||||
INSERT INTO `sample` VALUES (19,'credit-request','Solicitud de crédito',1,1,1,0,'Clients');
|
||||
INSERT INTO `sample` VALUES (20,'incoterms-authorization','Autorización de incoterms',1,1,1,0,'Clients');
|
||||
INSERT INTO `sample` VALUES (20,'incoterms-authorization','Entregas intracomunitarias recogidas por el cliente',1,1,1,0,'Clients');
|
||||
|
||||
INSERT INTO `siiTrascendencyInvoiceIn` VALUES (1,'Operación de régimen general');
|
||||
INSERT INTO `siiTrascendencyInvoiceIn` VALUES (2,'Operaciones por las que los empresarios satisfacen compensaciones REAGYP');
|
||||
|
@ -2605,48 +2682,50 @@ INSERT INTO `siiTypeInvoiceOut` VALUES (7,'R3','Factura rectificativa (Art. 80.4
|
|||
INSERT INTO `siiTypeInvoiceOut` VALUES (8,'R4','Factura rectificativa (Resto)');
|
||||
INSERT INTO `siiTypeInvoiceOut` VALUES (9,'R5','Factura rectificativa en facturas simplificadas');
|
||||
|
||||
INSERT INTO `state` VALUES (1,'Arreglar',2,0,'FIXING',NULL,1,0,0,0,0,0,0,4,1,'alert');
|
||||
INSERT INTO `state` VALUES (2,'Libre',2,0,'FREE',NULL,2,0,0,0,0,0,0,4,1,'notice');
|
||||
INSERT INTO `state` VALUES (3,'OK',3,0,'OK',3,28,1,0,1,0,1,1,3,0,'success');
|
||||
INSERT INTO `state` VALUES (4,'Impreso',4,0,'PRINTED',2,29,1,0,1,0,0,1,2,0,'success');
|
||||
INSERT INTO `state` VALUES (5,'Preparación',6,2,'ON_PREPARATION',7,14,0,0,0,2,0,0,2,0,'warning');
|
||||
INSERT INTO `state` VALUES (6,'En Revisión',7,2,'ON_CHECKING',NULL,6,0,1,0,3,0,0,1,0,'warning');
|
||||
INSERT INTO `state` VALUES (7,'Sin Acabar',1,0,'NOT_READY',NULL,7,0,0,0,0,0,0,4,1,'alert');
|
||||
INSERT INTO `state` VALUES (8,'Revisado',8,2,'CHECKED',NULL,8,0,1,0,3,0,0,1,0,'warning');
|
||||
INSERT INTO `state` VALUES (9,'Encajando',9,3,'PACKING',NULL,9,0,1,0,0,0,0,1,0,NULL);
|
||||
INSERT INTO `state` VALUES (10,'Encajado',10,3,'PACKED',NULL,10,0,1,0,0,0,0,0,0,NULL);
|
||||
INSERT INTO `state` VALUES (11,'Facturado',0,4,'INVOICED',NULL,11,0,1,0,0,0,0,0,0,NULL);
|
||||
INSERT INTO `state` VALUES (12,'Bloqueado',0,0,'BLOCKED',NULL,12,0,0,0,0,0,0,4,1,'alert');
|
||||
INSERT INTO `state` VALUES (13,'En Reparto',11,4,'ON_DELIVERY',NULL,13,0,1,0,0,0,0,0,0,NULL);
|
||||
INSERT INTO `state` VALUES (14,'Preparado',6,2,'PREPARED',NULL,14,0,1,0,2,0,0,1,0,'warning');
|
||||
INSERT INTO `state` VALUES (15,'Pte Recogida',12,4,'WAITING_FOR_PICKUP',NULL,15,0,1,0,0,0,0,0,0,NULL);
|
||||
INSERT INTO `state` VALUES (16,'Entregado',13,4,'DELIVERED',NULL,16,0,1,0,0,0,0,0,0,NULL);
|
||||
INSERT INTO `state` VALUES (20,'Asignado',4,0,'PICKER_DESIGNED',NULL,20,1,0,0,0,0,0,2,0,'success');
|
||||
INSERT INTO `state` VALUES (21,'Retornado',4,2,'PRINTED_BACK',6,21,0,0,0,0,0,0,2,0,'success');
|
||||
INSERT INTO `state` VALUES (22,'Pte. Ampliar',2,0,'EXPANDABLE',NULL,22,0,0,0,0,0,0,4,1,'alert');
|
||||
INSERT INTO `state` VALUES (23,'URGENTE',5,2,'LAST_CALL',NULL,23,1,0,1,0,0,0,4,1,'success');
|
||||
INSERT INTO `state` VALUES (24,'Encadenado',4,0,'CHAINED',4,24,0,0,0,0,0,0,3,1,'success');
|
||||
INSERT INTO `state` VALUES (25,'Embarcando',3,0,'BOARDING',5,25,1,0,0,0,0,0,3,0,'alert');
|
||||
INSERT INTO `state` VALUES (26,'Prep Previa',5,0,'PREVIOUS_PREPARATION',1,28,1,0,0,1,0,0,2,0,'warning');
|
||||
INSERT INTO `state` VALUES (27,'Prep Asistida',5,2,'ASSISTED_PREPARATION',7,27,0,0,0,0,0,0,2,0,'success');
|
||||
INSERT INTO `state` VALUES (28,'Previa OK',3,0,'OK PREVIOUS',3,28,1,0,1,1,1,1,3,0,'warning');
|
||||
INSERT INTO `state` VALUES (29,'Previa Impreso',4,0,'PRINTED PREVIOUS',2,29,1,0,1,0,0,1,2,0,'success');
|
||||
INSERT INTO `state` VALUES (30,'Embarcado',4,2,'BOARD',5,30,0,0,0,2,0,0,3,0,'success');
|
||||
INSERT INTO `state` VALUES (31,'Polizon Impreso',4,2,'PRINTED STOWAWAY',2,29,1,0,1,0,0,1,2,0,'success');
|
||||
INSERT INTO `state` VALUES (32,'Polizon OK',3,2,'OK STOWAWAY',3,31,1,0,0,1,1,1,3,0,'warning');
|
||||
INSERT INTO `state` VALUES (33,'Auto_Impreso',4,0,'PRINTED_AUTO',2,29,1,0,1,0,0,1,2,0,'success');
|
||||
INSERT INTO `state` VALUES (34,'Pte Pago',3,0,'WAITING_FOR_PAYMENT',NULL,34,0,0,0,0,0,0,4,1,'alert');
|
||||
INSERT INTO `state` VALUES (35,'Semi-Encajado',9,3,'HALF_PACKED',NULL,10,0,1,0,0,0,0,1,0,NULL);
|
||||
INSERT INTO `state` VALUES (36,'Previa Revisando',3,0,'PREVIOUS_CONTROL',2,37,1,0,0,4,0,1,2,0,'warning');
|
||||
INSERT INTO `state` VALUES (37,'Previa Revisado',3,0,'PREVIOUS_CONTROLLED',2,29,1,0,1,0,0,1,2,0,'warning');
|
||||
INSERT INTO `state` VALUES (38,'Prep Cámara',6,2,'COOLER_PREPARATION',7,14,0,0,0,2,0,0,2,0,'warning');
|
||||
INSERT INTO `state` VALUES (41,'Prep Parcial',6,2,'PARTIAL_PREPARATION',7,14,0,0,0,2,0,0,2,0,'warning');
|
||||
INSERT INTO `state` VALUES (42,'Entregado en parte',13,3,'PARTIAL_DELIVERED',NULL,16,0,1,0,0,0,0,0,0,NULL);
|
||||
INSERT INTO `state` VALUES (43,'Preparación por caja',6,2,'BOX_PICKING',7,42,0,0,0,2,0,0,2,0,'warning');
|
||||
INSERT INTO `state` VALUES (1,'Arreglar',2,0,'FIXING',1,0,0,0,0,0,0,4,1,'alert');
|
||||
INSERT INTO `state` VALUES (2,'Libre',2,0,'FREE',2,0,0,0,0,0,0,4,1,'notice');
|
||||
INSERT INTO `state` VALUES (3,'OK',3,0,'OK',28,1,0,1,0,1,1,3,0,'success');
|
||||
INSERT INTO `state` VALUES (4,'Impreso',4,0,'PRINTED',29,1,0,1,0,0,1,2,0,'success');
|
||||
INSERT INTO `state` VALUES (5,'Preparación',6,2,'ON_PREPARATION',14,0,0,0,2,0,0,2,0,'warning');
|
||||
INSERT INTO `state` VALUES (6,'En Revisión',7,2,'ON_CHECKING',6,0,1,0,3,0,0,1,0,'warning');
|
||||
INSERT INTO `state` VALUES (7,'Sin Acabar',1,0,'NOT_READY',7,0,0,0,0,0,0,4,1,'alert');
|
||||
INSERT INTO `state` VALUES (8,'Revisado',8,2,'CHECKED',8,0,1,0,3,0,0,1,0,'warning');
|
||||
INSERT INTO `state` VALUES (9,'Encajando',9,3,'PACKING',9,0,1,0,0,0,0,1,0,NULL);
|
||||
INSERT INTO `state` VALUES (10,'Encajado',10,3,'PACKED',10,0,1,0,0,0,0,0,0,NULL);
|
||||
INSERT INTO `state` VALUES (11,'Facturado',0,4,'INVOICED',11,0,1,0,0,0,0,0,0,NULL);
|
||||
INSERT INTO `state` VALUES (12,'Bloqueado',0,0,'BLOCKED',12,0,0,0,0,0,0,4,1,'alert');
|
||||
INSERT INTO `state` VALUES (13,'En Reparto',11,4,'ON_DELIVERY',13,0,1,0,0,0,0,0,0,NULL);
|
||||
INSERT INTO `state` VALUES (14,'Preparado',6,2,'PREPARED',14,0,1,0,2,0,0,1,0,'warning');
|
||||
INSERT INTO `state` VALUES (15,'Pte Recogida',12,4,'WAITING_FOR_PICKUP',15,0,1,0,0,0,0,0,0,NULL);
|
||||
INSERT INTO `state` VALUES (16,'Entregado',13,4,'DELIVERED',16,0,1,0,0,0,0,0,0,NULL);
|
||||
INSERT INTO `state` VALUES (20,'Asignado',4,0,'PICKER_DESIGNED',20,1,0,0,0,0,0,2,0,'success');
|
||||
INSERT INTO `state` VALUES (21,'Retornado',4,2,'PRINTED_BACK',21,0,0,0,0,0,0,2,0,'success');
|
||||
INSERT INTO `state` VALUES (22,'Pte. Ampliar',2,0,'EXPANDABLE',22,0,0,0,0,0,0,4,1,'alert');
|
||||
INSERT INTO `state` VALUES (23,'URGENTE',5,2,'LAST_CALL',23,1,0,1,0,0,0,4,1,'success');
|
||||
INSERT INTO `state` VALUES (24,'Encadenado',4,0,'CHAINED',24,0,0,0,0,0,0,3,1,'success');
|
||||
INSERT INTO `state` VALUES (25,'Embarcando',3,0,'BOARDING',25,1,0,0,0,0,0,3,0,'alert');
|
||||
INSERT INTO `state` VALUES (26,'Prep Previa',5,0,'PREVIOUS_PREPARATION',28,1,0,0,1,0,0,2,0,'warning');
|
||||
INSERT INTO `state` VALUES (27,'Prep Asistida',5,2,'ASSISTED_PREPARATION',27,0,0,0,0,0,0,2,0,'success');
|
||||
INSERT INTO `state` VALUES (28,'Previa OK',3,0,'OK PREVIOUS',28,1,0,1,1,1,1,3,0,'warning');
|
||||
INSERT INTO `state` VALUES (29,'Previa Impreso',4,0,'PRINTED PREVIOUS',29,1,0,1,0,0,1,2,0,'success');
|
||||
INSERT INTO `state` VALUES (30,'Embarcado',4,2,'BOARD',30,0,0,0,2,0,0,3,0,'success');
|
||||
INSERT INTO `state` VALUES (31,'Polizon Impreso',4,2,'PRINTED STOWAWAY',29,1,0,1,0,0,1,2,0,'success');
|
||||
INSERT INTO `state` VALUES (32,'Polizon OK',3,2,'OK STOWAWAY',31,1,0,0,1,1,1,3,0,'warning');
|
||||
INSERT INTO `state` VALUES (33,'Auto_Impreso',4,0,'PRINTED_AUTO',29,1,0,1,0,0,1,2,0,'success');
|
||||
INSERT INTO `state` VALUES (34,'Pte Pago',3,0,'WAITING_FOR_PAYMENT',34,0,0,0,0,0,0,4,1,'alert');
|
||||
INSERT INTO `state` VALUES (35,'Semi-Encajado',9,3,'HALF_PACKED',10,0,1,0,0,0,0,1,0,NULL);
|
||||
INSERT INTO `state` VALUES (36,'Previa Revisando',3,0,'PREVIOUS_CONTROL',37,1,0,0,4,0,1,2,0,'warning');
|
||||
INSERT INTO `state` VALUES (37,'Previa Revisado',3,0,'PREVIOUS_CONTROLLED',29,1,0,1,0,0,1,2,0,'warning');
|
||||
INSERT INTO `state` VALUES (38,'Prep Cámara',6,2,'COOLER_PREPARATION',14,0,0,0,2,0,0,2,0,'warning');
|
||||
INSERT INTO `state` VALUES (41,'Prep Parcial',6,2,'PARTIAL_PREPARATION',14,0,0,0,2,0,0,2,0,'warning');
|
||||
INSERT INTO `state` VALUES (42,'Entregado en parte',13,3,'PARTIAL_DELIVERED',16,0,1,0,0,0,0,0,0,NULL);
|
||||
INSERT INTO `state` VALUES (43,'Preparación por caja',6,2,'BOX_PICKING',42,0,0,0,2,0,0,2,0,'warning');
|
||||
|
||||
INSERT INTO `ticketUpdateAction` VALUES (1,'Cambiar los precios en el ticket','renewPrices');
|
||||
INSERT INTO `ticketUpdateAction` VALUES (2,'Convertir en maná','mana');
|
||||
|
||||
INSERT INTO `ticketCanAdvanceConfig` VALUES (1,5);
|
||||
|
||||
INSERT INTO `volumeConfig` VALUES (2.67,1.60,0.8,150,0.30,120,57,2.0,50,200,10,167.0);
|
||||
|
||||
INSERT INTO `workCenter` VALUES (1,'Silla',20,859,1,'Av espioca 100',552703,NULL);
|
||||
|
@ -2659,6 +2738,7 @@ INSERT INTO `workCenter` VALUES (7,'Tenerife',NULL,NULL,NULL,NULL,NULL,NULL);
|
|||
INSERT INTO `workCenter` VALUES (8,'Silla-Agrario',26,NULL,NULL,NULL,NULL,NULL);
|
||||
INSERT INTO `workCenter` VALUES (9,'Algemesi',20,1354,60,'Fenollars, 2',523549,NULL);
|
||||
INSERT INTO `workCenter` VALUES (10,'Rubi',88,NULL,84,'Av. de la Llana, 131',549722,NULL);
|
||||
INSERT INTO `workCenter` VALUES (11,'Colombia',NULL,NULL,NULL,NULL,NULL,NULL);
|
||||
|
||||
INSERT INTO `workerTimeControlError` VALUES (1,'IS_NOT_ALLOWED_FUTURE','No se permite fichar a futuro');
|
||||
INSERT INTO `workerTimeControlError` VALUES (2,'INACTIVE_BUSINESS','No hay un contrato en vigor');
|
||||
|
|
|
@ -1471,6 +1471,9 @@ INSERT IGNORE INTO `tables_priv` VALUES ('','vn','productionAssi','tillSerial','
|
|||
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','stockBuyed','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
|
||||
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','employee','alertLevel','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
|
||||
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','workerActivityType','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
|
||||
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','buyer','priceDelta','jenkins@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select,Insert,Update,Delete','');
|
||||
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','parkingLog','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
|
||||
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','travelLog','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
|
||||
/*!40000 ALTER TABLE `tables_priv` ENABLE KEYS */;
|
||||
|
||||
/*!40000 ALTER TABLE `columns_priv` DISABLE KEYS */;
|
||||
|
@ -2072,7 +2075,7 @@ INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','itemshelving_addby
|
|||
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','itemShelvingSale_addByCollection','PROCEDURE','carlosap@db-proxy1.servers.dc.verdnatura.es','Execute','0000-00-00 00:00:00');
|
||||
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','itemshelving_addlist','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
|
||||
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','itemshelving_selfconsumption','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
|
||||
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','cooler','item_getSimilar','PROCEDURE','guillermo@db-proxy1.servers.dc.verdnatura.es','Execute','0000-00-00 00:00:00');
|
||||
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','cooler','item_getSimilar','PROCEDURE','guillermo@db-proxy2.servers.dc.verdnatura.es','Execute','0000-00-00 00:00:00');
|
||||
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','itemshelvingsale_add','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
|
||||
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','collection_printsticker','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
|
||||
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','deviceproductionuser_getworker','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
|
||||
|
@ -2123,7 +2126,7 @@ INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','itemshelving_filterb
|
|||
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','itemshelving_addbyclaim','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
|
||||
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','itemshelving_addlist','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
|
||||
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','itemshelving_selfconsumption','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
|
||||
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','reviewer','item_getSimilar','PROCEDURE','guillermo@db-proxy1.servers.dc.verdnatura.es','Execute','0000-00-00 00:00:00');
|
||||
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','reviewer','item_getSimilar','PROCEDURE','guillermo@10.5.1.6','Execute','0000-00-00 00:00:00');
|
||||
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','itemshelvingsale_add','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
|
||||
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','collection_printsticker','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
|
||||
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','deviceproductionuser_getworker','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
|
||||
|
@ -2191,6 +2194,7 @@ INSERT IGNORE INTO `procs_priv` VALUES ('','vn','employee','buy_recalcPricesByEn
|
|||
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','entryEditor','buy_recalcPricesByBuy','PROCEDURE','jenkins@db-proxy2.servers.dc.verdnatura.es','Execute','0000-00-00 00:00:00');
|
||||
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','claimManager','buy_recalcPricesByBuy','PROCEDURE','jenkins@db-proxy2.servers.dc.verdnatura.es','Execute','0000-00-00 00:00:00');
|
||||
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','employee','buy_recalcPricesByBuy','PROCEDURE','jenkins@db-proxy2.servers.dc.verdnatura.es','Execute','0000-00-00 00:00:00');
|
||||
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','itemShelvingSale_addBySaleGroup','PROCEDURE','alexm@db-proxy2.servers.dc.verdnatura.es','Execute','0000-00-00 00:00:00');
|
||||
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','hr','ledger_nextTx','PROCEDURE','guillermo@db-proxy2.servers.dc.verdnatura.es','Execute','0000-00-00 00:00:00');
|
||||
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','hr','ledger_docompensation','PROCEDURE','guillermo@db-proxy2.servers.dc.verdnatura.es','Execute','0000-00-00 00:00:00');
|
||||
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','itemShelvingSale_setQuantity','PROCEDURE','carlosap@db-proxy1.servers.dc.verdnatura.es','Execute','0000-00-00 00:00:00');
|
||||
|
@ -2206,6 +2210,8 @@ INSERT IGNORE INTO `procs_priv` VALUES ('','vn','grafana-write','item_ValuateInv
|
|||
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','guest','ticketCalculatePurge','PROCEDURE','jenkins@db-proxy2.servers.dc.verdnatura.es','Execute','0000-00-00 00:00:00');
|
||||
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','buyer','buy_getUltimate','PROCEDURE','guillermo@db-proxy2.servers.dc.verdnatura.es','Execute','0000-00-00 00:00:00');
|
||||
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','cooler','buy_getUltimate','PROCEDURE','guillermo@db-proxy2.servers.dc.verdnatura.es','Execute','0000-00-00 00:00:00');
|
||||
INSERT IGNORE INTO `procs_priv` VALUES ('','bs','buyerBoss','waste_addSales','PROCEDURE','jenkins@db-proxy1.servers.dc.verdnatura.es','Execute','0000-00-00 00:00:00');
|
||||
INSERT IGNORE INTO `procs_priv` VALUES ('','bs','grafana','waste_addSales','PROCEDURE','guillermo@db-proxy2.servers.dc.verdnatura.es','Execute','0000-00-00 00:00:00');
|
||||
/*!40000 ALTER TABLE `procs_priv` ENABLE KEYS */;
|
||||
|
||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -4306,35 +4306,13 @@ DELIMITER ;
|
|||
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
|
||||
/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;
|
||||
DELIMITER ;;
|
||||
/*!50003 CREATE*/ /*!50017 DEFINER=`vn`@`localhost`*/ /*!50003 TRIGGER `vn`.`creditInsurance_beforeInsert`
|
||||
BEFORE INSERT ON `creditInsurance`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
IF NEW.creditClassificationFk THEN
|
||||
SET NEW.creditClassification = NEW.creditClassificationFk;
|
||||
END IF;
|
||||
END */;;
|
||||
DELIMITER ;
|
||||
/*!50003 SET sql_mode = @saved_sql_mode */ ;
|
||||
/*!50003 SET character_set_client = @saved_cs_client */ ;
|
||||
/*!50003 SET character_set_results = @saved_cs_results */ ;
|
||||
/*!50003 SET collation_connection = @saved_col_connection */ ;
|
||||
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
|
||||
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
|
||||
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
|
||||
/*!50003 SET character_set_client = utf8mb4 */ ;
|
||||
/*!50003 SET character_set_results = utf8mb4 */ ;
|
||||
/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ;
|
||||
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
|
||||
/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;
|
||||
DELIMITER ;;
|
||||
/*!50003 CREATE*/ /*!50017 DEFINER=`vn`@`localhost`*/ /*!50003 TRIGGER `vn`.`creditInsurance_afterInsert`
|
||||
AFTER INSERT ON `creditInsurance`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
UPDATE `client` c
|
||||
JOIN vn.creditClassification cc ON cc.client = c.id
|
||||
SET creditInsurance = NEW.credit WHERE cc.id = NEW.creditClassification;
|
||||
SET creditInsurance = NEW.credit WHERE cc.id = NEW.creditClassificationFk;
|
||||
|
||||
END */;;
|
||||
DELIMITER ;
|
||||
|
@ -5018,7 +4996,10 @@ BEGIN
|
|||
SET NEW.currencyFk = entry_getCurrency(NEW.currencyFk, NEW.supplierFk);
|
||||
END IF;
|
||||
|
||||
IF NOT (NEW.travelFk <=> OLD.travelFk) OR NOT (NEW.currencyFk <=> OLD.currencyFk) THEN
|
||||
IF NOT (NEW.travelFk <=> OLD.travelFk)
|
||||
OR NOT (NEW.currencyFk <=> OLD.currencyFk)
|
||||
OR NOT (NEW.supplierFk <=> OLD.supplierFk) THEN
|
||||
|
||||
SET NEW.commission = entry_getCommission(NEW.travelFk, NEW.currencyFk, NEW.supplierFk);
|
||||
END IF;
|
||||
END */;;
|
||||
|
@ -5552,7 +5533,7 @@ DELIMITER ;
|
|||
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
|
||||
/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;
|
||||
DELIMITER ;;
|
||||
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`host_beforeInsert`
|
||||
/*!50003 CREATE*/ /*!50017 DEFINER=`vn`@`localhost`*/ /*!50003 TRIGGER `vn`.`host_beforeInsert`
|
||||
BEFORE INSERT ON `host`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
|
@ -6518,6 +6499,36 @@ BEGIN
|
|||
SET NEW.userFk = account.myUser_getId();
|
||||
SET NEW.available = NEW.visible;
|
||||
|
||||
END */;;
|
||||
DELIMITER ;
|
||||
/*!50003 SET sql_mode = @saved_sql_mode */ ;
|
||||
/*!50003 SET character_set_client = @saved_cs_client */ ;
|
||||
/*!50003 SET character_set_results = @saved_cs_results */ ;
|
||||
/*!50003 SET collation_connection = @saved_col_connection */ ;
|
||||
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
|
||||
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
|
||||
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
|
||||
/*!50003 SET character_set_client = utf8mb4 */ ;
|
||||
/*!50003 SET character_set_results = utf8mb4 */ ;
|
||||
/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ;
|
||||
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
|
||||
/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;
|
||||
DELIMITER ;;
|
||||
/*!50003 CREATE*/ /*!50017 DEFINER=`vn`@`localhost`*/ /*!50003 TRIGGER `vn`.`itemShelving_afterInsert`
|
||||
AFTER INSERT ON `itemShelving`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
INSERT INTO itemShelvingLog
|
||||
SET itemShelvingFk = NEW.id,
|
||||
workerFk = account.myUser_getId(),
|
||||
accion = 'CREA REGISTRO',
|
||||
itemFk = NEW.itemFk,
|
||||
shelvingFk = NEW.shelvingFk,
|
||||
visible = NEW.visible,
|
||||
`grouping` = NEW.`grouping`,
|
||||
packing = NEW.packing,
|
||||
available = NEW.available;
|
||||
|
||||
END */;;
|
||||
DELIMITER ;
|
||||
/*!50003 SET sql_mode = @saved_sql_mode */ ;
|
||||
|
@ -7925,7 +7936,7 @@ DELIMITER ;
|
|||
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
|
||||
/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;
|
||||
DELIMITER ;;
|
||||
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`roadmap_beforeInsert`
|
||||
/*!50003 CREATE*/ /*!50017 DEFINER=`vn`@`localhost`*/ /*!50003 TRIGGER `vn`.`roadmap_beforeInsert`
|
||||
BEFORE INSERT ON `roadmap`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
|
@ -7949,7 +7960,7 @@ DELIMITER ;
|
|||
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
|
||||
/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;
|
||||
DELIMITER ;;
|
||||
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`roadmap_beforeUpdate`
|
||||
/*!50003 CREATE*/ /*!50017 DEFINER=`vn`@`localhost`*/ /*!50003 TRIGGER `vn`.`roadmap_beforeUpdate`
|
||||
BEFORE UPDATE ON `roadmap`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
|
@ -8604,7 +8615,7 @@ DELIMITER ;
|
|||
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
|
||||
/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;
|
||||
DELIMITER ;;
|
||||
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`saleGroupDetail_beforeInsert`
|
||||
/*!50003 CREATE*/ /*!50017 DEFINER=`vn`@`localhost`*/ /*!50003 TRIGGER `vn`.`saleGroupDetail_beforeInsert`
|
||||
BEFORE INSERT ON `saleGroupDetail`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
|
@ -8624,7 +8635,7 @@ DELIMITER ;
|
|||
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
|
||||
/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;
|
||||
DELIMITER ;;
|
||||
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`saleGroupDetail_beforeUpdate`
|
||||
/*!50003 CREATE*/ /*!50017 DEFINER=`vn`@`localhost`*/ /*!50003 TRIGGER `vn`.`saleGroupDetail_beforeUpdate`
|
||||
BEFORE UPDATE ON `saleGroupDetail`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
|
@ -8644,7 +8655,7 @@ DELIMITER ;
|
|||
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
|
||||
/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;
|
||||
DELIMITER ;;
|
||||
/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER `vn`.`saleGroupDetail_afterDelete`
|
||||
/*!50003 CREATE*/ /*!50017 DEFINER=`vn`@`localhost`*/ /*!50003 TRIGGER `vn`.`saleGroupDetail_afterDelete`
|
||||
AFTER DELETE ON `saleGroupDetail`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
|
@ -8925,7 +8936,7 @@ DELIMITER ;;
|
|||
BEGIN
|
||||
UPDATE client c
|
||||
JOIN creditClassification cc ON cc.client = c.id
|
||||
JOIN creditInsurance ci ON ci.creditClassification = cc.id
|
||||
JOIN creditInsurance ci ON ci.creditClassificationFk = cc.id
|
||||
SET creditInsurance = ci.credit * 2 WHERE ci.id = NEW.creditInsurance;
|
||||
END */;;
|
||||
DELIMITER ;
|
||||
|
@ -8949,12 +8960,12 @@ BEGIN
|
|||
IF NEW.dateLeaving IS NOT NULL THEN
|
||||
UPDATE client c
|
||||
JOIN creditClassification cc ON cc.client = c.id
|
||||
JOIN creditInsurance ci ON ci.creditClassification = cc.id
|
||||
JOIN creditInsurance ci ON ci.creditClassificationFk = cc.id
|
||||
SET creditInsurance = ci.credit WHERE ci.id = OLD.creditInsurance;
|
||||
ELSE
|
||||
UPDATE client c
|
||||
JOIN creditClassification cc ON cc.client = c.id
|
||||
JOIN creditInsurance ci ON ci.creditClassification = cc.id
|
||||
JOIN creditInsurance ci ON ci.creditClassificationFk = cc.id
|
||||
SET creditInsurance = ci.credit * 2 WHERE ci.id = OLD.creditInsurance;
|
||||
END IF;
|
||||
END */;;
|
||||
|
@ -8978,7 +8989,7 @@ DELIMITER ;;
|
|||
BEGIN
|
||||
UPDATE client c
|
||||
JOIN creditClassification cc ON cc.client = c.id
|
||||
JOIN creditInsurance ci ON ci.creditClassification = cc.id
|
||||
JOIN creditInsurance ci ON ci.creditClassificationFk = cc.id
|
||||
SET creditInsurance = ci.credit WHERE ci.id = OLD.creditInsurance;
|
||||
END */;;
|
||||
DELIMITER ;
|
||||
|
@ -10852,8 +10863,8 @@ DELIMITER ;
|
|||
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
|
||||
/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;
|
||||
DELIMITER ;;
|
||||
/*!50003 CREATE*/ /*!50017 DEFINER=`vn`@`localhost`*/ /*!50003 TRIGGER `vn`.`workerDocument_beforeInsert`
|
||||
BEFORE INSERT ON `workerDocument`
|
||||
/*!50003 CREATE*/ /*!50017 DEFINER=`vn`@`localhost`*/ /*!50003 TRIGGER `vn`.`workerDms_beforeInsert`
|
||||
BEFORE INSERT ON `workerDms`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.editorFk = account.myUser_getId();
|
||||
|
@ -10872,8 +10883,8 @@ DELIMITER ;
|
|||
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
|
||||
/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;
|
||||
DELIMITER ;;
|
||||
/*!50003 CREATE*/ /*!50017 DEFINER=`vn`@`localhost`*/ /*!50003 TRIGGER `vn`.`workerDocument_beforeUpdate`
|
||||
BEFORE UPDATE ON `workerDocument`
|
||||
/*!50003 CREATE*/ /*!50017 DEFINER=`vn`@`localhost`*/ /*!50003 TRIGGER `vn`.`workerDms_beforeUpdate`
|
||||
BEFORE UPDATE ON `workerDms`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.editorFk = account.myUser_getId();
|
||||
|
@ -10892,13 +10903,13 @@ DELIMITER ;
|
|||
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
|
||||
/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;
|
||||
DELIMITER ;;
|
||||
/*!50003 CREATE*/ /*!50017 DEFINER=`vn`@`localhost`*/ /*!50003 TRIGGER `vn`.`workerDocument_afterDelete`
|
||||
AFTER DELETE ON `workerDocument`
|
||||
/*!50003 CREATE*/ /*!50017 DEFINER=`vn`@`localhost`*/ /*!50003 TRIGGER `vn`.`workerDms_afterDelete`
|
||||
AFTER DELETE ON `workerDms`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
INSERT INTO workerLog
|
||||
SET `action` = 'delete',
|
||||
`changedModel` = 'WorkerDocument',
|
||||
`changedModel` = 'WorkerDms',
|
||||
`changedModelId` = OLD.id,
|
||||
`userFk` = account.myUser_getId();
|
||||
END */;;
|
||||
|
@ -11458,4 +11469,4 @@ USE `vn2008`;
|
|||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||
|
||||
-- Dump completed on 2024-09-18 9:32:59
|
||||
-- Dump completed on 2024-10-03 7:43:14
|
||||
|
|
|
@ -185,6 +185,7 @@ INSERT INTO `vn`.`warehouse`(`id`, `name`, `code`, `isComparative`, `isInventory
|
|||
(3, 'Warehouse Three', NULL, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0),
|
||||
(4, 'Warehouse Four', NULL, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1),
|
||||
(5, 'Warehouse Five', NULL, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0),
|
||||
(6, 'Warehouse six', 'vnh', 1, 1, 1, 1, 0, 0, 1, 1, 0, 0),
|
||||
(13, 'Inventory', 'inv', 1, 1, 1, 0, 0, 0, 1, 0, 0, 0),
|
||||
(60, 'Algemesi', NULL, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0);
|
||||
|
||||
|
@ -3941,6 +3942,11 @@ INSERT INTO vn.medicalReview
|
|||
(id, workerFk, centerFk, `date`, `time`, isFit, amount, invoice, remark)
|
||||
VALUES(3, 9, 2, '2000-01-01', '8:00', 1, 150.0, NULL, NULL);
|
||||
|
||||
INSERT INTO vn.stockBought (workerFk, bought, reserve, dated)
|
||||
VALUES(35, 1.00, 1.00, '2001-01-01');
|
||||
INSERT INTO vn.auctionConfig (id,conversionCoefficient,warehouseFk)
|
||||
VALUES (1,0.6,6);
|
||||
|
||||
INSERT INTO vn.payrollComponent
|
||||
(id, name, isSalaryAgreed, isVariable, isException)
|
||||
VALUES
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`vn`@`localhost`
|
||||
PROCEDURE `hedera`.`orderRow_updateOverstocking`(vOrderFk INT)
|
||||
BEGIN
|
||||
/**
|
||||
* Set amount = 0 to avoid overbooking sales
|
||||
*
|
||||
* @param vOrderFk hedera.order.id
|
||||
*/
|
||||
DECLARE vCalcFk INT;
|
||||
DECLARE vDone BOOL;
|
||||
DECLARE vWarehouseFk INT;
|
||||
|
||||
DECLARE cWarehouses CURSOR FOR
|
||||
SELECT DISTINCT warehouseFk
|
||||
FROM orderRow
|
||||
WHERE orderFk = vOrderFk
|
||||
AND shipment = util.VN_CURDATE();
|
||||
|
||||
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
|
||||
|
||||
DECLARE EXIT HANDLER FOR SQLEXCEPTION
|
||||
BEGIN
|
||||
ROLLBACK;
|
||||
RESIGNAL;
|
||||
END;
|
||||
|
||||
OPEN cWarehouses;
|
||||
checking: LOOP
|
||||
SET vDone = FALSE;
|
||||
|
||||
FETCH cWarehouses INTO vWarehouseFk;
|
||||
|
||||
IF vDone THEN
|
||||
LEAVE checking;
|
||||
END IF;
|
||||
|
||||
CALL cache.available_refresh(vCalcFk, FALSE, vWarehouseFk, util.VN_CURDATE());
|
||||
|
||||
UPDATE orderRow r
|
||||
JOIN `order` o ON o.id = r.orderFk
|
||||
JOIN orderConfig oc
|
||||
JOIN cache.available a ON a.calc_id = vCalcFk AND a.item_id = r.itemFk
|
||||
SET r.amount = 0
|
||||
WHERE ADDTIME(o.rowUpdated, oc.reserveTime) < util.VN_NOW()
|
||||
AND a.available <= 0
|
||||
AND r.warehouseFk = vWarehouseFk
|
||||
AND r.orderFk = vOrderFk;
|
||||
END LOOP;
|
||||
CLOSE cWarehouses;
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -12,6 +12,7 @@ BEGIN
|
|||
* @param vUser The user identifier
|
||||
*/
|
||||
DECLARE vHasRows BOOL;
|
||||
DECLARE vHas0Amount BOOL;
|
||||
DECLARE vDone BOOL;
|
||||
DECLARE vWarehouseFk INT;
|
||||
DECLARE vShipment DATE;
|
||||
|
@ -97,6 +98,20 @@ BEGIN
|
|||
SELECT employeeFk INTO vUserFk FROM orderConfig;
|
||||
END IF;
|
||||
|
||||
CALL orderRow_updateOverstocking(vSelf);
|
||||
|
||||
-- Check if any product has a quantity of 0
|
||||
SELECT EXISTS (
|
||||
SELECT id
|
||||
FROM orderRow
|
||||
WHERE orderFk = vSelf
|
||||
AND amount = 0
|
||||
) INTO vHas0Amount;
|
||||
|
||||
IF vHas0Amount THEN
|
||||
CALL util.throw('Remove lines with quantity = 0 before confirming');
|
||||
END IF;
|
||||
|
||||
START TRANSACTION;
|
||||
|
||||
CALL order_checkEditable(vSelf);
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `hedera`.`orderRow_afterInsert`
|
||||
AFTER INSERT ON `orderRow`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
UPDATE `order`
|
||||
SET rowUpdated = NOW()
|
||||
WHERE id = NEW.orderFk;
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -1,20 +0,0 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`buy_getVolumeByAgency`(vDated DATE, vAgencyFk INT)
|
||||
BEGIN
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp.buy;
|
||||
CREATE TEMPORARY TABLE tmp.buy (buyFk INT NOT NULL, PRIMARY KEY (buyFk)) ENGINE = MEMORY;
|
||||
|
||||
INSERT INTO tmp.buy
|
||||
SELECT b.id
|
||||
FROM buy b
|
||||
JOIN entry e ON e.id = b.entryFk
|
||||
JOIN travel t ON t.id = e.travelFk
|
||||
WHERE t.landed = vDated
|
||||
AND t.agencyModeFk IN (0, vAgencyFk);
|
||||
|
||||
CALL buy_getVolume();
|
||||
DROP TEMPORARY TABLE tmp.buy;
|
||||
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -57,12 +57,6 @@ BEGIN
|
|||
DELETE FROM claim WHERE ticketCreated < v4Years;
|
||||
-- Robert ubicacion anterior de travelLog comentario para debug
|
||||
DELETE FROM zoneEvent WHERE `type` = 'day' AND dated < v3Months;
|
||||
DELETE bm
|
||||
FROM buyMark bm
|
||||
JOIN buy b ON b.id = bm.id
|
||||
JOIN entry e ON e.id = b.entryFk
|
||||
JOIN travel t ON t.id = e.travelFk
|
||||
WHERE t.landed <= v2Months;
|
||||
DELETE b FROM buy b
|
||||
JOIN entryConfig e ON e.defaultEntry = b.entryFk
|
||||
WHERE b.created < v2Months;
|
||||
|
|
|
@ -118,9 +118,19 @@ BEGIN
|
|||
IF vCollectionFk IS NULL THEN
|
||||
CALL collection_new(vUserFk, vCollectionFk);
|
||||
|
||||
UPDATE `collection`
|
||||
SET workerFk = vUserFk
|
||||
WHERE id = vCollectionFk;
|
||||
START TRANSACTION;
|
||||
|
||||
SELECT workerFk INTO vCollectionWorker
|
||||
FROM `collection`
|
||||
WHERE id = vCollectionFk FOR UPDATE;
|
||||
|
||||
IF vCollectionWorker IS NULL THEN
|
||||
UPDATE `collection`
|
||||
SET workerFk = vUserFk
|
||||
WHERE id = vCollectionFk;
|
||||
END IF;
|
||||
|
||||
COMMIT;
|
||||
END IF;
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -21,9 +21,8 @@ BEGIN
|
|||
SELECT tob.ticketFk, tob.description
|
||||
FROM vn.ticketObservation tob
|
||||
JOIN vn.ticketCollection tc ON tc.ticketFk = tob.ticketFk
|
||||
LEFT JOIN vn.observationType ot ON ot.id = tob.observationTypeFk
|
||||
WHERE ot.`code` = 'itemPicker'
|
||||
AND tc.collectionFk = vParamFk OR tc.ticketFk = vParamFk
|
||||
JOIN vn.observationType ot ON ot.id = tob.observationTypeFk AND ot.`code` = 'itemPicker'
|
||||
WHERE tc.collectionFk = vParamFk OR tc.ticketFk = vParamFk
|
||||
)
|
||||
SELECT t.id ticketFk,
|
||||
IF(!(vItemPackingTypeFk <=> 'V'), cc.code, CONCAT(SUBSTRING('ABCDEFGH', tc.wagon, 1), '-', tc.`level`)) `level`,
|
||||
|
|
|
@ -5,22 +5,26 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`expeditionPallet_buil
|
|||
vWorkerFk INT,
|
||||
OUT vPalletFk INT
|
||||
)
|
||||
BEGIN
|
||||
/** Construye un pallet de expediciones.
|
||||
proc: BEGIN
|
||||
/**
|
||||
* Builds an expedition pallet.
|
||||
*
|
||||
* Primero comprueba si esas expediciones ya pertenecen a otro pallet,
|
||||
* en cuyo caso actualiza ese pallet.
|
||||
* First, it checks if these expeditions already belong to another pallet,
|
||||
* in which case it returns an error.
|
||||
*
|
||||
* @param vExpeditions JSON_ARRAY con esta estructura [exp1, exp2, exp3, ...]
|
||||
* @param vArcId INT Identificador de arcRead
|
||||
* @param vWorkerFk INT Identificador de worker
|
||||
* @param out vPalletFk Identificador de expeditionPallet
|
||||
* @param vExpeditions JSON_ARRAY with this structure [exp1, exp2, exp3, ...]
|
||||
* @param vArcId INT Identifier of arcRead
|
||||
* @param vWorkerFk INT Identifier of worker
|
||||
* @param out vPalletFk Identifier of expeditionPallet
|
||||
*/
|
||||
|
||||
DECLARE vCounter INT;
|
||||
DECLARE vExpeditionFk INT;
|
||||
DECLARE vTruckFk INT;
|
||||
DECLARE vPrinterFk INT;
|
||||
DECLARE vExpeditionStateTypeFk INT;
|
||||
DECLARE vFreeExpeditionCount INT;
|
||||
DECLARE vExpeditionWithPallet INT;
|
||||
|
||||
CREATE OR REPLACE TEMPORARY TABLE tExpedition (
|
||||
expeditionFk INT,
|
||||
|
@ -44,48 +48,63 @@ BEGIN
|
|||
WHERE e.id = vExpeditionFk;
|
||||
END WHILE;
|
||||
|
||||
SELECT palletFk INTO vPalletFk
|
||||
FROM (
|
||||
SELECT palletFk, count(*) n
|
||||
FROM tExpedition
|
||||
WHERE palletFk > 0
|
||||
GROUP BY palletFk
|
||||
ORDER BY n DESC
|
||||
LIMIT 100
|
||||
) sub
|
||||
LIMIT 1;
|
||||
SELECT COUNT(expeditionFk) INTO vFreeExpeditionCount
|
||||
FROM tExpedition
|
||||
WHERE palletFk IS NULL;
|
||||
|
||||
IF vPalletFk IS NULL THEN
|
||||
SELECT roadmapStopFk INTO vTruckFk
|
||||
FROM (
|
||||
SELECT rm.roadmapStopFk, count(*) n
|
||||
FROM routesMonitor rm
|
||||
JOIN tExpedition e ON e.routeFk = rm.routeFk
|
||||
GROUP BY roadmapStopFk
|
||||
ORDER BY n DESC
|
||||
LIMIT 1
|
||||
) sub;
|
||||
SELECT COUNT(expeditionFk) INTO vExpeditionWithPallet
|
||||
FROM tExpedition
|
||||
WHERE palletFk;
|
||||
|
||||
IF vTruckFk IS NULL THEN
|
||||
CALL util.throw ('TRUCK_NOT_AVAILABLE');
|
||||
END IF;
|
||||
|
||||
INSERT INTO expeditionPallet SET truckFk = vTruckFk;
|
||||
|
||||
SET vPalletFk = LAST_INSERT_ID();
|
||||
IF vExpeditionWithPallet THEN
|
||||
UPDATE arcRead
|
||||
SET error = (
|
||||
SELECT GROUP_CONCAT(expeditionFk SEPARATOR ', ')
|
||||
FROM tExpedition
|
||||
WHERE palletFk
|
||||
)
|
||||
WHERE id = vArcId;
|
||||
LEAVE proc;
|
||||
END IF;
|
||||
|
||||
IF NOT vFreeExpeditionCount THEN
|
||||
CALL util.throw ('NO_FREE_EXPEDITIONS');
|
||||
END IF;
|
||||
|
||||
SELECT roadmapStopFk INTO vTruckFk
|
||||
FROM (
|
||||
SELECT rm.roadmapStopFk, count(*) n
|
||||
FROM routesMonitor rm
|
||||
JOIN tExpedition e ON e.routeFk = rm.routeFk
|
||||
WHERE e.palletFk IS NULL
|
||||
GROUP BY roadmapStopFk
|
||||
ORDER BY n DESC
|
||||
LIMIT 1
|
||||
) sub;
|
||||
|
||||
IF vTruckFk IS NULL THEN
|
||||
CALL util.throw ('TRUCK_NOT_AVAILABLE');
|
||||
END IF;
|
||||
|
||||
INSERT INTO expeditionPallet SET truckFk = vTruckFk;
|
||||
|
||||
SET vPalletFk = LAST_INSERT_ID();
|
||||
|
||||
INSERT INTO expeditionScan(expeditionFk, palletFk, workerFk)
|
||||
SELECT expeditionFk, vPalletFk, vWorkerFk
|
||||
FROM tExpedition
|
||||
ON DUPLICATE KEY UPDATE palletFk = vPalletFk, workerFk = vWorkerFk;
|
||||
WHERE palletFk IS NULL;
|
||||
|
||||
SELECT id INTO vExpeditionStateTypeFk
|
||||
FROM expeditionStateType
|
||||
WHERE code = 'PALLETIZED';
|
||||
|
||||
INSERT INTO expeditionState(expeditionFk, typeFk)
|
||||
SELECT expeditionFk, vExpeditionStateTypeFk FROM tExpedition;
|
||||
SELECT expeditionFk, vExpeditionStateTypeFk
|
||||
FROM tExpedition
|
||||
WHERE palletFk IS NULL;
|
||||
|
||||
UPDATE arcRead SET error = NULL WHERE id = vArcId;
|
||||
|
||||
SELECT printerFk INTO vPrinterFk FROM arcRead WHERE id = vArcId;
|
||||
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`invoiceOut_newFromAddress`(
|
||||
IN vAddressFk INT,
|
||||
IN vSerial CHAR(2),
|
||||
IN vMaxShipped DATE,
|
||||
IN vCompanyFk INT,
|
||||
IN vTaxArea VARCHAR(25),
|
||||
IN vRef VARCHAR(25),
|
||||
OUT vInvoiceId INT)
|
||||
BEGIN
|
||||
/**
|
||||
* Factura los tickets de un consignatario hasta una fecha dada
|
||||
* @param vAddressFk Id del consignatario a facturar
|
||||
* @param vSerial Serie de factura
|
||||
* @param vMaxShipped Fecha hasta la cual cogerá tickets para facturar
|
||||
* @param vCompanyFk Id de la empresa desde la que se factura
|
||||
* @param vTaxArea Tipo de iva en relacion a la empresa y al cliente, NULL por defecto
|
||||
* @param vRef Referencia de la factura en caso que se quiera forzar, NULL por defecto
|
||||
* @return vInvoiceId factura
|
||||
*/
|
||||
DECLARE vIsRefEditable BOOLEAN;
|
||||
|
||||
IF vRef IS NOT NULL AND vSerial IS NOT NULL THEN
|
||||
SELECT isRefEditable INTO vIsRefEditable
|
||||
FROM invoiceOutSerial
|
||||
WHERE code = vSerial;
|
||||
|
||||
IF NOT vIsRefEditable THEN
|
||||
CALL util.throw('serial non editable');
|
||||
END IF;
|
||||
END IF;
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS `tmp`.`ticketToInvoice`;
|
||||
CREATE TEMPORARY TABLE `tmp`.`ticketToInvoice`
|
||||
(PRIMARY KEY (`id`))
|
||||
ENGINE = MEMORY
|
||||
SELECT id FROM ticket t
|
||||
WHERE t.addressFk = vAddressFk
|
||||
AND t.refFk IS NULL
|
||||
AND t.companyFk = vCompanyFk
|
||||
AND t.shipped BETWEEN
|
||||
util.firstDayOfYear(vMaxShipped - INTERVAL 1 YEAR)
|
||||
AND util.dayend(vMaxShipped);
|
||||
|
||||
CALL invoiceOut_new(vSerial, util.VN_CURDATE(), vTaxArea, vInvoiceId);
|
||||
|
||||
UPDATE invoiceOut
|
||||
SET `ref` = vRef
|
||||
WHERE id = vInvoiceId
|
||||
AND vRef IS NOT NULL;
|
||||
|
||||
IF vSerial <> 'R' AND NOT ISNULL(vInvoiceId) AND vInvoiceId <> 0 THEN
|
||||
CALL invoiceOutBooking(vInvoiceId);
|
||||
END IF;
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -1,16 +1,22 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`itemShelving_addList`(vShelvingFk VARCHAR(3), vList TEXT, vIsChecking BOOL, vWarehouseFk INT)
|
||||
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`itemShelving_addList`(
|
||||
vShelvingFk VARCHAR(3),
|
||||
vList TEXT,
|
||||
vIsChecking BOOL,
|
||||
vWarehouseFk INT
|
||||
)
|
||||
BEGIN
|
||||
/* Recorre cada elemento en la colección vList.
|
||||
/**
|
||||
* Recorre cada elemento en la colección vList.
|
||||
* Si el parámetro isChecking = FALSE, llama a itemShelving_add.
|
||||
*
|
||||
* Cuando es TRUE sólo inserta los elementos de la colección que no están ya en
|
||||
* ese shelving, actualizando los valores del campo vn.itemShelving.isChecked
|
||||
* ese shelving, actualizando los valores del campo itemShelving.isChecked
|
||||
*
|
||||
* param vShelvingFk Identificador de vn.shelving
|
||||
* param vList JSON array con esta estructura: '[value1, value2, ...]'
|
||||
* param vIsChecking Define si hay que añadir o comprobar los items
|
||||
* param vWarehouseFk Identificador de vn.warehouse
|
||||
* @param vShelvingFk Identificador de shelving
|
||||
* @param vList JSON array con esta estructura: '[value1, value2, ...]'
|
||||
* @param vIsChecking Define si hay que añadir o comprobar los items
|
||||
* @param vWarehouseFk Identificador de warehouse
|
||||
*/
|
||||
DECLARE vListLength INT DEFAULT JSON_LENGTH(vList);
|
||||
DECLARE vCounter INT DEFAULT 0;
|
||||
|
@ -20,26 +26,27 @@ BEGIN
|
|||
DECLARE vIsChecked BOOL;
|
||||
|
||||
WHILE vCounter < vListLength DO
|
||||
SET vPath = CONCAT('$[',vCounter,']');
|
||||
SET vBarcode = JSON_EXTRACT(vList,vPath);
|
||||
SET vPath = CONCAT('$[', vCounter, ']');
|
||||
SET vBarcode = JSON_EXTRACT(vList, vPath);
|
||||
SET vIsChecked = NULL;
|
||||
IF vIsChecking THEN
|
||||
SELECT barcodeToItem(vBarcode) INTO vItemFk;
|
||||
|
||||
SELECT COUNT(*) INTO vIsChecked
|
||||
FROM vn.itemShelving
|
||||
SELECT IF(COUNT(*), TRUE, FALSE) INTO vIsChecked
|
||||
FROM itemShelving
|
||||
WHERE shelvingFk COLLATE utf8_unicode_ci = vShelvingFk
|
||||
AND itemFk = vItemFk;
|
||||
END IF;
|
||||
|
||||
IF NOT (vIsChecking AND vIsChecked) THEN
|
||||
CALL vn.itemShelving_add(vShelvingFk, vBarcode, 1, NULL, NULL, NULL, vWarehouseFk);
|
||||
IF NOT vIsChecking OR NOT vIsChecked THEN
|
||||
CALL itemShelving_add(vShelvingFk, vBarcode, 1, NULL, NULL, NULL, vWarehouseFk);
|
||||
END IF;
|
||||
|
||||
UPDATE vn.itemShelving
|
||||
UPDATE itemShelving
|
||||
SET isChecked = vIsChecked
|
||||
WHERE shelvingFk COLLATE utf8_unicode_ci = vShelvingFk
|
||||
AND itemFk = vItemFk AND isChecked IS NULL;
|
||||
AND itemFk = vItemFk
|
||||
AND isChecked IS NULL;
|
||||
|
||||
SET vCounter = vCounter + 1;
|
||||
END WHILE;
|
||||
|
|
|
@ -8,19 +8,22 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`item_getSimilar`(
|
|||
)
|
||||
BEGIN
|
||||
/**
|
||||
* Propone articulos ordenados, con la cantidad
|
||||
* de veces usado y segun sus caracteristicas.
|
||||
*
|
||||
* @param vSelf Id de artículo
|
||||
* @param vWarehouseFk Id de almacen
|
||||
* @param vDated Fecha
|
||||
* @param vShowType Mostrar tipos
|
||||
* @param vDaysInForward Días de alcance para las ventas
|
||||
*/
|
||||
* Propone articulos ordenados, con la cantidad
|
||||
* de veces usado y segun sus caracteristicas.
|
||||
*
|
||||
* @param vSelf Id de artículo
|
||||
* @param vWarehouseFk Id de almacen
|
||||
* @param vDated Fecha
|
||||
* @param vShowType Mostrar tipos
|
||||
* @param vDaysInForward Días de alcance para las ventas (https://redmine.verdnatura.es/issues/7956#note-4)
|
||||
*/
|
||||
DECLARE vAvailableCalcFk INT;
|
||||
DECLARE vVisibleCalcFk INT;
|
||||
DECLARE vTypeFk INT;
|
||||
DECLARE vPriority INT DEFAULT 1;
|
||||
|
||||
CALL cache.available_refresh(vAvailableCalcFk, FALSE, vWarehouseFk, vDated);
|
||||
CALL cache.visible_refresh(vVisibleCalcFk, FALSE, vWarehouseFk);
|
||||
|
||||
WITH itemTags AS (
|
||||
SELECT i.id,
|
||||
|
@ -40,25 +43,9 @@ BEGIN
|
|||
AND it.priority = vPriority
|
||||
LEFT JOIN vn.tag t ON t.id = it.tagFk
|
||||
WHERE i.id = vSelf
|
||||
),
|
||||
stock AS (
|
||||
SELECT itemFk, SUM(visible) stock
|
||||
FROM vn.itemShelvingStock
|
||||
WHERE warehouseFk = vWarehouseFk
|
||||
GROUP BY itemFk
|
||||
),
|
||||
sold AS (
|
||||
SELECT SUM(s.quantity) quantity, s.itemFk
|
||||
FROM vn.sale s
|
||||
JOIN vn.ticket t ON t.id = s.ticketFk
|
||||
LEFT JOIN vn.itemShelvingSale iss ON iss.saleFk = s.id
|
||||
WHERE t.shipped >= CURDATE() + INTERVAL vDaysInForward DAY
|
||||
AND iss.saleFk IS NULL
|
||||
AND t.warehouseFk = vWarehouseFk
|
||||
GROUP BY s.itemFk
|
||||
)
|
||||
SELECT i.id itemFk,
|
||||
LEAST(CAST(sd.quantity AS INT), sk.stock) advanceable,
|
||||
NULL advanceable, -- https://redmine.verdnatura.es/issues/7956#note-4
|
||||
i.longName,
|
||||
i.subName,
|
||||
i.tag5,
|
||||
|
@ -80,13 +67,13 @@ BEGIN
|
|||
WHEN b.groupingMode = 'packing' THEN b.packing
|
||||
ELSE 1
|
||||
END minQuantity,
|
||||
sk.stock located,
|
||||
v.visible located,
|
||||
b.price2
|
||||
FROM vn.item i
|
||||
LEFT JOIN sold sd ON sd.itemFk = i.id
|
||||
JOIN cache.available a ON a.item_id = i.id
|
||||
AND a.calc_id = vAvailableCalcFk
|
||||
LEFT JOIN stock sk ON sk.itemFk = i.id
|
||||
LEFT JOIN cache.visible v ON v.item_id = i.id
|
||||
AND v.calc_id = vVisibleCalcFk
|
||||
LEFT JOIN cache.last_buy lb ON lb.item_id = i.id
|
||||
AND lb.warehouse_id = vWarehouseFk
|
||||
LEFT JOIN vn.itemProposal ip ON ip.mateFk = i.id
|
||||
|
@ -96,21 +83,20 @@ BEGIN
|
|||
LEFT JOIN vn.tag t ON t.id = it.tagFk
|
||||
LEFT JOIN vn.buy b ON b.id = lb.buy_id
|
||||
JOIN itemTags its
|
||||
WHERE (a.available > 0 OR sd.quantity < sk.stock)
|
||||
WHERE a.available > 0
|
||||
AND (i.typeFk = its.typeFk OR NOT vShowType)
|
||||
AND i.id <> vSelf
|
||||
ORDER BY (a.available > 0) DESC,
|
||||
`counter` DESC,
|
||||
(t.name = its.name) DESC,
|
||||
(it.value = its.value) DESC,
|
||||
(i.tag5 = its.tag5) DESC,
|
||||
match5 DESC,
|
||||
(i.tag6 = its.tag6) DESC,
|
||||
match6 DESC,
|
||||
(i.tag7 = its.tag7) DESC,
|
||||
match7 DESC,
|
||||
(i.tag8 = its.tag8) DESC,
|
||||
match8 DESC
|
||||
ORDER BY `counter` DESC,
|
||||
(t.name = its.name) DESC,
|
||||
(it.value = its.value) DESC,
|
||||
(i.tag5 = its.tag5) DESC,
|
||||
match5 DESC,
|
||||
(i.tag6 = its.tag6) DESC,
|
||||
match6 DESC,
|
||||
(i.tag7 = its.tag7) DESC,
|
||||
match7 DESC,
|
||||
(i.tag8 = its.tag8) DESC,
|
||||
match8 DESC
|
||||
LIMIT 100;
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
CREATE OR REPLACE DEFINER=`root`@`localhost`
|
||||
SQL SECURITY DEFINER
|
||||
VIEW `vn2008`.`Compres_mark`
|
||||
AS SELECT `bm`.`id` AS `Id_Compra`,
|
||||
`bm`.`comment` AS `comment`,
|
||||
`bm`.`mark` AS `mark`,
|
||||
`bm`.`odbcDate` AS `odbc_date`
|
||||
FROM `vn`.`buyMark` `bm`
|
|
@ -0,0 +1,7 @@
|
|||
UPDATE vn.itemShelving
|
||||
SET isChecked = TRUE
|
||||
WHERE isChecked;
|
||||
|
||||
UPDATE vn.itemShelving
|
||||
SET isChecked = FALSE
|
||||
WHERE NOT isChecked;
|
|
@ -0,0 +1,22 @@
|
|||
CREATE TABLE IF NOT EXISTS `vn`.`itemStateTag` (
|
||||
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(50) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `name_UNIQUE` (`name`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT
|
||||
CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||
|
||||
INSERT IGNORE INTO `vn`.`itemStateTag` (`name`) VALUES ('Artificial');
|
||||
INSERT IGNORE INTO `vn`.`itemStateTag` (`name`) VALUES ('Inactivo');
|
||||
INSERT IGNORE INTO `vn`.`itemStateTag` (`name`) VALUES ('Preservado');
|
||||
INSERT IGNORE INTO `vn`.`itemStateTag` (`name`) VALUES ('Seco');
|
||||
INSERT IGNORE INTO `vn`.`itemStateTag` (`name`) VALUES ('Seco y preservado');
|
||||
INSERT IGNORE INTO `vn`.`itemStateTag` (`name`) VALUES ('Estabilizada');
|
||||
INSERT IGNORE INTO `vn`.`itemStateTag` (`name`) VALUES ('Natural y seco');
|
||||
INSERT IGNORE INTO `vn`.`itemStateTag` (`name`) VALUES ('Preservado y artificial');
|
||||
INSERT IGNORE INTO `vn`.`itemStateTag` (`name`) VALUES ('Usado');
|
||||
|
||||
UPDATE vn.tag
|
||||
SET isFree=0,
|
||||
sourceTable='itemStateTag'
|
||||
WHERE name= 'Estado';
|
|
@ -0,0 +1,3 @@
|
|||
-- Place your SQL code here
|
||||
ALTER TABLE hedera.`order` ADD IF NOT EXISTS rowUpdated DATETIME NULL
|
||||
COMMENT 'Timestamp for last updated record in orderRow table';
|
|
@ -0,0 +1 @@
|
|||
DROP TABLE IF EXISTS vn.buyMark;
|
|
@ -1,46 +0,0 @@
|
|||
import getBrowser from '../../helpers/puppeteer';
|
||||
|
||||
const $ = {
|
||||
id: 'vn-order-summary vn-one:nth-child(1) > vn-label-value:nth-child(1) span',
|
||||
alias: 'vn-order-summary vn-one:nth-child(1) > vn-label-value:nth-child(2) span',
|
||||
consignee: 'vn-order-summary vn-one:nth-child(2) > vn-label-value:nth-child(6) span',
|
||||
subtotal: 'vn-order-summary vn-one.taxes > p:nth-child(1)',
|
||||
vat: 'vn-order-summary vn-one.taxes > p:nth-child(2)',
|
||||
total: 'vn-order-summary vn-one.taxes > p:nth-child(3)',
|
||||
sale: 'vn-order-summary vn-tbody > vn-tr',
|
||||
};
|
||||
|
||||
describe('Order summary path', () => {
|
||||
let browser;
|
||||
let page;
|
||||
beforeAll(async() => {
|
||||
browser = await getBrowser();
|
||||
page = browser.page;
|
||||
await page.loginAndModule('employee', 'order');
|
||||
await page.accessToSearchResult('16');
|
||||
});
|
||||
|
||||
afterAll(async() => {
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should reach the order summary section and check data', async() => {
|
||||
await page.waitForState('order.card.summary');
|
||||
|
||||
const id = await page.innerText($.id);
|
||||
const alias = await page.innerText($.alias);
|
||||
const consignee = await page.innerText($.consignee);
|
||||
const subtotal = await page.innerText($.subtotal);
|
||||
const vat = await page.innerText($.vat);
|
||||
const total = await page.innerText($.total);
|
||||
const sale = await page.countElement($.sale);
|
||||
|
||||
expect(id).toEqual('16');
|
||||
expect(alias).toEqual('Many places');
|
||||
expect(consignee).toEqual('address 26 - Gotham (Province one)');
|
||||
expect(subtotal.length).toBeGreaterThan(1);
|
||||
expect(vat.length).toBeGreaterThan(1);
|
||||
expect(total.length).toBeGreaterThan(1);
|
||||
expect(sale).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
|
@ -1,69 +0,0 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import getBrowser from '../../helpers/puppeteer';
|
||||
|
||||
const $ = {
|
||||
form: 'vn-order-basic-data form',
|
||||
observation: 'vn-order-basic-data form [vn-name="note"]',
|
||||
saveButton: `vn-order-basic-data form button[type=submit]`,
|
||||
acceptButton: '.vn-confirm.shown button[response="accept"]'
|
||||
};
|
||||
|
||||
describe('Order edit basic data path', () => {
|
||||
let browser;
|
||||
let page;
|
||||
|
||||
beforeAll(async() => {
|
||||
browser = await getBrowser();
|
||||
page = browser.page;
|
||||
|
||||
await page.loginAndModule('employee', 'order');
|
||||
await page.accessToSearchResult('1');
|
||||
await page.accessToSection('order.card.basicData');
|
||||
});
|
||||
|
||||
afterAll(async() => {
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
describe('when confirmed order', () => {
|
||||
it('should not be able to change the client', async() => {
|
||||
const message = await page.sendForm($.form, {
|
||||
client: 'Tony Stark',
|
||||
address: 'Tony Stark',
|
||||
});
|
||||
|
||||
expect(message.text).toContain(`You can't make changes on the basic data`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when new order', () => {
|
||||
it('should create an order and edit its basic data', async() => {
|
||||
await page.waitToClick(selectors.globalItems.returnToModuleIndexButton);
|
||||
await page.waitToClick($.acceptButton);
|
||||
await page.waitForContentLoaded();
|
||||
await page.waitToClick(selectors.ordersIndex.createOrderButton);
|
||||
await page.waitForState('order.create');
|
||||
|
||||
await page.autocompleteSearch(selectors.createOrderView.client, 'Jessica Jones');
|
||||
await page.pickDate(selectors.createOrderView.landedDatePicker);
|
||||
await page.autocompleteSearch(selectors.createOrderView.agency, 'Other agency');
|
||||
await page.waitToClick(selectors.createOrderView.createButton);
|
||||
await page.waitForState('order.card.catalog');
|
||||
|
||||
await page.accessToSection('order.card.basicData');
|
||||
|
||||
const values = {
|
||||
client: 'Tony Stark',
|
||||
address: 'Tony Stark',
|
||||
agencyMode: 'Other agency'
|
||||
};
|
||||
|
||||
const message = await page.sendForm($.form, values);
|
||||
await page.reloadSection('order.card.basicData');
|
||||
const formValues = await page.fetchForm($.form, Object.keys(values));
|
||||
|
||||
expect(message.isSuccess).toBeTrue();
|
||||
expect(formValues).toEqual(values);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,48 +0,0 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import getBrowser from '../../helpers/puppeteer';
|
||||
|
||||
describe('Order lines', () => {
|
||||
let browser;
|
||||
let page;
|
||||
beforeAll(async() => {
|
||||
browser = await getBrowser();
|
||||
page = browser.page;
|
||||
await page.loginAndModule('employee', 'order');
|
||||
await page.accessToSearchResult('8');
|
||||
await page.accessToSection('order.card.line');
|
||||
});
|
||||
|
||||
afterAll(async() => {
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should check the order subtotal', async() => {
|
||||
const result = await page
|
||||
.waitToGetProperty(selectors.orderLine.orderSubtotal, 'innerText');
|
||||
|
||||
expect(result).toContain('112.30');
|
||||
});
|
||||
|
||||
it('should delete the first line in the order', async() => {
|
||||
await page.waitToClick(selectors.orderLine.firstLineDeleteButton);
|
||||
await page.waitToClick(selectors.orderLine.confirmButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should confirm the order subtotal has changed', async() => {
|
||||
await page.waitForTextInElement(selectors.orderLine.orderSubtotal, '92.80');
|
||||
const result = await page
|
||||
.waitToGetProperty(selectors.orderLine.orderSubtotal, 'innerText');
|
||||
|
||||
expect(result).toContain('92.80');
|
||||
});
|
||||
|
||||
it('should confirm the whole order and redirect to ticket index filtered by clientFk', async() => {
|
||||
await page.waitToClick(selectors.orderLine.confirmOrder);
|
||||
|
||||
await page.expectURL('ticket/index');
|
||||
await page.expectURL('clientFk');
|
||||
});
|
||||
});
|
|
@ -1,97 +0,0 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import getBrowser from '../../helpers/puppeteer';
|
||||
|
||||
describe('Order catalog', () => {
|
||||
let browser;
|
||||
let page;
|
||||
|
||||
beforeAll(async() => {
|
||||
browser = await getBrowser();
|
||||
page = browser.page;
|
||||
await page.loginAndModule('employee', 'order');
|
||||
});
|
||||
|
||||
afterAll(async() => {
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should open the create new order form', async() => {
|
||||
await page.waitToClick(selectors.ordersIndex.createOrderButton);
|
||||
await page.waitForState('order.create');
|
||||
});
|
||||
|
||||
it('should create a new order', async() => {
|
||||
await page.autocompleteSearch(selectors.createOrderView.client, 'Tony Stark');
|
||||
await page.pickDate(selectors.createOrderView.landedDatePicker);
|
||||
await page.autocompleteSearch(selectors.createOrderView.agency, 'Other agency');
|
||||
await page.waitToClick(selectors.createOrderView.createButton);
|
||||
await page.waitForState('order.card.catalog');
|
||||
});
|
||||
|
||||
it('should add the realm and type filters and obtain results', async() => {
|
||||
await page.waitToClick(selectors.orderCatalog.plantRealmButton);
|
||||
await page.autocompleteSearch(selectors.orderCatalog.type, 'Anthurium');
|
||||
await page.waitForNumberOfElements('section.product', 4);
|
||||
const result = await page.countElement('section.product');
|
||||
|
||||
expect(result).toEqual(4);
|
||||
});
|
||||
|
||||
it('should perfom an "OR" search for the item tag colors silver and brown', async() => {
|
||||
await page.waitToClick(selectors.orderCatalog.openTagSearch);
|
||||
await page.autocompleteSearch(selectors.orderCatalog.tag, 'Color');
|
||||
await page.autocompleteSearch(selectors.orderCatalog.firstTagAutocomplete, 'silver');
|
||||
await page.waitToClick(selectors.orderCatalog.addTagButton);
|
||||
await page.autocompleteSearch(selectors.orderCatalog.secondTagAutocomplete, 'brown');
|
||||
await page.waitToClick(selectors.orderCatalog.searchTagButton);
|
||||
await page.waitForNumberOfElements('section.product', 4);
|
||||
});
|
||||
|
||||
it('should perfom an "OR" search for the item tag tallos 2 and 9', async() => {
|
||||
await page.waitToClick(selectors.orderCatalog.openTagSearch);
|
||||
await page.autocompleteSearch(selectors.orderCatalog.tag, 'Tallos');
|
||||
await page.write(selectors.orderCatalog.firstTagValue, '2');
|
||||
await page.waitToClick(selectors.orderCatalog.addTagButton);
|
||||
await page.write(selectors.orderCatalog.secondTagValue, '9');
|
||||
await page.waitToClick(selectors.orderCatalog.searchTagButton);
|
||||
await page.waitForNumberOfElements('section.product', 2);
|
||||
});
|
||||
|
||||
it('should perform a general search for category', async() => {
|
||||
await page.write(selectors.orderCatalog.itemTagValue, 'concussion');
|
||||
await page.keyboard.press('Enter');
|
||||
await page.waitForNumberOfElements('section.product', 2);
|
||||
});
|
||||
|
||||
it('should perfom an "AND" search for the item tag tallos 2', async() => {
|
||||
await page.waitToClick(selectors.orderCatalog.openTagSearch);
|
||||
await page.autocompleteSearch(selectors.orderCatalog.tag, 'Tallos');
|
||||
await page.write(selectors.orderCatalog.firstTagValue, '2');
|
||||
await page.waitToClick(selectors.orderCatalog.searchTagButton);
|
||||
await page.waitForNumberOfElements('section.product', 1);
|
||||
});
|
||||
|
||||
it('should remove the tag filters and have 4 results', async() => {
|
||||
await page.waitForContentLoaded();
|
||||
await page.waitToClick(selectors.orderCatalog.sixthFilterRemoveButton);
|
||||
await page.waitForContentLoaded();
|
||||
await page.waitToClick(selectors.orderCatalog.fifthFilterRemoveButton);
|
||||
await page.waitForContentLoaded();
|
||||
await page.waitToClick(selectors.orderCatalog.fourthFilterRemoveButton);
|
||||
await page.waitForContentLoaded();
|
||||
await page.waitToClick(selectors.orderCatalog.thirdFilterRemoveButton);
|
||||
|
||||
await page.waitForNumberOfElements('.product', 4);
|
||||
const result = await page.countElement('section.product');
|
||||
|
||||
expect(result).toEqual(4);
|
||||
});
|
||||
|
||||
it('should search for an item by id', async() => {
|
||||
await page.accessToSearchResult('2');
|
||||
await page.waitForNumberOfElements('section.product', 1);
|
||||
const result = await page.countElement('section.product');
|
||||
|
||||
expect(result).toEqual(1);
|
||||
});
|
||||
});
|
|
@ -1,34 +0,0 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import getBrowser from '../../helpers/puppeteer';
|
||||
|
||||
describe('Order Index', () => {
|
||||
let browser;
|
||||
let page;
|
||||
|
||||
beforeAll(async() => {
|
||||
browser = await getBrowser();
|
||||
page = browser.page;
|
||||
await page.loginAndModule('employee', 'order');
|
||||
});
|
||||
|
||||
afterAll(async() => {
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it(`should check the second search result doesn't contain a total of 0€`, async() => {
|
||||
await page.waitToClick(selectors.globalItems.searchButton);
|
||||
const result = await page.waitToGetProperty(selectors.ordersIndex.secondSearchResultTotal, 'innerText');
|
||||
|
||||
expect(result).not.toContain('0.00');
|
||||
});
|
||||
|
||||
it('should search including empty orders', async() => {
|
||||
await page.waitToClick(selectors.ordersIndex.openAdvancedSearch);
|
||||
await page.waitToClick(selectors.ordersIndex.advancedSearchShowEmptyCheckbox);
|
||||
await page.waitToClick(selectors.ordersIndex.advancedSearchButton);
|
||||
await page.waitForTextInElement(selectors.ordersIndex.secondSearchResultTotal, '0.00');
|
||||
const result = await page.waitToGetProperty(selectors.ordersIndex.secondSearchResultTotal, 'innerText');
|
||||
|
||||
expect(result).toContain('0.00');
|
||||
});
|
||||
});
|
|
@ -1,42 +0,0 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import getBrowser from '../../helpers/puppeteer';
|
||||
|
||||
describe('Travel create path', () => {
|
||||
let browser;
|
||||
let page;
|
||||
|
||||
beforeAll(async() => {
|
||||
browser = await getBrowser();
|
||||
page = browser.page;
|
||||
await page.loginAndModule('buyer', 'travel');
|
||||
});
|
||||
|
||||
afterAll(async() => {
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should create a new travel and check it was created with the correct data', async() => {
|
||||
const date = Date.vnNew();
|
||||
date.setDate(15);
|
||||
date.setUTCHours(0, 0, 0, 0);
|
||||
|
||||
await page.waitToClick(selectors.travelIndex.newTravelButton);
|
||||
await page.waitForState('travel.create');
|
||||
|
||||
const values = {
|
||||
reference: 'Testing reference',
|
||||
agencyMode: 'inhouse pickup',
|
||||
shipped: date,
|
||||
landed: date,
|
||||
warehouseOut: 'Warehouse One',
|
||||
warehouseIn: 'Warehouse Five'
|
||||
};
|
||||
|
||||
const message = await page.sendForm('vn-travel-create form', values);
|
||||
await page.waitForState('travel.card.basicData');
|
||||
const formValues = await page.fetchForm('vn-travel-basic-data form', Object.keys(values));
|
||||
|
||||
expect(message.isSuccess).toBeTrue();
|
||||
expect(formValues).toEqual(values);
|
||||
});
|
||||
});
|
|
@ -1,97 +0,0 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import getBrowser from '../../helpers/puppeteer';
|
||||
|
||||
describe('Travel basic data path', () => {
|
||||
let browser;
|
||||
let page;
|
||||
|
||||
beforeAll(async() => {
|
||||
browser = await getBrowser();
|
||||
page = browser.page;
|
||||
await page.loginAndModule('buyer', 'travel');
|
||||
await page.write(selectors.travelIndex.generalSearchFilter, '3');
|
||||
await page.keyboard.press('Enter');
|
||||
await page.accessToSection('travel.card.basicData');
|
||||
});
|
||||
|
||||
afterAll(async() => {
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should reach the thermograph section', async() => {
|
||||
await page.waitForState('travel.card.basicData');
|
||||
});
|
||||
|
||||
it('should set a wrong delivery date then receive an error on submit', async() => {
|
||||
await page.loginAndModule('buyer', 'travel');
|
||||
await page.write(selectors.travelIndex.generalSearchFilter, '4');
|
||||
await page.keyboard.press('Enter');
|
||||
await page.accessToSection('travel.card.basicData');
|
||||
await page.waitForState('travel.card.basicData');
|
||||
|
||||
const lastMonth = Date.vnNew();
|
||||
lastMonth.setMonth(lastMonth.getMonth() - 2);
|
||||
|
||||
await page.pickDate(selectors.travelBasicData.deliveryDate, lastMonth);
|
||||
await page.waitToClick(selectors.travelBasicData.save);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain('Landing cannot be lesser than shipment');
|
||||
});
|
||||
|
||||
it('should undo the changes', async() => {
|
||||
await page.clearInput(selectors.travelBasicData.reference);
|
||||
await page.write(selectors.travelBasicData.reference, 'totally pointless ref');
|
||||
await page.waitToClick(selectors.travelBasicData.undoChanges);
|
||||
const result = await page.waitToGetProperty(selectors.travelBasicData.reference, 'value');
|
||||
|
||||
expect(result).toEqual('fourth travel');
|
||||
});
|
||||
|
||||
it('should now edit the whole form then save', async() => {
|
||||
await page.clearInput(selectors.travelBasicData.reference);
|
||||
await page.write(selectors.travelBasicData.reference, 'new reference!');
|
||||
await page.autocompleteSearch(selectors.travelBasicData.agency, 'Entanglement');
|
||||
await page.autocompleteSearch(selectors.travelBasicData.outputWarehouse, 'Warehouse Three');
|
||||
await page.autocompleteSearch(selectors.travelBasicData.inputWarehouse, 'Warehouse Four');
|
||||
await page.waitToClick(selectors.travelBasicData.delivered);
|
||||
await page.waitToClick(selectors.travelBasicData.received);
|
||||
await page.waitToClick(selectors.travelBasicData.save);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should reload the section and check the reference was saved', async() => {
|
||||
await page.reloadSection('travel.card.basicData');
|
||||
const result = await page.waitToGetProperty(selectors.travelBasicData.reference, 'value');
|
||||
|
||||
expect(result).toEqual('new reference!');
|
||||
});
|
||||
|
||||
it('should check the agency was saved', async() => {
|
||||
const result = await page.waitToGetProperty(selectors.travelBasicData.agency, 'value');
|
||||
|
||||
expect(result).toEqual('Entanglement');
|
||||
});
|
||||
|
||||
it('should check the output warehouse date was saved', async() => {
|
||||
const result = await page.waitToGetProperty(selectors.travelBasicData.outputWarehouse, 'value');
|
||||
|
||||
expect(result).toEqual('Warehouse Three');
|
||||
});
|
||||
|
||||
it('should check the input warehouse date was saved', async() => {
|
||||
const result = await page.waitToGetProperty(selectors.travelBasicData.inputWarehouse, 'value');
|
||||
|
||||
expect(result).toEqual('Warehouse Four');
|
||||
});
|
||||
|
||||
it(`should check the delivered checkbox was saved even tho it doesn't make sense`, async() => {
|
||||
await page.waitForClassPresent(selectors.travelBasicData.delivered, 'checked');
|
||||
});
|
||||
|
||||
it(`should check the received checkbox was saved even tho it doesn't make sense`, async() => {
|
||||
await page.waitForClassPresent(selectors.travelBasicData.received, 'checked');
|
||||
});
|
||||
});
|
|
@ -1,36 +0,0 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import getBrowser from '../../helpers/puppeteer';
|
||||
|
||||
describe('Travel descriptor path', () => {
|
||||
let browser;
|
||||
let page;
|
||||
|
||||
beforeAll(async() => {
|
||||
browser = await getBrowser();
|
||||
page = browser.page;
|
||||
await page.loginAndModule('buyer', 'travel');
|
||||
await page.write(selectors.travelIndex.generalSearchFilter, '3');
|
||||
await page.keyboard.press('Enter');
|
||||
await page.waitForState('travel.card.summary');
|
||||
});
|
||||
|
||||
afterAll(async() => {
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should click the descriptor button to navigate to the travel index showing all travels with current agency', async() => {
|
||||
await page.waitToClick(selectors.travelDescriptor.filterByAgencyButton);
|
||||
await page.waitForState('travel.index');
|
||||
const result = await page.countElement(selectors.travelIndex.anySearchResult);
|
||||
|
||||
expect(result).toBeGreaterThanOrEqual(1);
|
||||
});
|
||||
|
||||
it('should navigate to the first search result', async() => {
|
||||
await page.waitToClick(selectors.travelIndex.firstSearchResult);
|
||||
await page.waitForState('travel.card.summary');
|
||||
const state = await page.getState();
|
||||
|
||||
expect(state).toBe('travel.card.summary');
|
||||
});
|
||||
});
|
|
@ -1,42 +0,0 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import getBrowser from '../../helpers/puppeteer';
|
||||
|
||||
describe('Travel extra community path', () => {
|
||||
let browser;
|
||||
let page;
|
||||
|
||||
beforeAll(async() => {
|
||||
browser = await getBrowser();
|
||||
page = browser.page;
|
||||
await page.loginAndModule('buyer', 'travel');
|
||||
await page.accessToSection('travel.extraCommunity');
|
||||
});
|
||||
|
||||
afterAll(async() => {
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should edit the travel reference and the locked kilograms', async() => {
|
||||
await page.waitToClick(selectors.travelExtraCommunity.removeContinentFilter);
|
||||
await page.waitForSpinnerLoad();
|
||||
await page.writeOnEditableTD(selectors.travelExtraCommunity.firstTravelReference, 'edited reference');
|
||||
await page.waitForSpinnerLoad();
|
||||
await page.writeOnEditableTD(selectors.travelExtraCommunity.firstTravelLockedKg, '1500');
|
||||
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain('Data saved!');
|
||||
});
|
||||
|
||||
it('should reload the index and confirm the reference and locked kg were edited', async() => {
|
||||
await page.accessToSection('travel.index');
|
||||
await page.accessToSection('travel.extraCommunity');
|
||||
await page.waitToClick(selectors.travelExtraCommunity.removeContinentFilter);
|
||||
await page.waitForTextInElement(selectors.travelExtraCommunity.firstTravelReference, 'edited reference');
|
||||
const reference = await page.getProperty(selectors.travelExtraCommunity.firstTravelReference, 'innerText');
|
||||
const lockedKg = await page.getProperty(selectors.travelExtraCommunity.firstTravelLockedKg, 'innerText');
|
||||
|
||||
expect(reference).toContain('edited reference');
|
||||
expect(lockedKg).toContain(1500);
|
||||
});
|
||||
});
|
|
@ -1,62 +0,0 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import getBrowser from '../../helpers/puppeteer';
|
||||
|
||||
describe('Travel search panel path', () => {
|
||||
let browser;
|
||||
let page;
|
||||
let httpRequest;
|
||||
|
||||
beforeAll(async() => {
|
||||
browser = await getBrowser();
|
||||
page = browser.page;
|
||||
await page.loginAndModule('buyer', 'travel');
|
||||
page.on('request', req => {
|
||||
if (req.url().includes(`Travels/filter`))
|
||||
httpRequest = req.url();
|
||||
});
|
||||
});
|
||||
|
||||
afterAll(async() => {
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should filter using all the fields', async() => {
|
||||
await page.click(selectors.travelIndex.chip);
|
||||
await page.write(selectors.travelIndex.generalSearchFilter, 'travel');
|
||||
await page.keyboard.press('Enter');
|
||||
|
||||
expect(httpRequest).toContain('search=travel');
|
||||
|
||||
await page.click(selectors.travelIndex.chip);
|
||||
await page.autocompleteSearch(selectors.travelIndex.agencyFilter, 'Entanglement');
|
||||
|
||||
expect(httpRequest).toContain('agencyModeFk');
|
||||
|
||||
await page.click(selectors.travelIndex.chip);
|
||||
await page.autocompleteSearch(selectors.travelIndex.warehouseOutFilter, 'Warehouse One');
|
||||
|
||||
expect(httpRequest).toContain('warehouseOutFk');
|
||||
|
||||
await page.click(selectors.travelIndex.chip);
|
||||
await page.autocompleteSearch(selectors.travelIndex.warehouseInFilter, 'Warehouse Two');
|
||||
|
||||
expect(httpRequest).toContain('warehouseInFk');
|
||||
|
||||
await page.click(selectors.travelIndex.chip);
|
||||
await page.overwrite(selectors.travelIndex.scopeDaysFilter, '15');
|
||||
await page.keyboard.press('Enter');
|
||||
|
||||
expect(httpRequest).toContain('scopeDays=15');
|
||||
|
||||
await page.click(selectors.travelIndex.chip);
|
||||
await page.autocompleteSearch(selectors.travelIndex.continentFilter, 'Asia');
|
||||
|
||||
expect(httpRequest).toContain('continent');
|
||||
|
||||
await page.click(selectors.travelIndex.chip);
|
||||
await page.write(selectors.travelIndex.totalEntriesFilter, '1');
|
||||
await page.keyboard.press('Enter');
|
||||
|
||||
expect(httpRequest).toContain('totalEntries=1');
|
||||
});
|
||||
});
|
|
@ -66,10 +66,16 @@ export default class App {
|
|||
]}
|
||||
};
|
||||
|
||||
const hasId = !isNaN(parseInt(route.split('/')[1]));
|
||||
|
||||
if (this.logger.$params.q)
|
||||
newRoute = newRoute.concat(`?table=${this.logger.$params.q}`);
|
||||
|
||||
if (this.logger.$params.q) {
|
||||
let tableValue = this.logger.$params.q;
|
||||
const q = JSON.parse(tableValue);
|
||||
if (typeof q === 'number')
|
||||
tableValue = JSON.stringify({id: tableValue});
|
||||
newRoute = newRoute.concat(`?table=${tableValue}`);
|
||||
} else if (!hasId && this.logger.$params.id && newRoute.indexOf(this.logger.$params.id) < 0)
|
||||
newRoute = newRoute.concat(`${this.logger.$params.id}`);
|
||||
|
||||
return this.logger.$http.get('Urls/findOne', {filter})
|
||||
.then(res => {
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
<th field="clientFk">
|
||||
<span translate>Client</span>
|
||||
</th>
|
||||
<th>
|
||||
<th field="isWorker">
|
||||
<span translate>Es trabajador</span>
|
||||
</th>
|
||||
<th field="salesPersonFk">
|
||||
|
|
|
@ -57,6 +57,11 @@ export default class Controller extends Section {
|
|||
field: 'observation',
|
||||
searchable: false
|
||||
},
|
||||
{
|
||||
field: 'isWorker',
|
||||
checkbox: true,
|
||||
|
||||
},
|
||||
{
|
||||
field: 'created',
|
||||
datepicker: true
|
||||
|
@ -73,9 +78,6 @@ export default class Controller extends Section {
|
|||
|
||||
set defaulters(value) {
|
||||
if (!value || !value.length) return;
|
||||
for (let defaulter of value)
|
||||
defaulter.isWorker = defaulter.businessTypeFk === 'worker';
|
||||
|
||||
this._defaulters = value;
|
||||
}
|
||||
|
||||
|
@ -164,6 +166,8 @@ export default class Controller extends Section {
|
|||
|
||||
exprBuilder(param, value) {
|
||||
switch (param) {
|
||||
case 'isWorker':
|
||||
return {isWorker: value};
|
||||
case 'creditInsurance':
|
||||
case 'amount':
|
||||
case 'clientFk':
|
||||
|
|
|
@ -39,7 +39,7 @@ describe('Entry filter()', () => {
|
|||
|
||||
const result = await models.Entry.filter(ctx, options);
|
||||
|
||||
expect(result.length).toEqual(11);
|
||||
expect(result.length).toEqual(12);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
|
@ -152,7 +152,7 @@ describe('Entry filter()', () => {
|
|||
|
||||
const result = await models.Entry.filter(ctx, options);
|
||||
|
||||
expect(result.length).toEqual(10);
|
||||
expect(result.length).toEqual(11);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
|
|
|
@ -45,8 +45,8 @@ module.exports = Self => {
|
|||
i.id itemFk,
|
||||
i.name itemName,
|
||||
ti.quantity,
|
||||
(ac.conversionCoefficient * (ti.quantity / b.packing) * buy_getVolume(b.id))
|
||||
/ (vc.trolleyM3 * 1000000) volume,
|
||||
ROUND((ac.conversionCoefficient * (ti.quantity / b.packing) * buy_getVolume(b.id))
|
||||
/ (vc.trolleyM3 * 1000000),1) volume,
|
||||
b.packagingFk packagingFk,
|
||||
b.packing
|
||||
FROM tmp.item ti
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
<slot-descriptor>
|
||||
<vn-entry-descriptor></vn-entry-descriptor>
|
||||
</slot-descriptor>
|
|
@ -3,7 +3,7 @@ import DescriptorPopover from 'salix/components/descriptor-popover';
|
|||
|
||||
class Controller extends DescriptorPopover {}
|
||||
|
||||
ngModule.vnComponent('vnTravelDescriptorPopover', {
|
||||
ngModule.vnComponent('vnEntryDescriptorPopover', {
|
||||
slotTemplate: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -0,0 +1,65 @@
|
|||
<vn-descriptor-content
|
||||
module="entry"
|
||||
description="$ctrl.entry.supplier.nickname"
|
||||
summary="$ctrl.$.summary">
|
||||
<slot-menu>
|
||||
<vn-item
|
||||
ng-click="$ctrl.showEntryReport()"
|
||||
translate>
|
||||
Show entry report
|
||||
</vn-item>
|
||||
</slot-menu>
|
||||
<slot-body>
|
||||
<div class="attributes">
|
||||
<vn-label-value label="Agency "
|
||||
value="{{$ctrl.entry.travel.agency.name}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Landed"
|
||||
value="{{$ctrl.entry.travel.landed | date: 'dd/MM/yyyy'}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Warehouse Out"
|
||||
value="{{$ctrl.entry.travel.warehouseOut.name}}">
|
||||
</vn-label-value>
|
||||
</div>
|
||||
<div class="icons">
|
||||
<vn-icon
|
||||
vn-tooltip="Is inventory entry"
|
||||
icon="icon-inventory"
|
||||
ng-if="$ctrl.entry.isExcludedFromAvailable">
|
||||
</vn-icon>
|
||||
<vn-icon
|
||||
vn-tooltip="Is virtual entry"
|
||||
icon="icon-net"
|
||||
ng-if="$ctrl.entry.isRaid">
|
||||
</vn-icon>
|
||||
</div>
|
||||
<div class="quicklinks">
|
||||
<div ng-transclude="btnOne">
|
||||
<vn-quick-link
|
||||
tooltip="Supplier card"
|
||||
state="['supplier.index', {q: $ctrl.entry.supplier.id }]"
|
||||
icon="icon-supplier">
|
||||
</vn-quick-link>
|
||||
</div>
|
||||
<div ng-transclude="btnTwo">
|
||||
<vn-quick-link
|
||||
tooltip="All travels with current agency"
|
||||
state="['travel.index', {q: $ctrl.travelFilter}]"
|
||||
icon="local_airport">
|
||||
</vn-quick-link>
|
||||
</div>
|
||||
<div ng-transclude="btnThree">
|
||||
<vn-quick-link
|
||||
tooltip="All entries with current supplier"
|
||||
state="['entry.index', {q: $ctrl.entryFilter}]"
|
||||
icon="icon-entry">
|
||||
</vn-quick-link>
|
||||
</div>
|
||||
<div ng-transclude="btnThree">
|
||||
</div>
|
||||
</div>
|
||||
</slot-body>
|
||||
</vn-descriptor-content>
|
||||
<vn-popup vn-id="summary">
|
||||
<vn-entry-summary entry="$ctrl.entry"></vn-entry-summary>
|
||||
</vn-popup>
|
|
@ -0,0 +1,99 @@
|
|||
import ngModule from '../module';
|
||||
import Descriptor from 'salix/components/descriptor';
|
||||
|
||||
class Controller extends Descriptor {
|
||||
get entry() {
|
||||
return this.entity;
|
||||
}
|
||||
|
||||
set entry(value) {
|
||||
this.entity = value;
|
||||
}
|
||||
|
||||
get travelFilter() {
|
||||
let travelFilter;
|
||||
const entryTravel = this.entry && this.entry.travel;
|
||||
|
||||
if (entryTravel && entryTravel.agencyModeFk) {
|
||||
travelFilter = this.entry && JSON.stringify({
|
||||
agencyModeFk: entryTravel.agencyModeFk
|
||||
});
|
||||
}
|
||||
return travelFilter;
|
||||
}
|
||||
|
||||
get entryFilter() {
|
||||
let entryTravel = this.entry && this.entry.travel;
|
||||
|
||||
if (!entryTravel || !entryTravel.landed) return null;
|
||||
|
||||
const date = new Date(entryTravel.landed);
|
||||
date.setHours(0, 0, 0, 0);
|
||||
|
||||
const from = new Date(date.getTime());
|
||||
from.setDate(from.getDate() - 10);
|
||||
|
||||
const to = new Date(date.getTime());
|
||||
to.setDate(to.getDate() + 10);
|
||||
|
||||
return JSON.stringify({
|
||||
supplierFk: this.entry.supplierFk,
|
||||
from,
|
||||
to
|
||||
});
|
||||
}
|
||||
|
||||
loadData() {
|
||||
const filter = {
|
||||
include: [
|
||||
{
|
||||
relation: 'travel',
|
||||
scope: {
|
||||
fields: ['id', 'landed', 'agencyModeFk', 'warehouseOutFk'],
|
||||
include: [
|
||||
{
|
||||
relation: 'agency',
|
||||
scope: {
|
||||
fields: ['name']
|
||||
}
|
||||
},
|
||||
{
|
||||
relation: 'warehouseOut',
|
||||
scope: {
|
||||
fields: ['name']
|
||||
}
|
||||
},
|
||||
{
|
||||
relation: 'warehouseIn',
|
||||
scope: {
|
||||
fields: ['name']
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
relation: 'supplier',
|
||||
scope: {
|
||||
fields: ['id', 'nickname']
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
return this.getData(`Entries/${this.id}`, {filter})
|
||||
.then(res => this.entity = res.data);
|
||||
}
|
||||
|
||||
showEntryReport() {
|
||||
this.vnReport.show(`Entries/${this.id}/entry-order-pdf`);
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnEntryDescriptor', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
entry: '<'
|
||||
}
|
||||
});
|
|
@ -1,3 +1,6 @@
|
|||
export * from './module';
|
||||
|
||||
import './main';
|
||||
import './descriptor';
|
||||
import './descriptor-popover';
|
||||
import './summary';
|
||||
|
|
|
@ -8,6 +8,12 @@
|
|||
"main": [
|
||||
{"state": "entry.index", "icon": "icon-entry"},
|
||||
{"state": "entry.latestBuys", "icon": "contact_support"}
|
||||
],
|
||||
"card": [
|
||||
{"state": "entry.card.basicData", "icon": "settings"},
|
||||
{"state": "entry.card.buy.index", "icon": "icon-lines"},
|
||||
{"state": "entry.card.observation", "icon": "insert_drive_file"},
|
||||
{"state": "entry.card.log", "icon": "history"}
|
||||
]
|
||||
},
|
||||
"keybindings": [
|
||||
|
@ -27,6 +33,90 @@
|
|||
"component": "vn-entry-index",
|
||||
"description": "Entries",
|
||||
"acl": ["buyer", "administrative"]
|
||||
},
|
||||
{
|
||||
"url": "/latest-buys?q",
|
||||
"state": "entry.latestBuys",
|
||||
"component": "vn-entry-latest-buys",
|
||||
"description": "Latest buys",
|
||||
"acl": ["buyer", "administrative"]
|
||||
},
|
||||
{
|
||||
"url": "/create?supplierFk&travelFk&companyFk",
|
||||
"state": "entry.create",
|
||||
"component": "vn-entry-create",
|
||||
"description": "New entry",
|
||||
"acl": ["buyer", "administrative"]
|
||||
},
|
||||
{
|
||||
"url": "/:id",
|
||||
"state": "entry.card",
|
||||
"abstract": true,
|
||||
"component": "vn-entry-card"
|
||||
},
|
||||
{
|
||||
"url": "/summary",
|
||||
"state": "entry.card.summary",
|
||||
"component": "vn-entry-summary",
|
||||
"description": "Summary",
|
||||
"params": {
|
||||
"entry": "$ctrl.entry"
|
||||
},
|
||||
"acl": ["buyer", "administrative"]
|
||||
},
|
||||
{
|
||||
"url": "/basic-data",
|
||||
"state": "entry.card.basicData",
|
||||
"component": "vn-entry-basic-data",
|
||||
"description": "Basic data",
|
||||
"params": {
|
||||
"entry": "$ctrl.entry"
|
||||
},
|
||||
"acl": ["buyer", "administrative"]
|
||||
},
|
||||
{
|
||||
"url": "/observation",
|
||||
"state": "entry.card.observation",
|
||||
"component": "vn-entry-observation",
|
||||
"description": "Notes",
|
||||
"params": {
|
||||
"entry": "$ctrl.entry"
|
||||
},
|
||||
"acl": ["buyer", "administrative"]
|
||||
},
|
||||
{
|
||||
"url" : "/log",
|
||||
"state": "entry.card.log",
|
||||
"component": "vn-entry-log",
|
||||
"description": "Log",
|
||||
"acl": ["buyer", "administrative"]
|
||||
},
|
||||
{
|
||||
"url": "/buy",
|
||||
"state": "entry.card.buy",
|
||||
"abstract": true,
|
||||
"component": "ui-view",
|
||||
"acl": ["buyer"]
|
||||
},
|
||||
{
|
||||
"url" : "/index",
|
||||
"state": "entry.card.buy.index",
|
||||
"component": "vn-entry-buy-index",
|
||||
"description": "Buys",
|
||||
"params": {
|
||||
"entry": "$ctrl.entry"
|
||||
},
|
||||
"acl": ["buyer", "administrative"]
|
||||
},
|
||||
{
|
||||
"url" : "/import",
|
||||
"state": "entry.card.buy.import",
|
||||
"component": "vn-entry-buy-import",
|
||||
"description": "Import buys",
|
||||
"params": {
|
||||
"entry": "$ctrl.entry"
|
||||
},
|
||||
"acl": ["buyer"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,195 @@
|
|||
<vn-crud-model
|
||||
vn-id="buysModel"
|
||||
url="Entries/{{$ctrl.entry.id}}/getBuys"
|
||||
limit="5"
|
||||
data="buys"
|
||||
auto-load="true">
|
||||
</vn-crud-model>
|
||||
<vn-card class="summary">
|
||||
<h5>
|
||||
<a ng-if="::$ctrl.entryData.id"
|
||||
vn-tooltip="Go to the entry"
|
||||
ui-sref="entry.card.summary({id: {{::$ctrl.entryData.id}}})"
|
||||
name="goToSummary">
|
||||
<vn-icon-button icon="launch"></vn-icon-button>
|
||||
</a>
|
||||
<span> #{{$ctrl.entryData.id}} - {{$ctrl.entryData.supplier.nickname}}</span>
|
||||
</h5>
|
||||
<vn-horizontal>
|
||||
<vn-one>
|
||||
<vn-label-value label="Commission"
|
||||
value="{{$ctrl.entryData.commission}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Currency"
|
||||
value="{{$ctrl.entryData.currency.name}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Company"
|
||||
value="{{$ctrl.entryData.company.code}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Reference"
|
||||
value="{{$ctrl.entryData.reference}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Invoice number"
|
||||
value="{{$ctrl.entryData.invoiceNumber}}">
|
||||
</vn-label-value>
|
||||
</vn-one>
|
||||
<vn-one>
|
||||
<vn-label-value label="Reference">
|
||||
<span
|
||||
ng-click="travelDescriptor.show($event, $ctrl.entryData.travel.id)"
|
||||
class="link">
|
||||
{{$ctrl.entryData.travel.ref}}
|
||||
</span>
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Agency"
|
||||
value="{{$ctrl.entryData.travel.agency.name}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Shipped"
|
||||
value="{{$ctrl.entryData.travel.shipped | date: 'dd/MM/yyyy'}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Warehouse Out"
|
||||
value="{{$ctrl.entryData.travel.warehouseOut.name}}">
|
||||
</vn-label-value>
|
||||
<vn-check
|
||||
label="Delivered"
|
||||
ng-model="$ctrl.entryData.travel.isDelivered"
|
||||
disabled="true">
|
||||
</vn-check>
|
||||
<vn-label-value label="Landed"
|
||||
value="{{$ctrl.entryData.travel.landed | date: 'dd/MM/yyyy'}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Warehouse In"
|
||||
value="{{$ctrl.entryData.travel.warehouseIn.name}}">
|
||||
</vn-label-value>
|
||||
<vn-check
|
||||
label="Received"
|
||||
ng-model="$ctrl.entryData.travel.isReceived"
|
||||
disabled="true">
|
||||
</vn-check>
|
||||
</vn-one>
|
||||
<vn-one>
|
||||
<vn-vertical>
|
||||
<vn-check
|
||||
label="Ordered"
|
||||
ng-model="$ctrl.entryData.isOrdered"
|
||||
disabled="true">
|
||||
</vn-check>
|
||||
<vn-check
|
||||
label="Confirmed"
|
||||
ng-model="$ctrl.entryData.isConfirmed"
|
||||
disabled="true">
|
||||
</vn-check>
|
||||
<vn-check
|
||||
label="Booked"
|
||||
ng-model="$ctrl.entryData.isBooked"
|
||||
disabled="true">
|
||||
</vn-check>
|
||||
<vn-check
|
||||
label="Raid"
|
||||
ng-model="$ctrl.entryData.isRaid"
|
||||
disabled="true">
|
||||
</vn-check>
|
||||
<vn-check
|
||||
label="Inventory"
|
||||
ng-model="$ctrl.entryData.isExcludedFromAvailable"
|
||||
disabled="true">
|
||||
</vn-check>
|
||||
</vn-vertical>
|
||||
</vn-one>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-auto name="buys">
|
||||
<h4 translate>Buys</h4>
|
||||
<table class="vn-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th translate center field="quantity">Quantity</th>
|
||||
<th translate center field="sticker">Stickers</th>
|
||||
<th translate center field="packagingFk">Package</th>
|
||||
<th translate center field="weight">Weight</th>
|
||||
<th translate center field="packing">Packing</th>
|
||||
<th translate center field="grouping">Grouping</th>
|
||||
<th translate center field="buyingValue">Buying value</th>
|
||||
<th translate center field="price3">Import</th>
|
||||
<th translate center expand field="price">PVP</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody ng-repeat="line in buys">
|
||||
<tr>
|
||||
<td center title="{{::line.quantity}}">{{::line.quantity}}</td>
|
||||
<td center title="{{::line.stickers | dashIfEmpty}}">{{::line.stickers | dashIfEmpty}}</td>
|
||||
<td center title="{{::line.packagingFk | dashIfEmpty}}">{{::line.packagingFk | dashIfEmpty}}</td>
|
||||
<td center title="{{::line.weight}}">{{::line.weight}}</td>
|
||||
<td center>
|
||||
<vn-chip class="transparent" translate-attr="line.groupingMode == 'packing' ? {title: 'Minimun amount'} : {title: 'Packing'}" ng-class="{'message': line.groupingMode == 'packing'}">
|
||||
<span>{{::line.packing | dashIfEmpty}}</span>
|
||||
</vn-chip>
|
||||
</td>
|
||||
<td center>
|
||||
<vn-chip class="transparent" translate-attr="line.groupingMode == 'grouping' ? {title: 'Minimun amount'} : {title: 'Grouping'}" ng-class="{'message': line.groupingMode == 'grouping'}">
|
||||
<span>{{::line.grouping | dashIfEmpty}}</span>
|
||||
</vn-chip>
|
||||
</vn-td>
|
||||
<td center title="{{::line.buyingValue | currency: 'EUR':2}}">{{::line.buyingValue | currency: 'EUR':2}}</td>
|
||||
<td center title="{{::line.quantity * line.buyingValue | currency: 'EUR':2}}">{{::line.quantity * line.buyingValue | currency: 'EUR':2}}</td>
|
||||
<td center title="Grouping / Packing">{{::line.price2 | currency: 'EUR':2 | dashIfEmpty}} / {{::line.price3 | currency: 'EUR':2 | dashIfEmpty}}</td>
|
||||
</tr>
|
||||
<tr class="dark-row">
|
||||
<td shrink>
|
||||
<span
|
||||
translate-attr="{title: 'Item type'}">
|
||||
{{::line.item.itemType.code}}
|
||||
</span>
|
||||
</td>
|
||||
<td shrink>
|
||||
<span
|
||||
ng-click="itemDescriptor.show($event, line.item.id)"
|
||||
class="link">
|
||||
{{::line.item.id}}
|
||||
</span>
|
||||
</td>
|
||||
<td number shrink>
|
||||
<span
|
||||
translate-attr="{title: 'Item size'}">
|
||||
{{::line.item.size}}
|
||||
</span>
|
||||
</td>
|
||||
<td center>
|
||||
<span
|
||||
translate-attr="{title: 'Minimum price'}">
|
||||
{{::line.item.minPrice | currency: 'EUR':2}}
|
||||
</span>
|
||||
</td>
|
||||
<td vn-fetched-tags colspan="6">
|
||||
<div>
|
||||
<vn-one title="{{::line.item.concept}}">{{::line.item.name}}</vn-one>
|
||||
<vn-one ng-if="::line.item.subName">
|
||||
<h3 title="{{::line.item.subName}}">{{::line.item.subName}}</h3>
|
||||
</vn-one>
|
||||
</div>
|
||||
<vn-fetched-tags
|
||||
max-length="6"
|
||||
item="::line.item"
|
||||
tabindex="-1">
|
||||
</vn-fetched-tags>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="empty-row">
|
||||
<td colspan="10"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<vn-pagination
|
||||
model="buysModel"
|
||||
class="vn-pt-xs">
|
||||
</vn-pagination>
|
||||
</vn-auto>
|
||||
</vn-horizontal>
|
||||
</vn-card>
|
||||
<vn-item-descriptor-popover
|
||||
vn-id="item-descriptor"
|
||||
warehouse-fk="$ctrl.vnConfig.warehouseFk">
|
||||
</vn-item-descriptor-popover>
|
||||
<vn-travel-descriptor-popover
|
||||
vn-id="travelDescriptor">
|
||||
</vn-travel-descriptor-popover>
|
|
@ -0,0 +1,33 @@
|
|||
import ngModule from '../module';
|
||||
import './style.scss';
|
||||
import Summary from 'salix/components/summary';
|
||||
|
||||
class Controller extends Summary {
|
||||
get entry() {
|
||||
if (!this._entry)
|
||||
return this.$params;
|
||||
|
||||
return this._entry;
|
||||
}
|
||||
|
||||
set entry(value) {
|
||||
this._entry = value;
|
||||
|
||||
if (value && value.id)
|
||||
this.getEntryData();
|
||||
}
|
||||
|
||||
getEntryData() {
|
||||
return this.$http.get(`Entries/${this.entry.id}/getEntry`).then(response => {
|
||||
this.entryData = response.data;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnEntrySummary', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
entry: '<'
|
||||
}
|
||||
});
|
|
@ -0,0 +1,30 @@
|
|||
@import "variables";
|
||||
|
||||
|
||||
vn-entry-summary .summary {
|
||||
max-width: $width-lg;
|
||||
|
||||
.dark-row {
|
||||
background-color: lighten($color-marginal, 10%);
|
||||
}
|
||||
|
||||
tbody tr:nth-child(1) {
|
||||
border-top: $border-thin;
|
||||
}
|
||||
|
||||
tbody tr:nth-child(1),
|
||||
tbody tr:nth-child(2) {
|
||||
border-left: $border-thin;
|
||||
border-right: $border-thin
|
||||
}
|
||||
|
||||
tbody tr:nth-child(3) {
|
||||
height: inherit
|
||||
}
|
||||
|
||||
tr {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
$color-font-link-medium: lighten($color-font-link, 20%)
|
|
@ -10,6 +10,11 @@ module.exports = Self => {
|
|||
type: 'any',
|
||||
description: 'The invoiceable client id'
|
||||
},
|
||||
{
|
||||
arg: 'addressFk',
|
||||
type: 'any',
|
||||
description: 'The address id'
|
||||
},
|
||||
{
|
||||
arg: 'ticketFk',
|
||||
type: 'any',
|
||||
|
@ -23,7 +28,8 @@ module.exports = Self => {
|
|||
{
|
||||
arg: 'serial',
|
||||
type: 'string',
|
||||
description: 'The invoice serial'
|
||||
description: 'The invoice serial',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
arg: 'taxArea',
|
||||
|
@ -46,108 +52,126 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.createManualInvoice = async(ctx, clientFk, ticketFk, maxShipped, serial, taxArea, reference, options) => {
|
||||
if (!clientFk && !ticketFk) throw new UserError(`Select ticket or client`);
|
||||
const models = Self.app.models;
|
||||
const myOptions = {userId: ctx.req.accessToken.userId};
|
||||
let tx;
|
||||
Self.createManualInvoice =
|
||||
async(ctx, clientFk, addressFk, ticketFk, maxShipped, serial, taxArea, reference, options) => {
|
||||
if (!clientFk && !ticketFk) throw new UserError(`Select ticket or client`);
|
||||
const models = Self.app.models;
|
||||
const myOptions = {userId: ctx.req.accessToken.userId};
|
||||
let tx;
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
if (!myOptions.transaction) {
|
||||
tx = await Self.beginTransaction({});
|
||||
myOptions.transaction = tx;
|
||||
}
|
||||
if (!myOptions.transaction) {
|
||||
tx = await Self.beginTransaction({});
|
||||
myOptions.transaction = tx;
|
||||
}
|
||||
|
||||
let companyId;
|
||||
let newInvoice;
|
||||
let query;
|
||||
try {
|
||||
if (ticketFk) {
|
||||
const ticket = await models.Ticket.findById(ticketFk, null, myOptions);
|
||||
const company = await models.Company.findById(ticket.companyFk, null, myOptions);
|
||||
let companyFk;
|
||||
let newInvoice;
|
||||
let query;
|
||||
try {
|
||||
if (ticketFk) {
|
||||
const ticket = await models.Ticket.findById(ticketFk, {
|
||||
fields: ['clientFk', 'companyFk', 'shipped', 'refFk', 'totalWithVat']
|
||||
}, myOptions);
|
||||
const company = await models.Company.findById(ticket.companyFk, {
|
||||
fields: ['code']
|
||||
}, myOptions);
|
||||
|
||||
clientFk = ticket.clientFk;
|
||||
maxShipped = ticket.shipped;
|
||||
companyId = ticket.companyFk;
|
||||
clientFk = ticket.clientFk;
|
||||
maxShipped = ticket.shipped;
|
||||
companyFk = ticket.companyFk;
|
||||
|
||||
// Validates invoiced ticket
|
||||
if (ticket.refFk)
|
||||
throw new UserError('This ticket is already invoiced');
|
||||
if (ticket.refFk)
|
||||
throw new UserError('This ticket is already invoiced');
|
||||
|
||||
// Validates ticket amount
|
||||
if (ticket.totalWithVat == 0)
|
||||
throw new UserError(`A ticket with an amount of zero can't be invoiced`);
|
||||
if (ticket.totalWithVat == 0)
|
||||
throw new UserError(`A ticket with an amount of zero can't be invoiced`);
|
||||
|
||||
// Validates ticket nagative base
|
||||
const hasNegativeBase = await getNegativeBase(maxShipped, clientFk, companyId, myOptions);
|
||||
if (hasNegativeBase && company.code == 'VNL')
|
||||
throw new UserError(`A ticket with a negative base can't be invoiced`);
|
||||
} else {
|
||||
if (!maxShipped)
|
||||
throw new UserError(`Max shipped required`);
|
||||
const hasNegativeBase = await getNegativeBase(maxShipped, clientFk, companyFk, myOptions);
|
||||
if (hasNegativeBase && company.code == 'VNL')
|
||||
throw new UserError(`A ticket with a negative base can't be invoiced`);
|
||||
} else {
|
||||
if (!maxShipped)
|
||||
throw new UserError(`Max shipped required`);
|
||||
|
||||
const company = await models.Ticket.findOne({
|
||||
fields: ['companyFk'],
|
||||
where: {
|
||||
clientFk: clientFk,
|
||||
shipped: {lte: maxShipped}
|
||||
if (addressFk) {
|
||||
const address = await models.Address.findById(addressFk, {
|
||||
fields: ['clientFk']
|
||||
}, myOptions);
|
||||
|
||||
if (clientFk && clientFk !== address.clientFk)
|
||||
throw new UserError('The provided clientFk does not match');
|
||||
}
|
||||
}, myOptions);
|
||||
companyId = company.companyFk;
|
||||
const company = await models.Ticket.findOne({
|
||||
fields: ['companyFk'],
|
||||
where: {
|
||||
clientFk: clientFk,
|
||||
shipped: {lte: maxShipped}
|
||||
}
|
||||
}, myOptions);
|
||||
companyFk = company.companyFk;
|
||||
}
|
||||
|
||||
const isClientInvoiceable = await isInvoiceable(clientFk, myOptions);
|
||||
if (!isClientInvoiceable)
|
||||
throw new UserError(`This client is not invoiceable`);
|
||||
|
||||
const tomorrow = Date.vnNew();
|
||||
tomorrow.setDate(tomorrow.getDate() + 1);
|
||||
|
||||
if (maxShipped >= tomorrow)
|
||||
throw new UserError(`Can't invoice to future`);
|
||||
|
||||
const maxInvoiceDate = await getMaxIssued(serial, companyFk, myOptions);
|
||||
if (Date.vnNew() < maxInvoiceDate)
|
||||
throw new UserError(`Can't invoice to past`);
|
||||
|
||||
if (ticketFk) {
|
||||
query = `CALL invoiceOut_newFromTicket(?, ?, ?, ?, @newInvoiceId)`;
|
||||
await Self.rawSql(query, [
|
||||
ticketFk,
|
||||
serial,
|
||||
taxArea,
|
||||
reference
|
||||
], myOptions);
|
||||
} else if (addressFk) {
|
||||
query = `CALL invoiceOut_newFromAddress(?, ?, ?, ?, ?, ?, @newInvoiceId)`;
|
||||
await Self.rawSql(query, [
|
||||
addressFk,
|
||||
serial,
|
||||
maxShipped,
|
||||
companyFk,
|
||||
taxArea,
|
||||
reference
|
||||
], myOptions);
|
||||
} else {
|
||||
query = `CALL invoiceOut_newFromClient(?, ?, ?, ?, ?, ?, @newInvoiceId)`;
|
||||
await Self.rawSql(query, [
|
||||
clientFk,
|
||||
serial,
|
||||
maxShipped,
|
||||
companyFk,
|
||||
taxArea,
|
||||
reference
|
||||
], myOptions);
|
||||
}
|
||||
|
||||
[newInvoice] = await Self.rawSql(`SELECT @newInvoiceId id`, null, myOptions);
|
||||
|
||||
if (tx) await tx.commit();
|
||||
} catch (e) {
|
||||
if (tx) await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
|
||||
// Validate invoiceable client
|
||||
const isClientInvoiceable = await isInvoiceable(clientFk, myOptions);
|
||||
if (!isClientInvoiceable)
|
||||
throw new UserError(`This client is not invoiceable`);
|
||||
if (!newInvoice.id) throw new UserError('It was not able to create the invoice');
|
||||
|
||||
// Can't invoice tickets into future
|
||||
const tomorrow = Date.vnNew();
|
||||
tomorrow.setDate(tomorrow.getDate() + 1);
|
||||
await Self.createPdf(ctx, newInvoice.id);
|
||||
|
||||
if (maxShipped >= tomorrow)
|
||||
throw new UserError(`Can't invoice to future`);
|
||||
|
||||
const maxInvoiceDate = await getMaxIssued(serial, companyId, myOptions);
|
||||
if (Date.vnNew() < maxInvoiceDate)
|
||||
throw new UserError(`Can't invoice to past`);
|
||||
|
||||
if (ticketFk) {
|
||||
query = `CALL invoiceOut_newFromTicket(?, ?, ?, ?, @newInvoiceId)`;
|
||||
await Self.rawSql(query, [
|
||||
ticketFk,
|
||||
serial,
|
||||
taxArea,
|
||||
reference
|
||||
], myOptions);
|
||||
} else {
|
||||
query = `CALL invoiceOut_newFromClient(?, ?, ?, ?, ?, ?, @newInvoiceId)`;
|
||||
await Self.rawSql(query, [
|
||||
clientFk,
|
||||
serial,
|
||||
maxShipped,
|
||||
companyId,
|
||||
taxArea,
|
||||
reference
|
||||
], myOptions);
|
||||
}
|
||||
|
||||
[newInvoice] = await Self.rawSql(`SELECT @newInvoiceId id`, null, myOptions);
|
||||
|
||||
if (tx) await tx.commit();
|
||||
} catch (e) {
|
||||
if (tx) await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
|
||||
if (!newInvoice.id) throw new UserError('It was not able to create the invoice');
|
||||
|
||||
await Self.createPdf(ctx, newInvoice.id);
|
||||
|
||||
return newInvoice;
|
||||
};
|
||||
return newInvoice;
|
||||
};
|
||||
|
||||
async function isInvoiceable(clientFk, options) {
|
||||
const models = Self.app.models;
|
||||
|
@ -159,10 +183,10 @@ module.exports = Self => {
|
|||
return result.invoiceable;
|
||||
}
|
||||
|
||||
async function getNegativeBase(maxShipped, clientFk, companyId, options) {
|
||||
async function getNegativeBase(maxShipped, clientFk, companyFk, options) {
|
||||
const models = Self.app.models;
|
||||
await models.InvoiceOut.rawSql('CALL invoiceOut_exportationFromClient(?,?,?)',
|
||||
[maxShipped, clientFk, companyId], options
|
||||
[maxShipped, clientFk, companyFk], options
|
||||
);
|
||||
const query = 'SELECT vn.hasAnyNegativeBase() AS base';
|
||||
const [result] = await models.InvoiceOut.rawSql(query, [], options);
|
||||
|
@ -170,14 +194,14 @@ module.exports = Self => {
|
|||
return result.base;
|
||||
}
|
||||
|
||||
async function getMaxIssued(serial, companyId, options) {
|
||||
async function getMaxIssued(serial, companyFk, options) {
|
||||
const models = Self.app.models;
|
||||
const query = `SELECT MAX(issued) AS issued
|
||||
FROM invoiceOut
|
||||
WHERE serial = ? AND companyFk = ?`;
|
||||
const [maxIssued] = await models.InvoiceOut.rawSql(query,
|
||||
[serial, companyId], options);
|
||||
const maxInvoiceDate = maxIssued && maxIssued.issued || Date.vnNew();
|
||||
[serial, companyFk], options);
|
||||
const maxInvoiceDate = maxIssued?.issued || Date.vnNew();
|
||||
|
||||
return maxInvoiceDate;
|
||||
}
|
||||
|
|
|
@ -6,110 +6,90 @@ describe('InvoiceOut createManualInvoice()', () => {
|
|||
const clientId = 1106;
|
||||
const activeCtx = {accessToken: {userId: 1}};
|
||||
const ctx = {req: activeCtx};
|
||||
let tx; let options;
|
||||
|
||||
beforeEach(async() => {
|
||||
spyOn(models.InvoiceOut, 'createPdf').and.returnValue(Promise.resolve(true));
|
||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||
active: activeCtx
|
||||
});
|
||||
|
||||
tx = await models.InvoiceOut.beginTransaction({});
|
||||
options = {transaction: tx};
|
||||
});
|
||||
|
||||
afterEach(async() => {
|
||||
await tx.rollback();
|
||||
});
|
||||
|
||||
it('should throw an error trying to invoice again', async() => {
|
||||
spyOn(models.InvoiceOut, 'createPdf').and.returnValue(new Promise(resolve => resolve(true)));
|
||||
|
||||
const tx = await models.InvoiceOut.beginTransaction({});
|
||||
const options = {transaction: tx};
|
||||
|
||||
let error;
|
||||
try {
|
||||
await createInvoice(ctx, options, undefined, ticketId);
|
||||
await createInvoice(ctx, options, undefined, ticketId);
|
||||
|
||||
await tx.rollback();
|
||||
await createInvoice(ctx, options, undefined, undefined, ticketId);
|
||||
await createInvoice(ctx, options, undefined, undefined, ticketId);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
await tx.rollback();
|
||||
}
|
||||
|
||||
expect(error.message).toContain('This ticket is already invoiced');
|
||||
});
|
||||
|
||||
it('should throw an error for a ticket with an amount of zero', async() => {
|
||||
spyOn(models.InvoiceOut, 'createPdf').and.returnValue(new Promise(resolve => resolve(true)));
|
||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||
active: activeCtx
|
||||
});
|
||||
|
||||
const tx = await models.InvoiceOut.beginTransaction({});
|
||||
const options = {transaction: tx};
|
||||
|
||||
let error;
|
||||
try {
|
||||
const ticket = await models.Ticket.findById(ticketId, null, options);
|
||||
await ticket.updateAttributes({totalWithVat: 0}, options);
|
||||
|
||||
await createInvoice(ctx, options, undefined, ticketId);
|
||||
await tx.rollback();
|
||||
await createInvoice(ctx, options, undefined, undefined, ticketId);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
await tx.rollback();
|
||||
}
|
||||
|
||||
expect(error.message).toContain(`A ticket with an amount of zero can't be invoiced`);
|
||||
});
|
||||
|
||||
it('should throw an error when the clientFk property is set without the max shipped date', async() => {
|
||||
spyOn(models.InvoiceOut, 'createPdf').and.returnValue(new Promise(resolve => resolve(true)));
|
||||
|
||||
const tx = await models.InvoiceOut.beginTransaction({});
|
||||
const options = {transaction: tx};
|
||||
|
||||
let error;
|
||||
try {
|
||||
await createInvoice(ctx, options, clientId);
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
error = e;
|
||||
await tx.rollback();
|
||||
}
|
||||
|
||||
expect(error.message).toContain(`Max shipped required`);
|
||||
});
|
||||
|
||||
it('should throw an error for a non-invoiceable client', async() => {
|
||||
spyOn(models.InvoiceOut, 'createPdf').and.returnValue(new Promise(resolve => resolve(true)));
|
||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||
active: activeCtx
|
||||
});
|
||||
|
||||
const tx = await models.InvoiceOut.beginTransaction({});
|
||||
const options = {transaction: tx};
|
||||
|
||||
let error;
|
||||
try {
|
||||
const client = await models.Client.findById(clientId, null, options);
|
||||
await client.updateAttributes({isTaxDataChecked: false}, options);
|
||||
|
||||
await createInvoice(ctx, options, undefined, ticketId);
|
||||
|
||||
await tx.rollback();
|
||||
await createInvoice(ctx, options, undefined, undefined, ticketId);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
await tx.rollback();
|
||||
}
|
||||
|
||||
expect(error.message).toContain(`This client is not invoiceable`);
|
||||
});
|
||||
|
||||
it('should create a manual invoice', async() => {
|
||||
spyOn(models.InvoiceOut, 'createPdf').and.returnValue(new Promise(resolve => resolve(true)));
|
||||
it('should create a manual invoice with ticket', async() => {
|
||||
const result = await createInvoice(ctx, options, undefined, undefined, ticketId);
|
||||
|
||||
const tx = await models.InvoiceOut.beginTransaction({});
|
||||
const options = {transaction: tx};
|
||||
expect(result.id).toEqual(jasmine.any(Number));
|
||||
});
|
||||
|
||||
try {
|
||||
const result = await createInvoice(ctx, options, undefined, ticketId);
|
||||
it('should create a manual invoice with client', async() => {
|
||||
const result = await createInvoice(ctx, options, clientId, undefined, undefined, Date.vnNew());
|
||||
|
||||
expect(result.id).toEqual(jasmine.any(Number));
|
||||
expect(result.id).toEqual(jasmine.any(Number));
|
||||
});
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
it('should create a manual invoice with address', async() => {
|
||||
const addressFk = 126;
|
||||
const result = await createInvoice(ctx, options, clientId, addressFk, undefined, Date.vnNew());
|
||||
|
||||
expect(result.id).toEqual(jasmine.any(Number));
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -117,6 +97,7 @@ function createInvoice(
|
|||
ctx,
|
||||
options,
|
||||
clientFk = undefined,
|
||||
addressFk = undefined,
|
||||
ticketFk = undefined,
|
||||
maxShipped = undefined,
|
||||
serial = 'T',
|
||||
|
@ -124,6 +105,6 @@ function createInvoice(
|
|||
reference = undefined
|
||||
) {
|
||||
return models.InvoiceOut.createManualInvoice(
|
||||
ctx, clientFk, ticketFk, maxShipped, serial, taxArea, reference, options
|
||||
ctx, clientFk, addressFk, ticketFk, maxShipped, serial, taxArea, reference, options
|
||||
);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"name": "Items",
|
||||
"icon": "icon-item",
|
||||
"validations" : true,
|
||||
"dependencies": ["worker", "client", "ticket"],
|
||||
"dependencies": ["worker", "client", "ticket", "entry"],
|
||||
"menus": {
|
||||
"main": [
|
||||
{"state": "item.index", "icon": "icon-item"},
|
||||
|
|
|
@ -1,8 +1,3 @@
|
|||
export * from './module';
|
||||
|
||||
import './main';
|
||||
import './index/';
|
||||
import './index/tickets';
|
||||
import './index/clients';
|
||||
import './index/orders';
|
||||
import './index/search-panel';
|
||||
|
|
|
@ -1,110 +0,0 @@
|
|||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="SalesMonitors/clientsFilter"
|
||||
limit="6"
|
||||
filter="$ctrl.filter"
|
||||
order="dated DESC, hour DESC"
|
||||
auto-load="true">
|
||||
</vn-crud-model>
|
||||
<vn-horizontal class="header">
|
||||
<vn-one translate>
|
||||
Clients on website
|
||||
</vn-one>
|
||||
<vn-none>
|
||||
<vn-icon class="arrow"
|
||||
icon="keyboard_arrow_up"
|
||||
vn-tooltip="Minimize/Maximize"
|
||||
ng-click="$ctrl.main.toggle()">
|
||||
</vn-icon>
|
||||
</vn-none>
|
||||
</vn-horizontal>
|
||||
<vn-card vn-id="card">
|
||||
<smart-table
|
||||
model="model"
|
||||
options="$ctrl.smartTableOptions"
|
||||
expr-builder="$ctrl.exprBuilder(param, value)"
|
||||
disabled-table-filter="true"
|
||||
disabled-table-order="true"
|
||||
class="scrollable sm">
|
||||
<slot-actions>
|
||||
<vn-horizontal>
|
||||
<vn-date-picker
|
||||
class="vn-pa-xs"
|
||||
label="From"
|
||||
ng-model="$ctrl.dateFrom"
|
||||
on-change="$ctrl.addFilterDate()">
|
||||
</vn-date-picker>
|
||||
<vn-date-picker
|
||||
class="vn-pa-xs"
|
||||
label="To"
|
||||
ng-model="$ctrl.dateTo"
|
||||
on-change="$ctrl.addFilterDate()">
|
||||
</vn-date-picker>
|
||||
</vn-horizontal>
|
||||
</slot-actions>
|
||||
<slot-table>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th field="dated">
|
||||
<span translate>Date</span>
|
||||
</th>
|
||||
<th field="hour">
|
||||
<span translate>Hour</span>
|
||||
</th>
|
||||
<th field="salesPersonFk" class="expendable">
|
||||
<span translate>Salesperson</span>
|
||||
</th>
|
||||
<th field="clientFk">
|
||||
<span translate>Client</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="visit in model.data track by visit.id">
|
||||
<td shrink-date>
|
||||
<span class="chip">
|
||||
{{::visit.dated | date:'dd/MM/yy'}}
|
||||
</span>
|
||||
</td>
|
||||
<td shrink-date>
|
||||
<span class="chip">
|
||||
{{::visit.hour | date: 'HH:mm'}}
|
||||
</span>
|
||||
</td>
|
||||
<td class="shrink expendable">
|
||||
<span
|
||||
title="{{::visit.salesPerson}}"
|
||||
vn-click-stop="workerDescriptor.show($event, visit.salesPersonFk)"
|
||||
class="link">
|
||||
{{::visit.salesPerson | dashIfEmpty}}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<span
|
||||
title="{{::visit.clientName}}"
|
||||
vn-click-stop="clientDescriptor.show($event, visit.clientFk)"
|
||||
class="link">
|
||||
{{::visit.clientName}}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</slot-table>
|
||||
<slot-pagination>
|
||||
<vn-pagination
|
||||
model="model"
|
||||
class="vn-pt-xs"
|
||||
scroll-selector="vn-monitor-sales-clients smart-table"
|
||||
scroll-offset="100">
|
||||
</vn-pagination>
|
||||
</slot-pagination>
|
||||
</smart-table>
|
||||
</vn-card>
|
||||
<vn-worker-descriptor-popover
|
||||
vn-id="workerDescriptor">
|
||||
</vn-worker-descriptor-popover>
|
||||
<vn-client-descriptor-popover
|
||||
vn-id="clientDescriptor">
|
||||
</vn-client-descriptor-popover>
|
|
@ -1,96 +0,0 @@
|
|||
import ngModule from '../../module';
|
||||
import Section from 'salix/components/section';
|
||||
|
||||
export default class Controller extends Section {
|
||||
constructor($element, $) {
|
||||
super($element, $);
|
||||
|
||||
const date = Date.vnNew();
|
||||
this.dateFrom = date;
|
||||
this.dateTo = date;
|
||||
this.filter = {
|
||||
where: {
|
||||
'v.stamp': {
|
||||
between: this.dateRange()
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.smartTableOptions = {
|
||||
activeButtons: {
|
||||
search: true
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
field: 'clientFk',
|
||||
autocomplete: {
|
||||
url: 'Clients',
|
||||
showField: 'name',
|
||||
valueField: 'id'
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'salesPersonFk',
|
||||
autocomplete: {
|
||||
url: 'Workers/activeWithInheritedRole',
|
||||
where: `{role: 'salesPerson'}`,
|
||||
searchFunction: '{firstName: $search}',
|
||||
showField: 'nickname',
|
||||
valueField: 'id',
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'dated',
|
||||
searchable: false
|
||||
},
|
||||
{
|
||||
field: 'hour',
|
||||
searchable: false
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
exprBuilder(param, value) {
|
||||
switch (param) {
|
||||
case 'clientFk':
|
||||
return {[`c.id`]: value};
|
||||
case 'salesPersonFk':
|
||||
return {[`c.${param}`]: value};
|
||||
}
|
||||
}
|
||||
|
||||
dateRange() {
|
||||
let from = this.dateFrom;
|
||||
let to = this.dateTo;
|
||||
if (!from)
|
||||
from = Date.vnNew();
|
||||
if (!to)
|
||||
to = Date.vnNew();
|
||||
const minHour = new Date(from);
|
||||
minHour.setHours(0, 0, 0, 0);
|
||||
const maxHour = new Date(to);
|
||||
maxHour.setHours(23, 59, 59, 59);
|
||||
|
||||
return [minHour, maxHour];
|
||||
}
|
||||
|
||||
addFilterDate() {
|
||||
this.$.model.filter = {
|
||||
where: {
|
||||
'v.stamp': {
|
||||
between: this.dateRange()
|
||||
}
|
||||
}
|
||||
};
|
||||
this.$.model.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnMonitorSalesClients', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
require: {
|
||||
main: '^vnMonitorIndex'
|
||||
}
|
||||
});
|
|
@ -1,5 +0,0 @@
|
|||
<vn-horizontal ng-class="{'hidden': $ctrl.isTopPanelHidden}">
|
||||
<vn-monitor-sales-clients class="vn-mb-sm"></vn-monitor-sales-clients>
|
||||
<vn-monitor-sales-orders></vn-monitor-sales-orders>
|
||||
</vn-horizontal>
|
||||
<vn-monitor-sales-tickets></vn-monitor-sales-tickets>
|
|
@ -1,34 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import Section from 'salix/components/section';
|
||||
import './style.scss';
|
||||
|
||||
export default class Controller extends Section {
|
||||
constructor($element, $) {
|
||||
super($element, $);
|
||||
|
||||
const isTopPanelHidden = localStorage.getItem('ticketTopPanelHidden');
|
||||
if (isTopPanelHidden === 'true')
|
||||
this.isTopPanelHidden = true;
|
||||
}
|
||||
|
||||
toggle() {
|
||||
const monitor = this.element.querySelector('vn-horizontal');
|
||||
const isHidden = monitor.classList.contains('hidden');
|
||||
|
||||
if (!isHidden) {
|
||||
monitor.classList.add('hidden');
|
||||
localStorage.setItem('ticketTopPanelHidden', true);
|
||||
} else {
|
||||
monitor.classList.remove('hidden');
|
||||
localStorage.setItem('ticketTopPanelHidden', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnMonitorIndex', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
require: {
|
||||
main: '^vnMonitorIndex'
|
||||
}
|
||||
});
|
|
@ -1,38 +0,0 @@
|
|||
import './index.js';
|
||||
describe('Component vnMonitorIndex', () => {
|
||||
let controller;
|
||||
let $element;
|
||||
|
||||
beforeEach(ngModule('monitor'));
|
||||
|
||||
beforeEach(inject(($compile, $rootScope) => {
|
||||
$element = $compile('<vn-monitor-index></vn-monitor-index>')($rootScope);
|
||||
controller = $element.controller('vnMonitorIndex');
|
||||
}));
|
||||
|
||||
describe('toggle()', () => {
|
||||
it('should add the hidden class to the horizontal contaning the panel to hide', () => {
|
||||
controller.toggle();
|
||||
|
||||
const targetElement = $element[0].querySelector('vn-horizontal');
|
||||
const firstClass = targetElement.classList[0];
|
||||
|
||||
const isTopPanelHidden = localStorage.getItem('ticketTopPanelHidden');
|
||||
|
||||
expect(firstClass).toEqual('hidden');
|
||||
expect(isTopPanelHidden).toEqual('true');
|
||||
});
|
||||
|
||||
it('should remove the hidden class to the horizontal contaning the panel to hide', () => {
|
||||
const targetElement = $element[0].querySelector('vn-horizontal');
|
||||
targetElement.classList.add('hidden');
|
||||
controller.toggle();
|
||||
const firstClass = targetElement.classList[0];
|
||||
|
||||
const isTopPanelHidden = localStorage.getItem('ticketTopPanelHidden');
|
||||
|
||||
expect(firstClass).toBeUndefined();
|
||||
expect(isTopPanelHidden).toEqual('false');
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,16 +0,0 @@
|
|||
Tickets monitor: Monitor de tickets
|
||||
Clients on website: Clientes activos en la web
|
||||
Recent order actions: Acciones recientes en pedidos
|
||||
Search tickets: Buscar tickets
|
||||
Delete selected elements: Eliminar los elementos seleccionados
|
||||
All the selected elements will be deleted. Are you sure you want to continue?: Todos los elementos seleccionados serán eliminados. ¿Seguro que quieres continuar?
|
||||
Component lack: Faltan componentes
|
||||
Ticket too little: Ticket demasiado pequeño
|
||||
Minimize/Maximize: Minimizar/Maximizar
|
||||
Problems: Problemas
|
||||
Theoretical: Teórica
|
||||
Practical: Práctica
|
||||
Preparation: Preparación
|
||||
Auto-refresh: Auto-refresco
|
||||
Toggle auto-refresh every 2 minutes: Conmuta el refresco automático cada 2 minutos
|
||||
Is fragile: Es frágil
|
|
@ -1,141 +0,0 @@
|
|||
<vn-crud-model auto-load="true"
|
||||
vn-id="model"
|
||||
url="SalesMonitors/ordersFilter"
|
||||
limit="6"
|
||||
order="date_make DESC">
|
||||
</vn-crud-model>
|
||||
<vn-horizontal class="header">
|
||||
<vn-one translate>
|
||||
Recent order actions
|
||||
</vn-one>
|
||||
<vn-none>
|
||||
<vn-icon
|
||||
icon="delete"
|
||||
vn-tooltip="Delete"
|
||||
ng-if="$ctrl.totalChecked > 0"
|
||||
ng-click="delete.show()">
|
||||
</vn-icon>
|
||||
<vn-icon class="arrow"
|
||||
icon="keyboard_arrow_up"
|
||||
vn-tooltip="Minimize/Maximize"
|
||||
ng-click="$ctrl.main.toggle()">
|
||||
</vn-icon>
|
||||
<vn-icon
|
||||
icon="refresh"
|
||||
vn-tooltip="Refresh"
|
||||
ng-click="model.refresh()">
|
||||
</vn-icon>
|
||||
</vn-none>
|
||||
</vn-horizontal>
|
||||
<vn-card>
|
||||
<vn-table model="model" class="scrollable">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th shrink>
|
||||
<vn-multi-check
|
||||
model="model">
|
||||
</vn-multi-check>
|
||||
</vn-th>
|
||||
<vn-th field="date_send" shrink-datetime>Date</vn-th>
|
||||
<vn-th field="clientFk">Client</vn-th>
|
||||
<vn-th field="salesPersonFk" shrink>SalesPerson</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<a ng-repeat="order in model.data track by order.id"
|
||||
class="clickable vn-tbody"
|
||||
ui-sref="order.card.summary({id: {{::order.id}}})" target="_blank">
|
||||
<vn-tr>
|
||||
<vn-td>
|
||||
<vn-check
|
||||
ng-model="order.checked"
|
||||
vn-click-stop>
|
||||
</vn-check>
|
||||
</vn-td>
|
||||
<vn-td>
|
||||
<span class="chip {{::$ctrl.chipColor(order.date_send)}}">
|
||||
{{::order.date_send | date: 'dd/MM/yyyy'}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td>
|
||||
<span
|
||||
title="{{::order.clientName}}"
|
||||
vn-click-stop="clientDescriptor.show($event, order.clientFk)"
|
||||
class="link">
|
||||
{{::order.clientName}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td>
|
||||
<span
|
||||
title="{{::order.salesPerson}}"
|
||||
vn-click-stop="workerDescriptor.show($event, order.salesPersonFk)"
|
||||
class="link">
|
||||
{{::order.salesPerson | dashIfEmpty}}
|
||||
</span>
|
||||
</vn-td>
|
||||
</vn-tr>
|
||||
<vn-tr>
|
||||
<vn-td></vn-td>
|
||||
<vn-td>
|
||||
<span>
|
||||
{{::order.date_make | date: 'dd/MM/yyyy HH:mm'}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td>
|
||||
<span title="{{::order.agencyName}}">
|
||||
{{::order.agencyName | dashIfEmpty}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td>
|
||||
{{::order.import | currency: 'EUR':2}}
|
||||
</vn-td>
|
||||
</vn-tr>
|
||||
</a>
|
||||
</vn-table>
|
||||
<vn-pagination
|
||||
model="model"
|
||||
class="vn-pt-xs"
|
||||
scroll-selector="vn-monitor-sales-orders vn-table"
|
||||
scroll-offset="100">
|
||||
</vn-pagination>
|
||||
</vn-card>
|
||||
<vn-worker-descriptor-popover
|
||||
vn-id="workerDescriptor">
|
||||
</vn-worker-descriptor-popover>
|
||||
<vn-client-descriptor-popover
|
||||
vn-id="clientDescriptor">
|
||||
</vn-client-descriptor-popover>
|
||||
<vn-contextmenu vn-id="contextmenu" targets="['vn-monitor-sales-orders vn-table']" model="model"
|
||||
expr-builder="$ctrl.exprBuilder(param, value)">
|
||||
<slot-menu>
|
||||
<vn-item translate
|
||||
ng-if="contextmenu.isFilterAllowed()"
|
||||
ng-click="contextmenu.filterBySelection()">
|
||||
Filter by selection
|
||||
</vn-item>
|
||||
<vn-item translate
|
||||
ng-if="contextmenu.isFilterAllowed()"
|
||||
ng-click="contextmenu.excludeSelection()">
|
||||
Exclude selection
|
||||
</vn-item>
|
||||
<vn-item translate
|
||||
ng-if="contextmenu.isFilterAllowed()"
|
||||
ng-click="contextmenu.removeFilter()">
|
||||
Remove filter
|
||||
</vn-item>
|
||||
<vn-item translate
|
||||
ng-click="contextmenu.removeAllFilters()">
|
||||
Remove all filters
|
||||
</vn-item>
|
||||
<vn-item translate
|
||||
ng-if="contextmenu.isActionAllowed()"
|
||||
ng-click="contextmenu.copyValue()">
|
||||
Copy value
|
||||
</vn-item>
|
||||
</slot-menu>
|
||||
</vn-contextmenu>
|
||||
<vn-confirm
|
||||
vn-id="delete"
|
||||
on-accept="$ctrl.onDelete()"
|
||||
question="All the selected elements will be deleted. Are you sure you want to continue?"
|
||||
message="Delete selected elements">
|
||||
</vn-confirm>
|
|
@ -1,74 +0,0 @@
|
|||
import ngModule from '../../module';
|
||||
import Section from 'salix/components/section';
|
||||
import './style.scss';
|
||||
|
||||
export default class Controller extends Section {
|
||||
get checked() {
|
||||
const rows = this.$.model.data || [];
|
||||
const checkedRows = [];
|
||||
for (let row of rows) {
|
||||
if (row.checked)
|
||||
checkedRows.push(row.id);
|
||||
}
|
||||
|
||||
return checkedRows;
|
||||
}
|
||||
|
||||
get totalChecked() {
|
||||
return this.checked.length;
|
||||
}
|
||||
|
||||
onDelete() {
|
||||
const params = {deletes: this.checked};
|
||||
const query = `SalesMonitors/deleteOrders`;
|
||||
this.$http.post(query, params).then(
|
||||
() => this.$.model.refresh());
|
||||
}
|
||||
|
||||
chipColor(date) {
|
||||
const today = Date.vnNew();
|
||||
today.setHours(0, 0, 0, 0);
|
||||
|
||||
const orderLanded = new Date(date);
|
||||
orderLanded.setHours(0, 0, 0, 0);
|
||||
|
||||
const difference = today - orderLanded;
|
||||
|
||||
if (difference == 0)
|
||||
return 'warning';
|
||||
if (difference < 0)
|
||||
return 'success';
|
||||
if (difference > 0)
|
||||
return 'alert';
|
||||
}
|
||||
|
||||
exprBuilder(param, value) {
|
||||
switch (param) {
|
||||
case 'date_send':
|
||||
return {[`o.date_send`]: {
|
||||
between: this.dateRange(value)}
|
||||
};
|
||||
case 'clientFk':
|
||||
return {[`c.id`]: value};
|
||||
case 'salesPersonFk':
|
||||
return {[`c.${param}`]: value};
|
||||
}
|
||||
}
|
||||
|
||||
dateRange(value) {
|
||||
const minHour = new Date(value);
|
||||
minHour.setHours(0, 0, 0, 0);
|
||||
const maxHour = new Date(value);
|
||||
maxHour.setHours(23, 59, 59, 59);
|
||||
|
||||
return [minHour, maxHour];
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnMonitorSalesOrders', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
require: {
|
||||
main: '^vnMonitorIndex'
|
||||
}
|
||||
});
|
|
@ -1,50 +0,0 @@
|
|||
import './index.js';
|
||||
import crudModel from 'core/mocks/crud-model';
|
||||
|
||||
describe('Component vnMonitorSalesOrders', () => {
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
|
||||
beforeEach(ngModule('monitor'));
|
||||
|
||||
beforeEach(inject(($componentController, _$httpBackend_) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
const $element = angular.element('<vn-monitor-sales-orders></vn-monitor-sales-orders>');
|
||||
controller = $componentController('vnMonitorSalesOrders', {$element});
|
||||
controller.$.model = crudModel;
|
||||
controller.$.model.data = [
|
||||
{id: 1, name: 'My item 1'},
|
||||
{id: 2, name: 'My item 2'},
|
||||
{id: 3, name: 'My item 3'}
|
||||
];
|
||||
}));
|
||||
|
||||
describe('checked() getter', () => {
|
||||
it('should return a the selected rows', () => {
|
||||
const modelData = controller.$.model.data;
|
||||
modelData[0].checked = true;
|
||||
modelData[1].checked = true;
|
||||
|
||||
const result = controller.checked;
|
||||
|
||||
expect(result).toEqual(expect.arrayContaining([1, 2]));
|
||||
});
|
||||
});
|
||||
|
||||
describe('onDelete()', () => {
|
||||
it('should make a query and then call to the model refresh() method', () => {
|
||||
jest.spyOn(controller.$.model, 'refresh');
|
||||
|
||||
const modelData = controller.$.model.data;
|
||||
modelData[0].checked = true;
|
||||
modelData[1].checked = true;
|
||||
|
||||
const expectedParams = {deletes: [1, 2]};
|
||||
$httpBackend.expect('POST', 'SalesMonitors/deleteOrders', expectedParams).respond(200);
|
||||
controller.onDelete();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.$.model.refresh).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,19 +0,0 @@
|
|||
@import "variables";
|
||||
|
||||
vn-monitor-sales-orders {
|
||||
vn-table.scrollable {
|
||||
max-height: 350px;
|
||||
overflow-x: hidden
|
||||
}
|
||||
|
||||
vn-table a.vn-tbody {
|
||||
& > vn-tr:nth-child(2) {
|
||||
color: gray;
|
||||
|
||||
& > vn-td {
|
||||
border-bottom: $border;
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,120 +0,0 @@
|
|||
<div class="search-panel">
|
||||
<vn-crud-model
|
||||
auto-load="true"
|
||||
url="Warehouses"
|
||||
data="warehouses">
|
||||
</vn-crud-model>
|
||||
<form id="manifold-form" ng-submit="$ctrl.onSearch()">
|
||||
<vn-horizontal class="vn-px-lg vn-pt-lg">
|
||||
<vn-textfield
|
||||
vn-one
|
||||
label="General search"
|
||||
ng-model="filter.search"
|
||||
info="Search ticket by id or alias"
|
||||
vn-focus>
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal class="vn-px-lg">
|
||||
<vn-textfield
|
||||
vn-one
|
||||
label="Client id"
|
||||
ng-model="filter.clientFk">
|
||||
</vn-textfield>
|
||||
<vn-textfield
|
||||
vn-one
|
||||
label="Order id"
|
||||
ng-model="filter.orderFk">
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal class="vn-px-lg">
|
||||
<vn-input-number
|
||||
vn-one
|
||||
min="0"
|
||||
step="1"
|
||||
label="Days onward"
|
||||
ng-model="filter.scopeDays"
|
||||
on-change="$ctrl.scopeDays = value"
|
||||
display-controls="true">
|
||||
</vn-input-number>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal class="vn-px-lg">
|
||||
<vn-textfield
|
||||
vn-one
|
||||
label="Nickname"
|
||||
ng-model="filter.nickname">
|
||||
</vn-textfield>
|
||||
<vn-worker-autocomplete
|
||||
vn-one
|
||||
ng-model="filter.salesPersonFk"
|
||||
departments="['VT']"
|
||||
label="Sales person">
|
||||
</vn-worker-autocomplete>
|
||||
<vn-textfield
|
||||
vn-one
|
||||
label="Invoice"
|
||||
ng-model="filter.refFk">
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal class="vn-px-lg">
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
label="Agency"
|
||||
ng-model="filter.agencyModeFk"
|
||||
url="AgencyModes/isActive">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
label="State"
|
||||
ng-model="filter.stateFk"
|
||||
url="States">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete vn-one
|
||||
data="$ctrl.groupedStates"
|
||||
label="Grouped States"
|
||||
value-field="id"
|
||||
show-field="name"
|
||||
ng-model="filter.alertLevel">
|
||||
<tpl-item>
|
||||
{{name}}
|
||||
</tpl-item>
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal class="vn-px-lg">
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
label="Warehouse"
|
||||
ng-model="filter.warehouseFk"
|
||||
data="warehouses">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
label="Province"
|
||||
ng-model="filter.provinceFk"
|
||||
url="Provinces">
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal class="vn-px-lg">
|
||||
<vn-check
|
||||
vn-one
|
||||
label="My team"
|
||||
ng-model="filter.myTeam"
|
||||
triple-state="true">
|
||||
</vn-check>
|
||||
<vn-check
|
||||
vn-one
|
||||
label="With problems"
|
||||
ng-model="filter.problems"
|
||||
triple-state="true">
|
||||
</vn-check>
|
||||
<vn-check
|
||||
vn-one
|
||||
label="Pending"
|
||||
ng-model="filter.pending"
|
||||
triple-state="true">
|
||||
</vn-check>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal class="vn-px-lg vn-pb-lg vn-mt-lg">
|
||||
<vn-submit label="Search"></vn-submit>
|
||||
</vn-horizontal>
|
||||
</form>
|
||||
</div>
|
|
@ -1,59 +0,0 @@
|
|||
import ngModule from '../../module';
|
||||
import SearchPanel from 'core/components/searchbar/search-panel';
|
||||
|
||||
class Controller extends SearchPanel {
|
||||
constructor($, $element) {
|
||||
super($, $element);
|
||||
this.filter = this.$.filter;
|
||||
|
||||
this.getGroupedStates();
|
||||
}
|
||||
|
||||
getGroupedStates() {
|
||||
let groupedStates = [];
|
||||
this.$http.get('AlertLevels').then(res => {
|
||||
for (let state of res.data) {
|
||||
groupedStates.push({
|
||||
id: state.id,
|
||||
code: state.code,
|
||||
name: this.$t(state.code)
|
||||
});
|
||||
}
|
||||
this.groupedStates = groupedStates;
|
||||
});
|
||||
}
|
||||
|
||||
get from() {
|
||||
return this._from;
|
||||
}
|
||||
|
||||
set from(value) {
|
||||
this._from = value;
|
||||
this.filter.scopeDays = null;
|
||||
}
|
||||
|
||||
get to() {
|
||||
return this._to;
|
||||
}
|
||||
|
||||
set to(value) {
|
||||
this._to = value;
|
||||
this.filter.scopeDays = null;
|
||||
}
|
||||
|
||||
get scopeDays() {
|
||||
return this._scopeDays;
|
||||
}
|
||||
|
||||
set scopeDays(value) {
|
||||
this._scopeDays = value;
|
||||
|
||||
this.filter.from = null;
|
||||
this.filter.to = null;
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnMonitorSalesSearchPanel', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -1,71 +0,0 @@
|
|||
import './index';
|
||||
|
||||
describe('Monitor Component vnMonitorSalesSearchPanel', () => {
|
||||
let $httpBackend;
|
||||
let controller;
|
||||
|
||||
beforeEach(ngModule('monitor'));
|
||||
|
||||
beforeEach(inject(($componentController, _$httpBackend_) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
controller = $componentController('vnMonitorSalesSearchPanel', {$element: null});
|
||||
controller.$t = () => {};
|
||||
controller.filter = {};
|
||||
}));
|
||||
|
||||
describe('getGroupedStates()', () => {
|
||||
it('should set an array of groupedStates with the adition of a name translation', () => {
|
||||
jest.spyOn(controller, '$t').mockReturnValue('miCodigo');
|
||||
const data = [
|
||||
{
|
||||
id: 9999,
|
||||
code: 'myCode'
|
||||
}
|
||||
];
|
||||
$httpBackend.whenGET('AlertLevels').respond(data);
|
||||
controller.getGroupedStates();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.groupedStates).toEqual([{
|
||||
id: 9999,
|
||||
code: 'myCode',
|
||||
name: 'miCodigo'
|
||||
}]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('from() setter', () => {
|
||||
it('should clear the scope days when setting the from property', () => {
|
||||
controller.filter.scopeDays = 1;
|
||||
|
||||
controller.from = Date.vnNew();
|
||||
|
||||
expect(controller.filter.scopeDays).toBeNull();
|
||||
expect(controller.from).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('to() setter', () => {
|
||||
it('should clear the scope days when setting the to property', () => {
|
||||
controller.filter.scopeDays = 1;
|
||||
|
||||
controller.to = Date.vnNew();
|
||||
|
||||
expect(controller.filter.scopeDays).toBeNull();
|
||||
expect(controller.to).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('scopeDays() setter', () => {
|
||||
it('should clear the date range when setting the scopeDays property', () => {
|
||||
controller.filter.from = Date.vnNew();
|
||||
controller.filter.to = Date.vnNew();
|
||||
|
||||
controller.scopeDays = 1;
|
||||
|
||||
expect(controller.filter.from).toBeNull();
|
||||
expect(controller.filter.to).toBeNull();
|
||||
expect(controller.scopeDays).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,85 +0,0 @@
|
|||
@import "variables";
|
||||
@import "effects";
|
||||
|
||||
vn-monitor-index {
|
||||
.header {
|
||||
padding: 12px 0 5px 0;
|
||||
color: gray;
|
||||
font-size: 1.2rem;
|
||||
border-bottom: $border;
|
||||
margin-bottom: 10px;
|
||||
|
||||
& > vn-none > vn-icon {
|
||||
@extend %clickable-light;
|
||||
color: $color-button;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
vn-none > .arrow {
|
||||
transition: transform 200ms;
|
||||
}
|
||||
}
|
||||
|
||||
vn-monitor-sales-clients {
|
||||
vn-card {
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.header {
|
||||
padding-right: 15px;
|
||||
|
||||
& > vn-none > .arrow {
|
||||
display: none
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vn-table.scrollable {
|
||||
height: 300px
|
||||
}
|
||||
|
||||
vn-horizontal {
|
||||
flex-wrap: wrap
|
||||
}
|
||||
|
||||
.hidden {
|
||||
vn-card {
|
||||
display: none
|
||||
}
|
||||
|
||||
.header > vn-none > .arrow {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width:1150px) {
|
||||
vn-monitor-index {
|
||||
& > vn-horizontal {
|
||||
flex-direction: column;
|
||||
|
||||
vn-monitor-sales-clients,
|
||||
vn-monitor-sales-orders {
|
||||
width: 100%
|
||||
}
|
||||
|
||||
vn-monitor-sales-clients {
|
||||
margin-bottom: 15px
|
||||
}
|
||||
}
|
||||
|
||||
vn-monitor-sales-clients {
|
||||
vn-card {
|
||||
margin-right: 0
|
||||
}
|
||||
|
||||
.header {
|
||||
padding-right: 0;
|
||||
|
||||
& > vn-none > .arrow {
|
||||
display: inline-block
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,270 +0,0 @@
|
|||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="SalesMonitors/salesFilter"
|
||||
auto-load="false"
|
||||
limit="20">
|
||||
</vn-crud-model>
|
||||
<vn-portal slot="topbar">
|
||||
<vn-searchbar
|
||||
vn-focus
|
||||
panel="vn-monitor-sales-search-panel"
|
||||
placeholder="Search tickets"
|
||||
info="Search ticket by id or alias"
|
||||
model="model"
|
||||
fetch-params="$ctrl.fetchParams($params)"
|
||||
suggested-filter="$ctrl.filterParams"
|
||||
auto-state="false">
|
||||
</vn-searchbar>
|
||||
</vn-portal>
|
||||
<vn-horizontal class="header">
|
||||
<vn-one translate>
|
||||
Tickets monitor
|
||||
</vn-one>
|
||||
</vn-horizontal>
|
||||
<vn-card>
|
||||
<smart-table
|
||||
model="model"
|
||||
view-config-id="ticketsMonitor"
|
||||
options="$ctrl.smartTableOptions"
|
||||
expr-builder="$ctrl.exprBuilder(param, value)">
|
||||
<slot-actions>
|
||||
<vn-check
|
||||
label="Auto-refresh"
|
||||
vn-tooltip="Toggle auto-refresh every 2 minutes"
|
||||
on-change="$ctrl.autoRefresh(value)">
|
||||
</vn-check>
|
||||
</slot-actions>
|
||||
<slot-table>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th field="totalProblems" menu-enabled="false">
|
||||
<span translate>Problems</span>
|
||||
</th>
|
||||
<th field="id">
|
||||
<span translate>Identifier</span>
|
||||
</th>
|
||||
<th field="nickname">
|
||||
<span translate>Client</span>
|
||||
</th>
|
||||
<th field="salesPersonFk">
|
||||
<span translate>Salesperson</span>
|
||||
</th>
|
||||
<th field="shippedDate" shrink-date filter-enabled="false">
|
||||
<span translate>Date</span>
|
||||
</th>
|
||||
<th field="theoreticalHour" filter-enabled="false">
|
||||
<span translate>Theoretical</span>
|
||||
</th>
|
||||
<th field="practicalHour" filter-enabled="false">
|
||||
<span translate>Practical</span>
|
||||
</th>
|
||||
<th field="preparationHour" filter-enabled="false">
|
||||
<span translate>Preparation</span>
|
||||
</th>
|
||||
<th field="provinceFk">
|
||||
<span translate>Province</span>
|
||||
</th>
|
||||
<th field="stateFk">
|
||||
<span translate>State</span>
|
||||
</th>
|
||||
<th field="isFragile" number>
|
||||
<span translate>Fragile</span>
|
||||
</th>
|
||||
<th field="zoneFk">
|
||||
<span translate>Zone</span>
|
||||
</th>
|
||||
<th field="totalWithVat" shrink>
|
||||
<span translate>Total</span>
|
||||
</th>
|
||||
<th shrink></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="ticket in model.data track by ticket.id"
|
||||
vn-anchor="{
|
||||
state: 'ticket.card.summary',
|
||||
params: {id: ticket.id},
|
||||
target: '_blank'
|
||||
}">
|
||||
<td>
|
||||
<vn-icon
|
||||
ng-show="ticket.isTaxDataChecked === 0"
|
||||
translate-attr="{title: 'No verified data'}"
|
||||
class="bright"
|
||||
icon="icon-no036">
|
||||
</vn-icon>
|
||||
<vn-icon
|
||||
ng-show="ticket.hasTicketRequest"
|
||||
translate-attr="{title: 'Purchase request'}"
|
||||
class="bright"
|
||||
icon="icon-buyrequest">
|
||||
</vn-icon>
|
||||
<vn-icon
|
||||
ng-show="ticket.itemShortage"
|
||||
translate-attr="{title: 'Not visible'}"
|
||||
class="bright"
|
||||
icon="icon-unavailable">
|
||||
</vn-icon>
|
||||
<vn-icon
|
||||
ng-show="ticket.isFreezed"
|
||||
translate-attr="{title: 'Client frozen'}"
|
||||
class="bright"
|
||||
icon="icon-frozen">
|
||||
</vn-icon>
|
||||
<vn-icon
|
||||
ng-show="ticket.risk"
|
||||
ng-class="{'highRisk': ticket.hasHighRisk}"
|
||||
title="{{$ctrl.$t('Risk')}}: {{ticket.risk}}"
|
||||
class="bright"
|
||||
icon="icon-risk">
|
||||
</vn-icon>
|
||||
<vn-icon
|
||||
ng-show="ticket.hasComponentLack"
|
||||
translate-attr="{title: 'Component lack'}"
|
||||
class="bright"
|
||||
icon="icon-components">
|
||||
</vn-icon>
|
||||
<vn-icon
|
||||
ng-show="ticket.isTooLittle"
|
||||
translate-attr="{title: 'Ticket too little'}"
|
||||
class="bright"
|
||||
icon="icon-isTooLittle">
|
||||
</vn-icon>
|
||||
</td>
|
||||
<td>
|
||||
<span
|
||||
vn-click-stop="ticketDescriptor.show($event, ticket.id)"
|
||||
class="link">
|
||||
{{ticket.id}}
|
||||
</span>
|
||||
</td>
|
||||
<td name="nickname">
|
||||
<span
|
||||
title="{{ticket.nickname}}"
|
||||
vn-click-stop="clientDescriptor.show($event, ticket.clientFk)"
|
||||
class="link">
|
||||
{{ticket.nickname}}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<span
|
||||
title="{{ticket.userName}}"
|
||||
vn-click-stop="workerDescriptor.show($event, ticket.salesPersonFk)"
|
||||
class="link">
|
||||
{{ticket.userName | dashIfEmpty}}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="chip {{$ctrl.compareDate(ticket.shippedDate)}}">
|
||||
{{ticket.shippedDate | date: 'dd/MM/yyyy'}}
|
||||
</span>
|
||||
</td>
|
||||
<td>{{ticket.zoneLanding | date: 'HH:mm'}}</td>
|
||||
<td>{{ticket.practicalHour | date: 'HH:mm'}}</td>
|
||||
<td>{{ticket.shipped | date: 'HH:mm'}}</td>
|
||||
<td>{{ticket.province}}</td>
|
||||
<td>
|
||||
<span
|
||||
ng-show="ticket.refFk"
|
||||
title="{{ticket.refFk}}"
|
||||
vn-click-stop="invoiceOutDescriptor.show($event, ticket.invoiceOutId)"
|
||||
class="link">
|
||||
{{ticket.refFk}}
|
||||
</span>
|
||||
<span
|
||||
ng-show="!ticket.refFk"
|
||||
class="chip {{ticket.classColor}}">
|
||||
{{ticket.state}}
|
||||
</span>
|
||||
</td>
|
||||
<td number>
|
||||
<vn-icon
|
||||
ng-show="ticket.isFragile"
|
||||
translate-attr="{title: 'Is fragile'}"
|
||||
class="bright"
|
||||
icon="local_bar">
|
||||
</vn-icon>
|
||||
</td>
|
||||
<td name="zone">
|
||||
<span
|
||||
title="{{ticket.zoneName}}"
|
||||
vn-click-stop="zoneDescriptor.show($event, ticket.zoneFk)"
|
||||
class="link">
|
||||
{{ticket.zoneName | dashIfEmpty}}
|
||||
</span>
|
||||
</td>
|
||||
<td number>
|
||||
<span class="chip {{$ctrl.totalPriceColor(ticket)}}">
|
||||
{{(ticket.totalWithVat ? ticket.totalWithVat : 0) | currency: 'EUR': 2}}
|
||||
</span>
|
||||
</td>
|
||||
<td actions>
|
||||
<vn-icon-button
|
||||
vn-anchor="{
|
||||
state: 'ticket.card.sale',
|
||||
params: {id: ticket.id},
|
||||
target: '_blank'
|
||||
}"
|
||||
vn-tooltip="Go to lines"
|
||||
icon="icon-lines">
|
||||
</vn-icon-button>
|
||||
<vn-icon-button
|
||||
vn-click-stop="$ctrl.preview(ticket)"
|
||||
vn-tooltip="Preview"
|
||||
icon="preview">
|
||||
</vn-icon-button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</slot-table>
|
||||
</smart-table>
|
||||
</vn-card>
|
||||
<vn-ticket-descriptor-popover
|
||||
vn-id="ticketDescriptor">
|
||||
</vn-ticket-descriptor-popover>
|
||||
<vn-worker-descriptor-popover
|
||||
vn-id="workerDescriptor">
|
||||
</vn-worker-descriptor-popover>
|
||||
<vn-client-descriptor-popover
|
||||
vn-id="clientDescriptor">
|
||||
</vn-client-descriptor-popover>
|
||||
<vn-zone-descriptor-popover
|
||||
vn-id="zoneDescriptor">
|
||||
</vn-zone-descriptor-popover>
|
||||
<vn-popup vn-id="summary">
|
||||
<vn-ticket-summary
|
||||
ticket="$ctrl.selectedTicket"
|
||||
model="model">
|
||||
</vn-ticket-summary>
|
||||
</vn-popup>
|
||||
<vn-contextmenu vn-id="contextmenu" targets="['vn-monitor-sales-tickets smart-table']" model="model"
|
||||
expr-builder="$ctrl.exprBuilder(param, value)">
|
||||
<slot-menu>
|
||||
<vn-item translate
|
||||
ng-if="contextmenu.isFilterAllowed()"
|
||||
ng-click="contextmenu.filterBySelection()">
|
||||
Filter by selection
|
||||
</vn-item>
|
||||
<vn-item translate
|
||||
ng-if="contextmenu.isFilterAllowed()"
|
||||
ng-click="contextmenu.excludeSelection()">
|
||||
Exclude selection
|
||||
</vn-item>
|
||||
<vn-item translate
|
||||
ng-if="contextmenu.isFilterAllowed()"
|
||||
ng-click="contextmenu.removeFilter()">
|
||||
Remove filter
|
||||
</vn-item>
|
||||
<vn-item translate
|
||||
ng-click="contextmenu.removeAllFilters()">
|
||||
Remove all filters
|
||||
</vn-item>
|
||||
<vn-item translate
|
||||
ng-if="contextmenu.isActionAllowed()"
|
||||
ng-click="contextmenu.copyValue()">
|
||||
Copy value
|
||||
</vn-item>
|
||||
</slot-menu>
|
||||
</vn-contextmenu>
|
|
@ -1,178 +0,0 @@
|
|||
import ngModule from '../../module';
|
||||
import Section from 'salix/components/section';
|
||||
import './style.scss';
|
||||
|
||||
export default class Controller extends Section {
|
||||
constructor($element, $) {
|
||||
super($element, $);
|
||||
|
||||
this.filterParams = this.fetchParams();
|
||||
this.smartTableOptions = {
|
||||
activeButtons: {
|
||||
search: true,
|
||||
shownColumns: true,
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
field: 'totalProblems',
|
||||
searchable: false
|
||||
},
|
||||
{
|
||||
field: 'salesPersonFk',
|
||||
autocomplete: {
|
||||
url: 'Workers/activeWithInheritedRole',
|
||||
where: `{role: 'salesPerson'}`,
|
||||
searchFunction: '{firstName: $search}',
|
||||
showField: 'nickname',
|
||||
valueField: 'id',
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'provinceFk',
|
||||
autocomplete: {
|
||||
url: 'Provinces',
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'stateFk',
|
||||
autocomplete: {
|
||||
url: 'States',
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'zoneFk',
|
||||
autocomplete: {
|
||||
url: 'Zones',
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'warehouseFk',
|
||||
autocomplete: {
|
||||
url: 'Warehouses',
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'shippedDate',
|
||||
datepicker: true
|
||||
},
|
||||
{
|
||||
field: 'theoreticalHour',
|
||||
searchable: false
|
||||
},
|
||||
{
|
||||
field: 'preparationHour',
|
||||
searchable: false
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
$onInit() {
|
||||
if (!this.$params.q) {
|
||||
this.$.$applyAsync(
|
||||
() => this.$.model.applyFilter(null, this.filterParams));
|
||||
}
|
||||
}
|
||||
|
||||
fetchParams($params = {}) {
|
||||
const excludedParams = [
|
||||
'search',
|
||||
'clientFk',
|
||||
'orderFk',
|
||||
'refFk',
|
||||
'scopeDays'
|
||||
];
|
||||
|
||||
const hasExcludedParams = excludedParams.some(param => {
|
||||
return $params && $params[param] != undefined;
|
||||
});
|
||||
const hasParams = Object.entries($params).length;
|
||||
if (!hasParams || !hasExcludedParams)
|
||||
$params.scopeDays = 1;
|
||||
|
||||
if (typeof $params.scopeDays === 'number') {
|
||||
const from = Date.vnNew();
|
||||
from.setHours(0, 0, 0, 0);
|
||||
|
||||
const to = new Date(from.getTime());
|
||||
to.setDate(to.getDate() + $params.scopeDays);
|
||||
to.setHours(23, 59, 59, 999);
|
||||
|
||||
Object.assign($params, {from, to});
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
compareDate(date) {
|
||||
let today = Date.vnNew();
|
||||
today.setHours(0, 0, 0, 0);
|
||||
let timeTicket = new Date(date);
|
||||
timeTicket.setHours(0, 0, 0, 0);
|
||||
|
||||
let comparation = today - timeTicket;
|
||||
|
||||
if (comparation == 0)
|
||||
return 'warning';
|
||||
if (comparation < 0)
|
||||
return 'success';
|
||||
}
|
||||
|
||||
totalPriceColor(ticket) {
|
||||
const total = parseInt(ticket.totalWithVat);
|
||||
if (total > 0 && total < 50)
|
||||
return 'warning';
|
||||
}
|
||||
|
||||
exprBuilder(param, value) {
|
||||
switch (param) {
|
||||
case 'stateFk':
|
||||
return {'ts.stateFk': value};
|
||||
case 'salesPersonFk':
|
||||
return {'c.salesPersonFk': value};
|
||||
case 'provinceFk':
|
||||
return {'a.provinceFk': value};
|
||||
case 'theoreticalHour':
|
||||
return {'z.hour': value};
|
||||
case 'practicalHour':
|
||||
return {'zed.etc': value};
|
||||
case 'shippedDate':
|
||||
return {'t.shipped': {
|
||||
between: this.dateRange(value)}
|
||||
};
|
||||
case 'nickname':
|
||||
return {[`t.nickname`]: {like: `%${value}%`}};
|
||||
case 'zoneFk':
|
||||
case 'totalWithVat':
|
||||
return {[`t.${param}`]: value};
|
||||
}
|
||||
}
|
||||
|
||||
dateRange(value) {
|
||||
const minHour = new Date(value);
|
||||
minHour.setHours(0, 0, 0, 0);
|
||||
const maxHour = new Date(value);
|
||||
maxHour.setHours(23, 59, 59, 59);
|
||||
|
||||
return [minHour, maxHour];
|
||||
}
|
||||
|
||||
preview(ticket) {
|
||||
this.selectedTicket = ticket;
|
||||
this.$.summary.show();
|
||||
}
|
||||
|
||||
autoRefresh(value) {
|
||||
if (value)
|
||||
this.refreshTimer = setInterval(() => this.$.model.refresh(), 120000);
|
||||
else {
|
||||
clearInterval(this.refreshTimer);
|
||||
this.refreshTimer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnMonitorSalesTickets', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -1,133 +0,0 @@
|
|||
import './index.js';
|
||||
describe('Component vnMonitorSalesTickets', () => {
|
||||
let controller;
|
||||
let $window;
|
||||
let tickets = [{
|
||||
id: 1,
|
||||
clientFk: 1,
|
||||
checked: false,
|
||||
totalWithVat: 10.5
|
||||
}, {
|
||||
id: 2,
|
||||
clientFk: 1,
|
||||
checked: true,
|
||||
totalWithVat: 20.5
|
||||
}, {
|
||||
id: 3,
|
||||
clientFk: 1,
|
||||
checked: true,
|
||||
totalWithVat: 30
|
||||
}];
|
||||
|
||||
beforeEach(ngModule('monitor'));
|
||||
|
||||
beforeEach(inject(($componentController, _$window_) => {
|
||||
$window = _$window_;
|
||||
const $element = angular.element('<vn-monitor-sales-tickets></vn-monitor-sales-tickets>');
|
||||
controller = $componentController('vnMonitorSalesTickets', {$element});
|
||||
}));
|
||||
|
||||
describe('fetchParams()', () => {
|
||||
it('should return a range of dates with passed scope days', () => {
|
||||
let params = controller.fetchParams({
|
||||
scopeDays: 2
|
||||
});
|
||||
const from = Date.vnNew();
|
||||
from.setHours(0, 0, 0, 0);
|
||||
const to = new Date(from.getTime());
|
||||
to.setDate(to.getDate() + params.scopeDays);
|
||||
to.setHours(23, 59, 59, 999);
|
||||
|
||||
const expectedParams = {
|
||||
from,
|
||||
scopeDays: params.scopeDays,
|
||||
to
|
||||
};
|
||||
|
||||
expect(params).toEqual(expectedParams);
|
||||
});
|
||||
|
||||
it('should return default value for scope days', () => {
|
||||
let params = controller.fetchParams({
|
||||
scopeDays: 1
|
||||
});
|
||||
|
||||
expect(params.scopeDays).toEqual(1);
|
||||
});
|
||||
|
||||
it('should return the given scope days', () => {
|
||||
let params = controller.fetchParams({
|
||||
scopeDays: 2
|
||||
});
|
||||
|
||||
expect(params.scopeDays).toEqual(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('compareDate()', () => {
|
||||
it('should return warning when the date is the present', () => {
|
||||
let today = Date.vnNew();
|
||||
let result = controller.compareDate(today);
|
||||
|
||||
expect(result).toEqual('warning');
|
||||
});
|
||||
|
||||
it('should return sucess when the date is in the future', () => {
|
||||
let futureDate = Date.vnNew();
|
||||
futureDate = futureDate.setDate(futureDate.getDate() + 10);
|
||||
let result = controller.compareDate(futureDate);
|
||||
|
||||
expect(result).toEqual('success');
|
||||
});
|
||||
|
||||
it('should return undefined when the date is in the past', () => {
|
||||
let pastDate = Date.vnNew();
|
||||
pastDate = pastDate.setDate(pastDate.getDate() - 10);
|
||||
let result = controller.compareDate(pastDate);
|
||||
|
||||
expect(result).toEqual(undefined);
|
||||
});
|
||||
});
|
||||
|
||||
describe('totalPriceColor()', () => {
|
||||
it('should return "warning" when the ticket amount is less than 50€', () => {
|
||||
const result = controller.totalPriceColor({totalWithVat: '8.50'});
|
||||
|
||||
expect(result).toEqual('warning');
|
||||
});
|
||||
});
|
||||
|
||||
describe('dateRange()', () => {
|
||||
it('should return two dates with the hours at the start and end of the given date', () => {
|
||||
const now = Date.vnNew();
|
||||
|
||||
const today = now.getDate();
|
||||
|
||||
const dateRange = controller.dateRange(now);
|
||||
const start = dateRange[0].toString();
|
||||
const end = dateRange[1].toString();
|
||||
|
||||
expect(start).toContain(today);
|
||||
expect(start).toContain('00:00:00');
|
||||
|
||||
expect(end).toContain(today);
|
||||
expect(end).toContain('23:59:59');
|
||||
});
|
||||
});
|
||||
|
||||
describe('preview()', () => {
|
||||
it('should show the dialog summary', () => {
|
||||
controller.$.summary = {show: () => {}};
|
||||
jest.spyOn(controller.$.summary, 'show');
|
||||
|
||||
let event = new MouseEvent('click', {
|
||||
view: $window,
|
||||
bubbles: true,
|
||||
cancelable: true
|
||||
});
|
||||
controller.preview(event, tickets[0]);
|
||||
|
||||
expect(controller.$.summary.show).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,47 +0,0 @@
|
|||
@import "variables";
|
||||
|
||||
vn-monitor-sales-tickets {
|
||||
@media screen and (max-width: 1440px) {
|
||||
.expendable {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
vn-th.icon-field,
|
||||
vn-th.icon-field *,
|
||||
vn-td.icon-field,
|
||||
vn-td.icon-field * {
|
||||
padding: 0;
|
||||
max-width: 50px
|
||||
}
|
||||
|
||||
vn-th[field="nickname"],
|
||||
vn-td[name="nickname"] {
|
||||
min-width: 250px
|
||||
}
|
||||
|
||||
vn-td.icon-field > vn-icon {
|
||||
margin-left: 3px;
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
vn-table.scrollable.lg {
|
||||
height: 736px
|
||||
}
|
||||
|
||||
tbody tr[ng-repeat]:focus {
|
||||
background-color: $color-primary-light
|
||||
}
|
||||
|
||||
.highRisk i {
|
||||
color: $color-alert
|
||||
}
|
||||
|
||||
td[name="nickname"] {
|
||||
max-width: 200px
|
||||
}
|
||||
|
||||
td[name="zone"] {
|
||||
max-width: 150px
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
Sales monitor: Monitor de ventas
|
|
@ -1,4 +0,0 @@
|
|||
<vn-portal slot="menu">
|
||||
<vn-left-menu></vn-left-menu>
|
||||
</vn-portal>
|
||||
<ui-view></ui-view>
|
|
@ -1,7 +1,16 @@
|
|||
import ngModule from '../module';
|
||||
import ModuleMain from 'salix/components/module-main';
|
||||
|
||||
export default class Monitor extends ModuleMain {}
|
||||
export default class Monitor extends ModuleMain {
|
||||
constructor($element, $) {
|
||||
super($element, $);
|
||||
}
|
||||
|
||||
async $onInit() {
|
||||
this.$state.go('home');
|
||||
window.location.href = await this.vnApp.getUrl(`monitor/`);
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnMonitor', {
|
||||
controller: Monitor,
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
{
|
||||
"module": "monitor",
|
||||
"name": "Monitors",
|
||||
"icon" : "grid_view",
|
||||
"dependencies": ["ticket", "worker", "client"],
|
||||
"validations" : true,
|
||||
"icon": "grid_view",
|
||||
"menus": {
|
||||
"main": [
|
||||
{"state": "monitor.index", "icon": "grid_view"}
|
||||
],
|
||||
"main": [],
|
||||
"card": []
|
||||
},
|
||||
"keybindings": [
|
||||
|
|
|
@ -1,88 +0,0 @@
|
|||
<mg-ajax path="Orders/{{patch.params.id}}/updateBasicData" options="vnPatch"></mg-ajax>
|
||||
<vn-crud-model
|
||||
autoload="true"
|
||||
url="Addresses"
|
||||
data="address"
|
||||
order="nickname"
|
||||
vn-id="address-model">
|
||||
</vn-crud-model>
|
||||
<vn-watcher
|
||||
vn-id="watcher"
|
||||
data="$ctrl.order"
|
||||
form="form"
|
||||
save="patch">
|
||||
</vn-watcher>
|
||||
<form name="form" ng-submit="watcher.submit()" class="vn-w-md">
|
||||
<vn-card class="vn-pa-lg">
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
url="Clients"
|
||||
label="Client"
|
||||
search-function="{or: [{id: $search}, {name: {like: '%'+ $search +'%'}}]}"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
ng-model="$ctrl.order.clientFk"
|
||||
vn-name="client"
|
||||
selection="$ctrl.selection"
|
||||
fields="['defaultAddressFk']">
|
||||
<tpl-item>
|
||||
<div>{{::name}}</div>
|
||||
<div class="text-secondary text-caption">#{{::id}}</div>
|
||||
</tpl-item>
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
fields="['id', 'nickname']"
|
||||
data="address"
|
||||
label="Address"
|
||||
search-function="$search"
|
||||
show-field="nickname"
|
||||
value-field="id"
|
||||
ng-model="$ctrl.order.addressFk"
|
||||
vn-name="address"
|
||||
on-change="$ctrl.getAvailableAgencies()">
|
||||
<tpl-item>{{::nickname}}</tpl-item>
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-date-picker
|
||||
vn-one
|
||||
label="Landed"
|
||||
ng-model="$ctrl.order.landed"
|
||||
vn-name="landed"
|
||||
on-change="$ctrl.getAvailableAgencies()">
|
||||
</vn-date-picker>
|
||||
<vn-autocomplete
|
||||
disabled="!$ctrl.order.addressFk || !$ctrl.order.landed"
|
||||
data="$ctrl._availableAgencies"
|
||||
label="Agency"
|
||||
show-field="agencyMode"
|
||||
value-field="agencyModeFk"
|
||||
ng-model="$ctrl.order.agencyModeFk"
|
||||
vn-name="agencyMode">
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-textarea
|
||||
vn-one
|
||||
label="Notes"
|
||||
ng-model="$ctrl.order.note"
|
||||
vn-name="note"
|
||||
rule>
|
||||
</vn-textarea>
|
||||
</vn-horizontal>
|
||||
</vn-card>
|
||||
<vn-button-bar>
|
||||
<vn-submit
|
||||
disabled="!watcher.dataChanged()"
|
||||
label="Save">
|
||||
</vn-submit>
|
||||
<vn-button
|
||||
class="cancel"
|
||||
label="Undo changes"
|
||||
disabled="!watcher.dataChanged()"
|
||||
ng-click="watcher.loadOriginalData()">
|
||||
</vn-button>
|
||||
</vn-button-bar>
|
||||
</form>
|
|
@ -1,57 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import Section from 'salix/components/section';
|
||||
import './style.scss';
|
||||
|
||||
class Controller extends Section {
|
||||
constructor($element, $) {
|
||||
super($element, $);
|
||||
let isDirty = false;
|
||||
this.$.$watch('$ctrl.selection', newValue => {
|
||||
if (newValue) {
|
||||
this.$.addressModel.where = {clientFk: newValue.id};
|
||||
this.$.addressModel.refresh();
|
||||
if (isDirty)
|
||||
this.order.addressFk = newValue.defaultAddressFk;
|
||||
isDirty = true;
|
||||
} else {
|
||||
this.$.addressModel.clear();
|
||||
if (isDirty)
|
||||
this.order.addressFk = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
set order(value = {}) {
|
||||
this._order = value;
|
||||
|
||||
const agencyModeFk = value.agencyModeFk;
|
||||
this.getAvailableAgencies();
|
||||
this._order.agencyModeFk = agencyModeFk;
|
||||
}
|
||||
|
||||
get order() {
|
||||
return this._order;
|
||||
}
|
||||
|
||||
getAvailableAgencies() {
|
||||
const order = this.order;
|
||||
order.agencyModeFk = null;
|
||||
|
||||
const params = {
|
||||
addressFk: order.addressFk,
|
||||
landed: order.landed
|
||||
};
|
||||
if (params.landed && params.addressFk) {
|
||||
this.$http.get(`Agencies/landsThatDay`, {params})
|
||||
.then(res => this._availableAgencies = res.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnOrderBasicData', {
|
||||
controller: Controller,
|
||||
template: require('./index.html'),
|
||||
bindings: {
|
||||
order: '<'
|
||||
}
|
||||
});
|
|
@ -1,67 +0,0 @@
|
|||
import './index.js';
|
||||
|
||||
describe('Order', () => {
|
||||
describe('Component vnOrderBasicData', () => {
|
||||
let $httpBackend;
|
||||
let $httpParamSerializer;
|
||||
let controller;
|
||||
let $scope;
|
||||
|
||||
beforeEach(ngModule('order'));
|
||||
|
||||
beforeEach(inject(($compile, _$httpBackend_, $rootScope, _$httpParamSerializer_) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
$httpParamSerializer = _$httpParamSerializer_;
|
||||
$scope = $rootScope.$new();
|
||||
|
||||
$httpBackend.whenRoute('GET', 'Addresses')
|
||||
.respond([{id: 2, nickname: 'address 2'}]);
|
||||
$httpBackend.whenRoute('GET', 'Clients')
|
||||
.respond([{id: 1, defaultAddressFk: 1}]);
|
||||
$scope.order = {clientFk: 1, addressFk: 1};
|
||||
|
||||
let $element = $compile('<vn-order-basic-data order="order"></vn-order-basic-data>')($scope);
|
||||
$httpBackend.flush();
|
||||
controller = $element.controller('vnOrderBasicData');
|
||||
}));
|
||||
|
||||
afterAll(() => {
|
||||
$scope.$destroy();
|
||||
$element.remove();
|
||||
});
|
||||
|
||||
describe('constructor()', () => {
|
||||
it('should update the address after the client changes', async() => {
|
||||
const addressId = 999;
|
||||
const id = 444;
|
||||
|
||||
controller.selection = {id: id, defaultAddressFk: addressId};
|
||||
$scope.$digest();
|
||||
|
||||
expect(controller.order.addressFk).toEqual(addressId);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getAvailableAgencies()', () => {
|
||||
it('should set agencyModeFk to null and get the available agencies if the order has landed and client', async() => {
|
||||
controller.order.agencyModeFk = 999;
|
||||
controller.order.addressFk = 999;
|
||||
controller.order.landed = Date.vnNew();
|
||||
|
||||
const expectedAgencies = [{id: 1}, {id: 2}];
|
||||
|
||||
const paramsObj = {
|
||||
addressFk: controller.order.addressFk,
|
||||
landed: controller.order.landed
|
||||
};
|
||||
const serializedParams = $httpParamSerializer(paramsObj);
|
||||
$httpBackend.expect('GET', `Agencies/landsThatDay?${serializedParams}`).respond(expectedAgencies);
|
||||
controller.getAvailableAgencies();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.order.agencyModeFk).toBeDefined();
|
||||
expect(controller._availableAgencies).toEqual(expectedAgencies);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1 +0,0 @@
|
|||
This form has been disabled because there are lines in this order or it's confirmed: Este formulario ha sido deshabilitado por que esta orden contiene líneas o está confirmada
|
|
@ -1,9 +0,0 @@
|
|||
vn-order-basic-data {
|
||||
.disabledForm {
|
||||
text-align: center;
|
||||
color: red;
|
||||
span {
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
<vn-portal slot="menu">
|
||||
<vn-order-descriptor order="$ctrl.order"></vn-order-descriptor>
|
||||
<vn-left-menu source="card"></vn-left-menu>
|
||||
</vn-portal>
|
||||
<ui-view></ui-view>
|
|
@ -1,58 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import ModuleCard from 'salix/components/module-card';
|
||||
|
||||
class Controller extends ModuleCard {
|
||||
reload() {
|
||||
let filter = {
|
||||
include: [
|
||||
{
|
||||
relation: 'agencyMode',
|
||||
scope: {
|
||||
fields: ['name']
|
||||
}
|
||||
}, {
|
||||
relation: 'address',
|
||||
scope: {
|
||||
fields: ['nickname']
|
||||
}
|
||||
}, {
|
||||
relation: 'rows',
|
||||
scope: {
|
||||
fields: ['id']
|
||||
}
|
||||
}, {
|
||||
relation: 'client',
|
||||
scope: {
|
||||
fields: [
|
||||
'salesPersonFk',
|
||||
'name',
|
||||
'isActive',
|
||||
'isFreezed',
|
||||
'isTaxDataChecked'
|
||||
],
|
||||
include: {
|
||||
relation: 'salesPersonUser',
|
||||
scope: {
|
||||
fields: ['id', 'name']
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
return this.$q.all([
|
||||
this.$http.get(`Orders/${this.$params.id}`, {filter})
|
||||
.then(res => this.order = res.data),
|
||||
this.$http.get(`Orders/${this.$params.id}/getTotal`)
|
||||
.then(res => ({total: res.data}))
|
||||
]).then(res => {
|
||||
this.order = Object.assign.apply(null, res);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnOrderCard', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -1,31 +0,0 @@
|
|||
import './index.js';
|
||||
|
||||
describe('Order', () => {
|
||||
describe('Component vnOrderCard', () => {
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
let data = {id: 1, name: 'fooName'};
|
||||
let total = 10.5;
|
||||
|
||||
beforeEach(ngModule('order'));
|
||||
|
||||
beforeEach(inject(($componentController, _$httpBackend_, $stateParams) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
|
||||
let $element = angular.element('<div></div>');
|
||||
controller = $componentController('vnOrderCard', {$element});
|
||||
|
||||
$stateParams.id = data.id;
|
||||
$httpBackend.whenRoute('GET', 'Orders/:id').respond(data);
|
||||
$httpBackend.whenRoute('GET', 'Orders/:id/getTotal').respond(200, total);
|
||||
}));
|
||||
|
||||
it('should request data and total, merge them, and set it on the controller', () => {
|
||||
controller.reload();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.order).toEqual(Object.assign({}, data, {total}));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
<div class="vn-pa-lg" style="min-width: 18em">
|
||||
<form name="form" ng-submit="$ctrl.onSearch()">
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
vn-id="tag"
|
||||
vn-one
|
||||
selection="filter.tagSelection"
|
||||
ng-model="filter.tagFk"
|
||||
data="$ctrl.resultTags"
|
||||
show-field="name"
|
||||
label="Tag"
|
||||
on-change="itemTag.value = null">
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal ng-repeat="tagValue in filter.values">
|
||||
<vn-textfield
|
||||
vn-one
|
||||
ng-show="tag.selection.isFree != false"
|
||||
vn-id="text"
|
||||
label="Value"
|
||||
ng-model="tagValue.value">
|
||||
</vn-textfield>
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
ng-show="tag.selection.isFree == false"
|
||||
url="{{'Tags/' + tag.selection.id + '/filterValue'}}"
|
||||
search-function="{value: $search}"
|
||||
label="Value"
|
||||
ng-model="tagValue.value"
|
||||
show-field="value"
|
||||
value-field="value">
|
||||
</vn-autocomplete>
|
||||
<vn-icon-button
|
||||
vn-none
|
||||
vn-tooltip="Remove tag"
|
||||
icon="delete"
|
||||
ng-click="filter.values.splice($index, 1)"
|
||||
tabindex="-1">
|
||||
</vn-icon-button>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-icon-button
|
||||
vn-none
|
||||
vn-bind="+"
|
||||
vn-tooltip="Add value"
|
||||
icon="add_circle"
|
||||
ng-click="$ctrl.addValue()">
|
||||
</vn-icon-button>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal class="vn-mt-lg">
|
||||
<vn-submit label="Search"></vn-submit>
|
||||
</vn-horizontal>
|
||||
</form>
|
||||
</div>
|
|
@ -1,38 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import SearchPanel from 'core/components/searchbar/search-panel';
|
||||
|
||||
class Controller extends SearchPanel {
|
||||
constructor($element, $) {
|
||||
super($element, $);
|
||||
|
||||
this.filter = {};
|
||||
}
|
||||
|
||||
get filter() {
|
||||
return this.$.filter;
|
||||
}
|
||||
|
||||
set filter(value) {
|
||||
if (!value)
|
||||
value = {};
|
||||
if (!value.values)
|
||||
value.values = [{}];
|
||||
|
||||
this.$.filter = value;
|
||||
}
|
||||
|
||||
addValue() {
|
||||
this.filter.values.push({});
|
||||
setTimeout(() => this.parentPopover.relocate());
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnOrderCatalogSearchPanel', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
onSubmit: '&?',
|
||||
parentPopover: '<?',
|
||||
resultTags: '<?'
|
||||
}
|
||||
});
|
|
@ -1,81 +0,0 @@
|
|||
<vn-data-viewer
|
||||
model="$ctrl.model">
|
||||
<vn-horizontal class="catalog-list">
|
||||
<section ng-repeat="item in $ctrl.model.data" class="product">
|
||||
<vn-card>
|
||||
<div class="image">
|
||||
<div ng-if="::item.hex != null" class="item-color-background">
|
||||
<div class="item-color" ng-style="{'background-color': '#' + item.hex}"></div>
|
||||
</div>
|
||||
<img
|
||||
ng-src="{{::$root.imagePath('catalog', '200x200', item.id)}}"
|
||||
zoom-image="{{::$root.imagePath('catalog', '1600x900', item.id)}}"
|
||||
on-error-src/>
|
||||
</div>
|
||||
<div class="description">
|
||||
<h3 class="link"
|
||||
ng-click="itemDescriptor.show($event, item.id)">
|
||||
{{::item.name}}
|
||||
</h3>
|
||||
<h4 class="ellipsize">
|
||||
<span translate-attr="::{title: item.subName}">{{::item.subName}}</span>
|
||||
</h4>
|
||||
<div class="tags">
|
||||
<vn-label-value
|
||||
ng-if="::item.value5"
|
||||
label="{{::item.tag5}}"
|
||||
value="{{::item.value5}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value
|
||||
ng-if="::item.value6"
|
||||
label="{{::item.tag6}}"
|
||||
value="{{::item.value6}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value
|
||||
ng-if="::item.value7"
|
||||
label="{{::item.tag7}}"
|
||||
value="{{::item.value7}}">
|
||||
</vn-label-value>
|
||||
</div>
|
||||
<vn-horizontal
|
||||
class="text-right text-caption alert vn-mr-xs"
|
||||
ng-if="::item.minQuantity">
|
||||
<vn-one>
|
||||
<vn-icon
|
||||
icon="production_quantity_limits"
|
||||
translate-attr="{title: 'Minimal quantity'}"
|
||||
class="text-subtitle1">
|
||||
</vn-icon>
|
||||
</vn-one>
|
||||
{{::item.minQuantity}}
|
||||
</vn-horizontal>
|
||||
<div class="footer">
|
||||
<div class="price">
|
||||
<vn-one>
|
||||
<span>{{::item.available}}</span>
|
||||
<span translate>to</span>
|
||||
<span>{{::item.price | currency:'EUR':2}}</span>
|
||||
</vn-one>
|
||||
<vn-icon-button vn-none
|
||||
icon="add_circle"
|
||||
ng-click="pricesPopover.show($event, item)"
|
||||
vn-tooltip="Add">
|
||||
</vn-icon-button>
|
||||
</div>
|
||||
<div class="priceKg" ng-show="::item.priceKg">
|
||||
<span>Precio por kilo {{::item.priceKg | currency: 'EUR'}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</vn-card>
|
||||
</section>
|
||||
</vn-horizontal>
|
||||
</vn-data-viewer>
|
||||
<vn-order-prices-popover
|
||||
vn-id="prices-popover"
|
||||
order="$ctrl.order">
|
||||
</vn-order-prices-popover>
|
||||
<vn-item-descriptor-popover
|
||||
vn-id="item-descriptor"
|
||||
warehouse-fk="$ctrl.vnConfig.warehouseFk">
|
||||
</vn-item-descriptor-popover>
|
|
@ -1,12 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import Component from 'core/lib/component';
|
||||
import './style.scss';
|
||||
|
||||
ngModule.vnComponent('vnOrderCatalogView', {
|
||||
template: require('./index.html'),
|
||||
controller: Component,
|
||||
bindings: {
|
||||
order: '<',
|
||||
model: '<'
|
||||
}
|
||||
});
|
|
@ -1 +0,0 @@
|
|||
Order created: Orden creada
|
|
@ -1,50 +0,0 @@
|
|||
@import "variables";
|
||||
|
||||
vn-order-catalog {
|
||||
.catalog-header {
|
||||
border-bottom: $border-thin;
|
||||
padding: $spacing-md;
|
||||
align-items: center;
|
||||
|
||||
& > vn-one {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
|
||||
span {
|
||||
color: $color-font-secondary
|
||||
}
|
||||
}
|
||||
& > vn-auto {
|
||||
width: 448px;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
|
||||
& > * {
|
||||
padding-left: $spacing-md;
|
||||
}
|
||||
}
|
||||
}
|
||||
.catalog-list {
|
||||
padding-top: $spacing-sm;
|
||||
}
|
||||
.item-color-background {
|
||||
background: linear-gradient($color-bg-panel, $color-main);
|
||||
border-radius: 50%;
|
||||
margin-left: 140px;
|
||||
margin-top: 140px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
position: absolute;
|
||||
}
|
||||
.item-color {
|
||||
margin: auto;
|
||||
margin-top: 5px;
|
||||
border-radius: 50%;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
position: relative;
|
||||
}
|
||||
.alert {
|
||||
color: $color-alert;
|
||||
}
|
||||
}
|
|
@ -1,166 +0,0 @@
|
|||
<vn-crud-model
|
||||
url="ItemCategories"
|
||||
data="categories"
|
||||
auto-load="true">
|
||||
</vn-crud-model>
|
||||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="Orders/CatalogFilter"
|
||||
params="{orderFk: $ctrl.$params.id}"
|
||||
limit="50"
|
||||
data="$ctrl.items">
|
||||
</vn-crud-model>
|
||||
<vn-portal slot="topbar">
|
||||
<vn-searchbar vn-id="searchbar"
|
||||
auto-state="false"
|
||||
info="Search by item id or name"
|
||||
on-search="$ctrl.onSearch($params)">
|
||||
</vn-searchbar>
|
||||
</vn-portal>
|
||||
<vn-order-catalog-view
|
||||
model="model"
|
||||
order="$ctrl.order">
|
||||
</vn-order-catalog-view>
|
||||
<vn-side-menu side="right">
|
||||
<vn-horizontal class="item-category">
|
||||
<vn-autocomplete vn-id="category"
|
||||
data="categories"
|
||||
ng-model="$ctrl.categoryId"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
label="Category">
|
||||
</vn-autocomplete>
|
||||
<vn-one ng-repeat="category in categories">
|
||||
<vn-icon
|
||||
ng-class="{'active': $ctrl.categoryId == category.id}"
|
||||
icon="{{::category.icon}}"
|
||||
vn-tooltip="{{::category.name}}"
|
||||
ng-click="$ctrl.changeCategory(category.id)">
|
||||
</vn-icon>
|
||||
</vn-one>
|
||||
</vn-horizontal>
|
||||
<vn-vertical class="input">
|
||||
<vn-autocomplete vn-id="type"
|
||||
data="$ctrl.itemTypes"
|
||||
ng-model="$ctrl.typeId"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
label="Type"
|
||||
fields="['categoryFk']"
|
||||
include="'category'">
|
||||
<tpl-item>
|
||||
<div>{{name}}</div>
|
||||
<div class="text-caption text-secondary">
|
||||
{{categoryName}}
|
||||
</div>
|
||||
</tpl-item>
|
||||
</vn-autocomplete>
|
||||
</vn-vertical>
|
||||
<vn-vertical class="input vn-pt-md">
|
||||
<vn-autocomplete
|
||||
vn-id="field"
|
||||
data="$ctrl.orderFields"
|
||||
ng-model="$ctrl.orderField"
|
||||
selection="$ctrl.orderSelection"
|
||||
translate-fields="['name']"
|
||||
order="priority DESC"
|
||||
show-field="name"
|
||||
value-field="field"
|
||||
label="Order by"
|
||||
disabled="!model.data">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete
|
||||
data="$ctrl.orderWays"
|
||||
ng-model="$ctrl.orderWay"
|
||||
translate-fields="['name']"
|
||||
show-field="name"
|
||||
value-field="way"
|
||||
label="Order"
|
||||
disabled="!model.data">
|
||||
</vn-autocomplete>
|
||||
<div ng-if="false && model.moreRows">
|
||||
<span translate>More than</span> {{model.limit}} <span translate>results</span>
|
||||
</div>
|
||||
</vn-vertical>
|
||||
<vn-vertical class="input vn-pt-md">
|
||||
<vn-textfield vn-one
|
||||
vn-id="search"
|
||||
ng-keyUp="$ctrl.onSearchByTag($event)"
|
||||
label="Search tag">
|
||||
<prepend>
|
||||
<vn-icon icon="search"></vn-icon>
|
||||
</prepend>
|
||||
<append>
|
||||
<vn-icon
|
||||
icon="keyboard_arrow_down"
|
||||
ng-click="$ctrl.openPanel($event)"
|
||||
style="cursor: pointer;">
|
||||
</vn-icon>
|
||||
</append>
|
||||
</vn-textfield>
|
||||
</vn-vertical>
|
||||
<vn-popover
|
||||
vn-id="popover"
|
||||
on-close="$ctrl.onPopoverClose()">
|
||||
<vn-order-catalog-search-panel
|
||||
on-submit="$ctrl.onPanelSubmit($filter)"
|
||||
parent-popover="popover"
|
||||
result-tags="$ctrl.resultTags">
|
||||
</vn-order-catalog-search-panel>
|
||||
</vn-popover>
|
||||
<div class="chips">
|
||||
<vn-chip
|
||||
ng-if="$ctrl.itemId"
|
||||
removable="true"
|
||||
vn-tooltip="Item id"
|
||||
on-remove="$ctrl.removeItemId()"
|
||||
class="colored">
|
||||
<span>Id: {{$ctrl.itemId}}</span>
|
||||
</vn-chip>
|
||||
<vn-chip
|
||||
ng-if="$ctrl.itemName"
|
||||
removable="true"
|
||||
vn-tooltip="Item"
|
||||
on-remove="$ctrl.removeItemName()"
|
||||
class="colored">
|
||||
<div>
|
||||
<span>
|
||||
<span translate>Name</span>:
|
||||
</span>
|
||||
<span>{{$ctrl.itemName}}</span>
|
||||
</div>
|
||||
</vn-chip>
|
||||
<vn-chip
|
||||
ng-if="category.selection"
|
||||
removable="true"
|
||||
vn-tooltip="Category"
|
||||
on-remove="$ctrl.categoryId = null"
|
||||
class="colored">
|
||||
<span translate>{{category.selection.name}}</span>
|
||||
</vn-chip>
|
||||
<vn-chip
|
||||
ng-if="type.selection"
|
||||
removable="true"
|
||||
vn-tooltip="Type"
|
||||
on-remove="$ctrl.typeId = null"
|
||||
class="colored">
|
||||
<span translate>{{type.selection.name}}</span>
|
||||
</vn-chip>
|
||||
<vn-chip
|
||||
ng-repeat="tagGroup in $ctrl.tagGroups"
|
||||
removable="true"
|
||||
on-remove="$ctrl.remove($index)"
|
||||
vn-tooltip="{{::$ctrl.formatTooltip(tagGroup)}}"
|
||||
class="colored">
|
||||
<div>
|
||||
<span ng-if="::tagGroup.tagFk">
|
||||
<span translate>{{::tagGroup.tagSelection.name}}</span>:
|
||||
</span>
|
||||
<span ng-repeat="tagValue in tagGroup.values">
|
||||
<span ng-if="$index > 0">,</span>
|
||||
<span>"{{::tagValue.value}}"</span>
|
||||
</span>
|
||||
</div>
|
||||
</vn-chip>
|
||||
</div>
|
||||
</vn-side-menu>
|
|
@ -1,377 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import Section from 'salix/components/section';
|
||||
import './style.scss';
|
||||
|
||||
class Controller extends Section {
|
||||
constructor($element, $) {
|
||||
super($element, $);
|
||||
this.itemTypes = [];
|
||||
this._tagGroups = [];
|
||||
|
||||
// Static autocomplete data
|
||||
this.orderWays = [
|
||||
{way: 'ASC', name: 'Ascendant'},
|
||||
{way: 'DESC', name: 'Descendant'},
|
||||
];
|
||||
this.defaultOrderFields = [
|
||||
{field: 'relevancy DESC, name', name: 'Relevancy', priority: 999},
|
||||
{field: 'showOrder, price', name: 'Color and price', priority: 999},
|
||||
{field: 'name', name: 'Name', priority: 999},
|
||||
{field: 'price', name: 'Price', priority: 999}
|
||||
];
|
||||
this.orderFields = [].concat(this.defaultOrderFields);
|
||||
this._orderWay = this.orderWays[0].way;
|
||||
this.orderField = this.orderFields[0].field;
|
||||
}
|
||||
|
||||
$onChanges() {
|
||||
this.getData().then(() => {
|
||||
if (this.order && this.order.isConfirmed)
|
||||
this.$state.go('order.card.line');
|
||||
});
|
||||
}
|
||||
|
||||
getData() {
|
||||
return this.$http.get(`Orders/${this.$params.id}`)
|
||||
.then(res => this.order = res.data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills order autocomplete with tags
|
||||
* obtained from last filtered
|
||||
*/
|
||||
get order() {
|
||||
return this._order;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets filter values from state params
|
||||
*
|
||||
* @param {Object} value - Order data
|
||||
*/
|
||||
set order(value) {
|
||||
this._order = value;
|
||||
|
||||
if (!value) return;
|
||||
|
||||
this.$.$applyAsync(() => {
|
||||
if (this.$params.categoryId)
|
||||
this.categoryId = parseInt(this.$params.categoryId);
|
||||
|
||||
if (this.$params.typeId)
|
||||
this.typeId = parseInt(this.$params.typeId);
|
||||
|
||||
if (this.$params.tagGroups)
|
||||
this.tagGroups = JSON.parse(this.$params.tagGroups);
|
||||
});
|
||||
}
|
||||
|
||||
get items() {
|
||||
return this._items;
|
||||
}
|
||||
|
||||
set items(value) {
|
||||
this._items = value;
|
||||
|
||||
if (!value) return;
|
||||
|
||||
this.fetchResultTags(value);
|
||||
this.buildOrderFilter();
|
||||
}
|
||||
|
||||
get categoryId() {
|
||||
return this._categoryId;
|
||||
}
|
||||
|
||||
set categoryId(value = null) {
|
||||
this._categoryId = value;
|
||||
this.itemTypes = [];
|
||||
this.typeId = null;
|
||||
|
||||
this.updateStateParams();
|
||||
|
||||
if (this.tagGroups.length > 0)
|
||||
this.applyFilters();
|
||||
|
||||
if (value)
|
||||
this.updateItemTypes();
|
||||
}
|
||||
|
||||
changeCategory(id) {
|
||||
if (this._categoryId == id) id = null;
|
||||
this.categoryId = id;
|
||||
}
|
||||
|
||||
get typeId() {
|
||||
return this._typeId;
|
||||
}
|
||||
|
||||
set typeId(value) {
|
||||
this._typeId = value;
|
||||
|
||||
this.updateStateParams();
|
||||
|
||||
if (value || this.tagGroups.length > 0)
|
||||
this.applyFilters();
|
||||
}
|
||||
|
||||
get tagGroups() {
|
||||
return this._tagGroups;
|
||||
}
|
||||
|
||||
set tagGroups(value) {
|
||||
this._tagGroups = value;
|
||||
|
||||
this.updateStateParams();
|
||||
|
||||
if (value.length)
|
||||
this.applyFilters();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get order way ASC/DESC
|
||||
*/
|
||||
get orderWay() {
|
||||
return this._orderWay;
|
||||
}
|
||||
|
||||
set orderWay(value) {
|
||||
this._orderWay = value;
|
||||
if (value) this.applyOrder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the order way selection
|
||||
*/
|
||||
get orderSelection() {
|
||||
return this._orderSelection;
|
||||
}
|
||||
|
||||
set orderSelection(value) {
|
||||
this._orderSelection = value;
|
||||
|
||||
if (value) this.applyOrder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply order to model
|
||||
*/
|
||||
applyOrder() {
|
||||
if (this.typeId || this.tagGroups.length > 0 || this.itemName)
|
||||
this.$.model.addFilter(null, {orderBy: this.getOrderBy()});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns order param
|
||||
*
|
||||
* @return {Object} - Order param
|
||||
*/
|
||||
getOrderBy() {
|
||||
const isTag = !!(this.orderSelection && this.orderSelection.isTag);
|
||||
return {
|
||||
field: this.orderField,
|
||||
way: this.orderWay,
|
||||
isTag: isTag
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes item type dropdown data
|
||||
*/
|
||||
updateItemTypes() {
|
||||
let params = {
|
||||
itemCategoryId: this.categoryId
|
||||
};
|
||||
|
||||
const query = `Orders/${this.order.id}/getItemTypeAvailable`;
|
||||
this.$http.get(query, {params}).then(res =>
|
||||
this.itemTypes = res.data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search by tag value
|
||||
* @param {object} event
|
||||
*/
|
||||
onSearchByTag(event) {
|
||||
const value = this.$.search.value;
|
||||
if (event.key !== 'Enter' || !value) return;
|
||||
this.tagGroups.push({values: [{value: value}]});
|
||||
this.$.search.value = null;
|
||||
this.updateStateParams();
|
||||
this.applyFilters();
|
||||
}
|
||||
|
||||
remove(index) {
|
||||
this.tagGroups.splice(index, 1);
|
||||
this.updateStateParams();
|
||||
|
||||
if (this.tagGroups.length >= 0 || this.itemId || this.typeId)
|
||||
this.applyFilters();
|
||||
}
|
||||
|
||||
removeItemId() {
|
||||
this.itemId = null;
|
||||
this.$.searchbar.doSearch({}, 'bar');
|
||||
}
|
||||
|
||||
removeItemName() {
|
||||
this.itemName = null;
|
||||
this.$.searchbar.doSearch({}, 'bar');
|
||||
}
|
||||
|
||||
applyFilters(filter = {}) {
|
||||
let newParams = {};
|
||||
let newFilter = Object.assign({}, filter);
|
||||
const model = this.$.model;
|
||||
|
||||
if (this.categoryId)
|
||||
newFilter.categoryFk = this.categoryId;
|
||||
|
||||
if (this.typeId)
|
||||
newFilter.typeFk = this.typeId;
|
||||
|
||||
newParams = {
|
||||
orderFk: this.$params.id,
|
||||
orderBy: this.getOrderBy(),
|
||||
tagGroups: this.tagGroups,
|
||||
};
|
||||
|
||||
return model.applyFilter({where: newFilter}, newParams);
|
||||
}
|
||||
|
||||
openPanel(event) {
|
||||
if (event.defaultPrevented) return;
|
||||
event.preventDefault();
|
||||
|
||||
this.panelFilter = {};
|
||||
this.$.popover.show(this.$.search.element);
|
||||
}
|
||||
|
||||
onPanelSubmit(filter) {
|
||||
this.$.popover.hide();
|
||||
const values = filter.values;
|
||||
const nonEmptyValues = values.filter(tagValue => {
|
||||
return tagValue.value;
|
||||
});
|
||||
|
||||
filter.values = nonEmptyValues;
|
||||
|
||||
if (filter.tagFk && nonEmptyValues.length) {
|
||||
this.tagGroups.push(filter);
|
||||
this.updateStateParams();
|
||||
this.applyFilters();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates url state params from filter values
|
||||
*/
|
||||
updateStateParams() {
|
||||
const params = {};
|
||||
|
||||
params.categoryId = undefined;
|
||||
if (this.categoryId)
|
||||
params.categoryId = this.categoryId;
|
||||
|
||||
params.typeId = undefined;
|
||||
if (this.typeId)
|
||||
params.typeId = this.typeId;
|
||||
|
||||
params.tagGroups = undefined;
|
||||
if (this.tagGroups && this.tagGroups.length)
|
||||
params.tagGroups = JSON.stringify(this.sanitizedTagGroupParam());
|
||||
|
||||
this.$state.go(this.$state.current.name, params);
|
||||
}
|
||||
|
||||
sanitizedTagGroupParam() {
|
||||
const tagGroups = [];
|
||||
for (let tagGroup of this.tagGroups) {
|
||||
const tagParam = {values: []};
|
||||
|
||||
for (let tagValue of tagGroup.values)
|
||||
tagParam.values.push({value: tagValue.value});
|
||||
|
||||
if (tagGroup.tagFk)
|
||||
tagParam.tagFk = tagGroup.tagFk;
|
||||
|
||||
if (tagGroup.tagSelection) {
|
||||
tagParam.tagSelection = {
|
||||
name: tagGroup.tagSelection.name
|
||||
};
|
||||
}
|
||||
|
||||
tagGroups.push(tagParam);
|
||||
}
|
||||
|
||||
return tagGroups;
|
||||
}
|
||||
|
||||
fetchResultTags(items) {
|
||||
const resultTags = [];
|
||||
for (let item of items) {
|
||||
for (let itemTag of item.tags) {
|
||||
const alreadyAdded = resultTags.findIndex(tag => {
|
||||
return tag.tagFk == itemTag.tagFk;
|
||||
});
|
||||
|
||||
if (alreadyAdded == -1)
|
||||
resultTags.push({...itemTag, priority: 1});
|
||||
else
|
||||
resultTags[alreadyAdded].priority += 1;
|
||||
}
|
||||
}
|
||||
this.resultTags = resultTags;
|
||||
}
|
||||
|
||||
buildOrderFilter() {
|
||||
const filter = [].concat(this.defaultOrderFields);
|
||||
for (let tag of this.resultTags)
|
||||
filter.push({...tag, field: tag.id, isTag: true});
|
||||
|
||||
this.orderFields = filter;
|
||||
}
|
||||
|
||||
onSearch(params) {
|
||||
if (!params) return;
|
||||
|
||||
this.itemId = null;
|
||||
this.itemName = null;
|
||||
|
||||
if (params.search) {
|
||||
if (/^\d+$/.test(params.search)) {
|
||||
this.itemId = params.search;
|
||||
return this.applyFilters({
|
||||
'i.id': params.search
|
||||
});
|
||||
} else {
|
||||
this.itemName = params.search;
|
||||
return this.applyFilters({
|
||||
'i.name': {like: `%${params.search}%`}
|
||||
});
|
||||
}
|
||||
} else return this.applyFilters();
|
||||
}
|
||||
|
||||
formatTooltip(tagGroup) {
|
||||
const tagValues = tagGroup.values;
|
||||
|
||||
let title = '';
|
||||
if (tagGroup.tagFk) {
|
||||
const tagName = tagGroup.tagSelection.name;
|
||||
title += `${tagName}: `;
|
||||
}
|
||||
|
||||
for (let [i, tagValue] of tagValues.entries()) {
|
||||
if (i > 0) title += ', ';
|
||||
title += `"${tagValue.value}"`;
|
||||
}
|
||||
|
||||
return `${title}`;
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnOrderCatalog', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -1,386 +0,0 @@
|
|||
import './index.js';
|
||||
import crudModel from 'core/mocks/crud-model';
|
||||
|
||||
describe('Order', () => {
|
||||
describe('Component vnOrderCatalog', () => {
|
||||
let $scope;
|
||||
let $state;
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
|
||||
beforeEach(ngModule('order'));
|
||||
|
||||
beforeEach(inject(($componentController, _$state_, _$httpBackend_, $rootScope) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
$scope = $rootScope.$new();
|
||||
$scope.model = crudModel;
|
||||
$scope.search = {};
|
||||
$scope.itemId = {};
|
||||
$state = _$state_;
|
||||
$state.current.name = 'my.current.state';
|
||||
const $element = angular.element('<vn-order-catalog></vn-order-catalog>');
|
||||
controller = $componentController('vnOrderCatalog', {$element, $scope});
|
||||
controller._order = {id: 4};
|
||||
controller.$params = {
|
||||
categoryId: 1,
|
||||
typeId: 2,
|
||||
id: 4
|
||||
};
|
||||
}));
|
||||
|
||||
describe('getData()', () => {
|
||||
it(`should make a query an fetch the order data`, () => {
|
||||
controller._order = null;
|
||||
|
||||
$httpBackend.expect('GET', `Orders/4`).respond(200, {id: 4, isConfirmed: true});
|
||||
$httpBackend.expect('GET', `Orders/4/getItemTypeAvailable?itemCategoryId=1`).respond();
|
||||
controller.getData();
|
||||
$httpBackend.flush();
|
||||
|
||||
const order = controller.order;
|
||||
|
||||
expect(order.id).toEqual(4);
|
||||
expect(order.isConfirmed).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('order() setter', () => {
|
||||
it(`should call scope $applyAsync() method and apply filters from state params`, () => {
|
||||
$httpBackend.expect('GET', `Orders/4/getItemTypeAvailable?itemCategoryId=1`).respond();
|
||||
controller.order = {id: 4};
|
||||
|
||||
$scope.$apply();
|
||||
|
||||
expect(controller.categoryId).toEqual(1);
|
||||
expect(controller.typeId).toEqual(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('items() setter', () => {
|
||||
it(`should return an object with order params`, () => {
|
||||
jest.spyOn(controller, 'fetchResultTags');
|
||||
jest.spyOn(controller, 'buildOrderFilter');
|
||||
|
||||
const expectedResult = [{field: 'showOrder, price', name: 'Color and price', priority: 999}];
|
||||
const items = [{id: 1, name: 'My Item', tags: [
|
||||
{tagFk: 4, name: 'Length'},
|
||||
{tagFk: 5, name: 'Color'}
|
||||
]}];
|
||||
controller.items = items;
|
||||
|
||||
expect(controller.orderFields.length).toEqual(6);
|
||||
expect(controller.orderFields).toEqual(jasmine.arrayContaining(expectedResult));
|
||||
expect(controller.fetchResultTags).toHaveBeenCalledWith(items);
|
||||
expect(controller.buildOrderFilter).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('categoryId() setter', () => {
|
||||
it(`should set category property to null, call updateStateParams() method and not call applyFilters()`, () => {
|
||||
jest.spyOn(controller, 'updateStateParams');
|
||||
|
||||
controller.categoryId = null;
|
||||
|
||||
expect(controller.updateStateParams).toHaveBeenCalledWith();
|
||||
});
|
||||
|
||||
it(`should set category property and then call updateStateParams() and applyFilters() methods`, () => {
|
||||
jest.spyOn(controller, 'updateStateParams');
|
||||
|
||||
controller.categoryId = 2;
|
||||
|
||||
expect(controller.updateStateParams).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('changeCategory()', () => {
|
||||
it(`should set categoryId property to null if the new value equals to the old one`, () => {
|
||||
controller.categoryId = 2;
|
||||
controller.changeCategory(2);
|
||||
|
||||
expect(controller.categoryId).toBeNull();
|
||||
});
|
||||
|
||||
it(`should set categoryId property`, () => {
|
||||
controller.categoryId = 2;
|
||||
controller.changeCategory(1);
|
||||
|
||||
expect(controller.categoryId).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('typeId() setter', () => {
|
||||
it(`should set type property to null, call updateStateParams() method and not call applyFilters()`, () => {
|
||||
jest.spyOn(controller, 'updateStateParams');
|
||||
jest.spyOn(controller, 'applyFilters');
|
||||
|
||||
controller.typeId = null;
|
||||
|
||||
expect(controller.updateStateParams).toHaveBeenCalledWith();
|
||||
expect(controller.applyFilters).not.toHaveBeenCalledWith();
|
||||
});
|
||||
|
||||
it(`should set category property and then call updateStateParams() and applyFilters() methods`, () => {
|
||||
jest.spyOn(controller, 'updateStateParams');
|
||||
jest.spyOn(controller, 'applyFilters');
|
||||
|
||||
controller.typeId = 2;
|
||||
|
||||
expect(controller.updateStateParams).toHaveBeenCalledWith();
|
||||
expect(controller.applyFilters).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('tagGroups() setter', () => {
|
||||
it(`should set tagGroups property and then call updateStateParams() and applyFilters() methods`, () => {
|
||||
jest.spyOn(controller, 'updateStateParams');
|
||||
jest.spyOn(controller, 'applyFilters');
|
||||
|
||||
controller.tagGroups = [{tagFk: 11, values: [{value: 'Brown'}]}];
|
||||
|
||||
expect(controller.updateStateParams).toHaveBeenCalledWith();
|
||||
expect(controller.applyFilters).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('onSearchByTag()', () => {
|
||||
it(`should not add a new tag if the event key code doesn't equals to 'Enter'`, () => {
|
||||
jest.spyOn(controller, 'applyFilters');
|
||||
|
||||
controller.order = {id: 4};
|
||||
controller.$.search.value = 'Brown';
|
||||
controller.onSearchByTag({key: 'Tab'});
|
||||
|
||||
expect(controller.applyFilters).not.toHaveBeenCalledWith();
|
||||
});
|
||||
|
||||
it(`should add a new tag if the event key code equals to 'Enter' an then call applyFilters()`, () => {
|
||||
jest.spyOn(controller, 'applyFilters');
|
||||
|
||||
controller.order = {id: 4};
|
||||
controller.$.search.value = 'Brown';
|
||||
controller.onSearchByTag({key: 'Enter'});
|
||||
|
||||
expect(controller.applyFilters).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('onSearch()', () => {
|
||||
it(`should apply a filter by item id an then call the applyFilters method`, () => {
|
||||
jest.spyOn(controller, 'applyFilters');
|
||||
|
||||
const itemId = 1;
|
||||
controller.onSearch({search: itemId});
|
||||
|
||||
expect(controller.applyFilters).toHaveBeenCalledWith({
|
||||
'i.id': itemId
|
||||
});
|
||||
});
|
||||
|
||||
it(`should apply a filter by item name an then call the applyFilters method`, () => {
|
||||
jest.spyOn(controller, 'applyFilters');
|
||||
|
||||
const itemName = 'Bow';
|
||||
controller.onSearch({search: itemName});
|
||||
|
||||
expect(controller.applyFilters).toHaveBeenCalledWith({
|
||||
'i.name': {like: `%${itemName}%`}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('applyFilters()', () => {
|
||||
it(`should call model applyFilter() method with a new filter`, () => {
|
||||
jest.spyOn(controller.$.model, 'applyFilter');
|
||||
|
||||
controller._categoryId = 2;
|
||||
controller._typeId = 4;
|
||||
|
||||
controller.applyFilters();
|
||||
|
||||
expect(controller.$.model.applyFilter).toHaveBeenCalledWith(
|
||||
{where: {categoryFk: 2, typeFk: 4}},
|
||||
{orderFk: 4, orderBy: controller.getOrderBy(), tagGroups: []});
|
||||
});
|
||||
});
|
||||
|
||||
describe('remove()', () => {
|
||||
it(`should remove a tag from tags property`, () => {
|
||||
jest.spyOn(controller, 'applyFilters');
|
||||
|
||||
controller.tagGroups = [
|
||||
{tagFk: 1, values: [{value: 'Brown'}]},
|
||||
{tagFk: 67, values: [{value: 'Concussion'}]}
|
||||
];
|
||||
controller.remove(0);
|
||||
|
||||
const firstTag = controller.tagGroups[0];
|
||||
|
||||
expect(controller.tagGroups.length).toEqual(1);
|
||||
expect(firstTag.tagFk).toEqual(67);
|
||||
expect(controller.applyFilters).toHaveBeenCalledWith();
|
||||
});
|
||||
|
||||
it(`should remove a tag from tags property and call applyFilters() if there's no more tags`, () => {
|
||||
jest.spyOn(controller, 'applyFilters');
|
||||
|
||||
controller._categoryId = 1;
|
||||
controller._typeId = 1;
|
||||
controller.tagGroups = [{tagFk: 1, values: [{value: 'Blue'}]}];
|
||||
controller.remove(0);
|
||||
|
||||
expect(controller.tagGroups.length).toEqual(0);
|
||||
expect(controller.applyFilters).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('updateStateParams()', () => {
|
||||
it(`should call state go() method passing category and type state params`, () => {
|
||||
jest.spyOn(controller.$state, 'go');
|
||||
|
||||
controller._categoryId = 2;
|
||||
controller._typeId = 4;
|
||||
controller._tagGroups = [
|
||||
{tagFk: 67, values: [{value: 'Concussion'}], tagSelection: {name: 'Category'}}
|
||||
];
|
||||
const tagGroups = JSON.stringify([
|
||||
{values: [{value: 'Concussion'}], tagFk: 67, tagSelection: {name: 'Category'}}
|
||||
]);
|
||||
const expectedResult = {categoryId: 2, typeId: 4, tagGroups: tagGroups};
|
||||
controller.updateStateParams();
|
||||
|
||||
expect(controller.$state.go).toHaveBeenCalledWith('my.current.state', expectedResult);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getOrderBy()', () => {
|
||||
it(`should return an object with order params`, () => {
|
||||
controller.orderField = 'relevancy DESC, name';
|
||||
controller.orderWay = 'DESC';
|
||||
let expectedResult = {
|
||||
field: 'relevancy DESC, name',
|
||||
way: 'DESC',
|
||||
isTag: false
|
||||
};
|
||||
let result = controller.getOrderBy();
|
||||
|
||||
expect(result).toEqual(expectedResult);
|
||||
});
|
||||
});
|
||||
|
||||
describe('applyOrder()', () => {
|
||||
it(`should apply order param to model calling getOrderBy()`, () => {
|
||||
jest.spyOn(controller, 'getOrderBy');
|
||||
jest.spyOn(controller.$.model, 'addFilter');
|
||||
|
||||
controller.field = 'relevancy DESC, name';
|
||||
controller.way = 'ASC';
|
||||
controller._categoryId = 1;
|
||||
controller._typeId = 1;
|
||||
let expectedOrder = {orderBy: controller.getOrderBy()};
|
||||
|
||||
controller.applyOrder();
|
||||
|
||||
expect(controller.getOrderBy).toHaveBeenCalledWith();
|
||||
expect(controller.$.model.addFilter).toHaveBeenCalledWith(null, expectedOrder);
|
||||
});
|
||||
});
|
||||
|
||||
describe('fetchResultTags()', () => {
|
||||
it(`should create an array of non repeated tags then set the resultTags property`, () => {
|
||||
const items = [
|
||||
{
|
||||
id: 1, name: 'My Item 1', tags: [
|
||||
{tagFk: 4, name: 'Length', value: 1},
|
||||
{tagFk: 5, name: 'Color', value: 'red'}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 2, name: 'My Item 2', tags: [
|
||||
{tagFk: 4, name: 'Length', value: 1},
|
||||
{tagFk: 5, name: 'Color', value: 'blue'}
|
||||
]
|
||||
}];
|
||||
controller.fetchResultTags(items);
|
||||
|
||||
expect(controller.resultTags.length).toEqual(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('buildOrderFilter()', () => {
|
||||
it(`should create an array of non repeated tags plus default filters and then set the orderFields property`, () => {
|
||||
const items = [
|
||||
{
|
||||
id: 1, name: 'My Item 1', tags: [
|
||||
{tagFk: 4, name: 'Length'},
|
||||
{tagFk: 5, name: 'Color'}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 2, name: 'My Item 2', tags: [
|
||||
{tagFk: 5, name: 'Color'},
|
||||
{tagFk: 6, name: 'Relevancy'}
|
||||
]
|
||||
}];
|
||||
|
||||
controller.fetchResultTags(items);
|
||||
controller.buildOrderFilter();
|
||||
|
||||
expect(controller.orderFields.length).toEqual(7);
|
||||
});
|
||||
});
|
||||
|
||||
describe('formatTooltip()', () => {
|
||||
it(`should return a formatted text with the tag name and values`, () => {
|
||||
const tagGroup = {
|
||||
values: [{value: 'Silver'}, {value: 'Brown'}],
|
||||
tagFk: 1,
|
||||
tagSelection: {
|
||||
name: 'Color'
|
||||
}
|
||||
};
|
||||
|
||||
const result = controller.formatTooltip(tagGroup);
|
||||
|
||||
expect(result).toEqual(`Color: "Silver", "Brown"`);
|
||||
});
|
||||
|
||||
it(`should return a formatted text with the tag value`, () => {
|
||||
const tagGroup = {
|
||||
values: [{value: 'Silver'}]
|
||||
};
|
||||
|
||||
const result = controller.formatTooltip(tagGroup);
|
||||
|
||||
expect(result).toEqual(`"Silver"`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('sanitizedTagGroupParam()', () => {
|
||||
it(`should return an array of tags`, () => {
|
||||
const dirtyTagGroups = [{
|
||||
values: [{value: 'Silver'}, {value: 'Brown'}],
|
||||
tagFk: 1,
|
||||
tagSelection: {
|
||||
name: 'Color',
|
||||
$orgRow: {name: 'Color'}
|
||||
},
|
||||
$orgIndex: 1
|
||||
}];
|
||||
controller.tagGroups = dirtyTagGroups;
|
||||
|
||||
const expectedResult = [{
|
||||
values: [{value: 'Silver'}, {value: 'Brown'}],
|
||||
tagFk: 1,
|
||||
tagSelection: {
|
||||
name: 'Color'
|
||||
}
|
||||
}];
|
||||
const result = controller.sanitizedTagGroupParam();
|
||||
|
||||
expect(result).toEqual(expect.objectContaining(expectedResult));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
Name: Nombre
|
||||
Search by item id or name: Buscar por id de artículo o nombre
|
||||
OR: O
|
|
@ -1,54 +0,0 @@
|
|||
@import "variables";
|
||||
|
||||
vn-order-catalog vn-side-menu div {
|
||||
& > .input {
|
||||
padding-left: $spacing-md;
|
||||
padding-right: $spacing-md;
|
||||
border-color: $color-spacer;
|
||||
border-bottom: $border-thin;
|
||||
}
|
||||
.item-category {
|
||||
padding: $spacing-sm;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
flex-wrap: wrap;
|
||||
|
||||
vn-autocomplete[vn-id="category"] {
|
||||
display: none
|
||||
}
|
||||
|
||||
& > vn-one {
|
||||
padding: $spacing-sm;
|
||||
min-width: 33.33%;
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
|
||||
& > vn-icon {
|
||||
padding: $spacing-sm;
|
||||
background-color: $color-font-secondary;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
|
||||
&.active {
|
||||
background-color: $color-main;
|
||||
color: #FFF
|
||||
}
|
||||
& > i:before {
|
||||
font-size: 2.6rem;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.chips {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding: $spacing-md;
|
||||
overflow: hidden;
|
||||
max-width: 100%;
|
||||
}
|
||||
vn-autocomplete[vn-id="type"] .list {
|
||||
max-height: 320px
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
<vn-autocomplete
|
||||
vn-focus
|
||||
vn-id="client"
|
||||
url="Clients"
|
||||
label="Client"
|
||||
search-function="{or: [{id: $search}, {name: {like: '%'+ $search +'%'}}]}"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
ng-model="$ctrl.clientFk"
|
||||
vn-name="client"
|
||||
order="id">
|
||||
<tpl-item>{{id}}: {{name}}</tpl-item>
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete
|
||||
disabled="!$ctrl.clientFk"
|
||||
url="{{ $ctrl.clientFk ? 'Clients/'+ $ctrl.clientFk +'/addresses' : null }}"
|
||||
fields="['nickname', 'street', 'city']"
|
||||
ng-model="$ctrl.addressFk"
|
||||
vn-name="address"
|
||||
show-field="nickname"
|
||||
value-field="id"
|
||||
label="Address">
|
||||
<tpl-item>{{nickname}}: {{street}}, {{city}}</tpl-item>
|
||||
</vn-autocomplete>
|
||||
<vn-date-picker
|
||||
label="Landed"
|
||||
ng-model="$ctrl.landed"
|
||||
vn-name="landed">
|
||||
</vn-date-picker>
|
||||
<vn-autocomplete
|
||||
disabled="!$ctrl.clientFk || !$ctrl.landed"
|
||||
data="$ctrl._availableAgencies"
|
||||
label="Agency"
|
||||
show-field="agencyMode"
|
||||
value-field="agencyModeFk"
|
||||
ng-model="$ctrl.order.agencyModeFk"
|
||||
vn-name="agencyMode">
|
||||
</vn-autocomplete>
|
|
@ -1,114 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import Component from 'core/lib/component';
|
||||
|
||||
class Controller extends Component {
|
||||
constructor($element, $) {
|
||||
super($element, $);
|
||||
this.order = {};
|
||||
this.clientFk = this.$params.clientFk;
|
||||
}
|
||||
|
||||
$onInit() {
|
||||
if (this.$params && this.$params.clientFk)
|
||||
this.clientFk = this.$params.clientFk;
|
||||
}
|
||||
|
||||
set order(value) {
|
||||
if (value)
|
||||
this._order = value;
|
||||
}
|
||||
|
||||
get order() {
|
||||
return this._order;
|
||||
}
|
||||
|
||||
set clientFk(value) {
|
||||
this.order.clientFk = value;
|
||||
|
||||
if (value) {
|
||||
let filter = {
|
||||
include: {
|
||||
relation: 'defaultAddress',
|
||||
scope: {
|
||||
fields: 'id'
|
||||
}
|
||||
},
|
||||
where: {id: value}
|
||||
};
|
||||
filter = encodeURIComponent(JSON.stringify(filter));
|
||||
let query = `Clients?filter=${filter}`;
|
||||
this.$http.get(query).then(res => {
|
||||
if (res.data) {
|
||||
let client = res.data[0];
|
||||
let defaultAddress = client.defaultAddress;
|
||||
this.addressFk = defaultAddress.id;
|
||||
}
|
||||
});
|
||||
} else
|
||||
this.addressFk = null;
|
||||
}
|
||||
|
||||
get clientFk() {
|
||||
return this.order.clientFk;
|
||||
}
|
||||
|
||||
set addressFk(value) {
|
||||
this.order.addressFk = value;
|
||||
this.getAvailableAgencies();
|
||||
}
|
||||
|
||||
get addressFk() {
|
||||
return this.order.addressFk;
|
||||
}
|
||||
|
||||
set landed(value) {
|
||||
this.order.landed = value;
|
||||
this.getAvailableAgencies();
|
||||
}
|
||||
|
||||
get landed() {
|
||||
return this.order.landed;
|
||||
}
|
||||
|
||||
get warehouseFk() {
|
||||
return this.order.warehouseFk;
|
||||
}
|
||||
|
||||
getAvailableAgencies() {
|
||||
let order = this.order;
|
||||
order.agencyModeFk = null;
|
||||
|
||||
let params = {
|
||||
addressFk: order.addressFk,
|
||||
landed: order.landed
|
||||
};
|
||||
if (params.landed && params.addressFk) {
|
||||
this.$http.get(`Agencies/landsThatDay`, {params})
|
||||
.then(res => this._availableAgencies = res.data);
|
||||
}
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
this.createOrder();
|
||||
}
|
||||
|
||||
createOrder() {
|
||||
let params = {
|
||||
landed: this.order.landed,
|
||||
addressId: this.order.addressFk,
|
||||
agencyModeId: this.order.agencyModeFk
|
||||
};
|
||||
this.$http.post(`Orders/new`, params).then(res => {
|
||||
this.vnApp.showSuccess(this.$t('Data saved!'));
|
||||
this.$state.go('order.card.catalog', {id: res.data});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnOrderCreateCard', {
|
||||
template: require('./card.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
order: '<?'
|
||||
}
|
||||
});
|
|
@ -1,104 +0,0 @@
|
|||
import './card.js';
|
||||
|
||||
describe('Order', () => {
|
||||
describe('Component vnOrderCreateCard', () => {
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
let $scope;
|
||||
|
||||
beforeEach(ngModule('order'));
|
||||
|
||||
beforeEach(inject(($componentController, _$httpBackend_, _vnApp_, $rootScope) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
$scope = $rootScope.$new();
|
||||
const $element = angular.element('<vn-order-create-card></vn-order-create-card>');
|
||||
controller = $componentController('vnOrderCreateCard', {$element, $scope});
|
||||
controller.item = {id: 3};
|
||||
}));
|
||||
|
||||
describe('set order', () => {
|
||||
it(`should set order if the value given is not null`, () => {
|
||||
controller.order = 1;
|
||||
|
||||
expect(controller.order).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('set clientFk', () => {
|
||||
it(`should set addressFk to null and clientFk to a value and set addressFk to a value given`, () => {
|
||||
let filter = {
|
||||
include: {
|
||||
relation: 'defaultAddress',
|
||||
scope: {
|
||||
fields: 'id'
|
||||
}
|
||||
},
|
||||
where: {id: 2}
|
||||
};
|
||||
filter = encodeURIComponent(JSON.stringify(filter));
|
||||
let response = [
|
||||
{
|
||||
defaultAddress: {id: 1}
|
||||
}
|
||||
];
|
||||
$httpBackend.whenGET(`Clients?filter=${filter}`).respond(response);
|
||||
$httpBackend.expectGET(`Clients?filter=${filter}`);
|
||||
|
||||
controller.clientFk = 2;
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.clientFk).toEqual(2);
|
||||
expect(controller.order.addressFk).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('set addressFk', () => {
|
||||
it(`should set agencyModeFk property to null and addressFk to a value`, () => {
|
||||
controller.addressFk = 1101;
|
||||
|
||||
expect(controller.addressFk).toEqual(1101);
|
||||
expect(controller.order.agencyModeFk).toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getAvailableAgencies()', () => {
|
||||
it(`should make a query if landed and addressFk exists`, () => {
|
||||
controller.order.addressFk = 1101;
|
||||
controller.order.landed = 1101;
|
||||
|
||||
$httpBackend.whenRoute('GET', 'Agencies/landsThatDay')
|
||||
.respond({data: 1});
|
||||
|
||||
controller.getAvailableAgencies();
|
||||
$httpBackend.flush();
|
||||
});
|
||||
});
|
||||
|
||||
describe('onSubmit()', () => {
|
||||
it(`should call createOrder()`, () => {
|
||||
jest.spyOn(controller, 'createOrder');
|
||||
controller.onSubmit();
|
||||
|
||||
expect(controller.createOrder).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('createOrder()', () => {
|
||||
it(`should make a query, call vnApp.showSuccess and $state.go if the response is defined`, () => {
|
||||
controller.order.landed = 1101;
|
||||
controller.order.addressFk = 1101;
|
||||
controller.order.agencyModeFk = 1101;
|
||||
|
||||
jest.spyOn(controller.vnApp, 'showSuccess');
|
||||
jest.spyOn(controller.$state, 'go');
|
||||
$httpBackend.expect('POST', 'Orders/new', {landed: 1101, addressId: 1101, agencyModeId: 1101}).respond(200, 1);
|
||||
controller.createOrder();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
|
||||
expect(controller.$state.go).toHaveBeenCalledWith('order.card.catalog', {id: 1});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<div class="vn-w-md">
|
||||
<vn-card class="vn-pa-lg">
|
||||
<vn-order-create-card vn-id="card" on-save=""></vn-order-create-card>
|
||||
</vn-card>
|
||||
<vn-button-bar>
|
||||
<vn-submit
|
||||
ng-click="$ctrl.onSubmit()"
|
||||
label="Create">
|
||||
</vn-submit>
|
||||
<vn-button
|
||||
class="cancel"
|
||||
label="Cancel"
|
||||
ui-sref="order.index">
|
||||
</vn-button>
|
||||
</vn-button-bar>
|
||||
</div>
|
|
@ -1,14 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import Section from 'salix/components/section';
|
||||
|
||||
class Controller extends Section {
|
||||
async onSubmit() {
|
||||
let newOrderID = await this.$.card.createOrder();
|
||||
this.$state.go('order.card.summary', {id: newOrderID});
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnOrderCreate', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -1,34 +0,0 @@
|
|||
import './index.js';
|
||||
|
||||
describe('Order', () => {
|
||||
describe('Component vnOrderCreate', () => {
|
||||
let $scope;
|
||||
let controller;
|
||||
|
||||
beforeEach(ngModule('order'));
|
||||
|
||||
beforeEach(inject(($componentController, $rootScope) => {
|
||||
$scope = $rootScope.$new();
|
||||
$scope.card = {createOrder: () => {}};
|
||||
const $element = angular.element('<vn-order-create></vn-order-create>');
|
||||
controller = $componentController('vnOrderCreate', {$element, $scope});
|
||||
}));
|
||||
|
||||
describe('onSubmit()', () => {
|
||||
it(`should call createOrder()`, () => {
|
||||
jest.spyOn(controller.$.card, 'createOrder');
|
||||
controller.onSubmit();
|
||||
|
||||
expect(controller.$.card.createOrder).toHaveBeenCalledWith();
|
||||
});
|
||||
|
||||
it(`should call go()`, async() => {
|
||||
jest.spyOn(controller.$state, 'go');
|
||||
await controller.onSubmit();
|
||||
|
||||
expect(controller.$state.go).toHaveBeenCalledWith('order.card.summary', {id: undefined});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
You can't create an order for a frozen client: No puedes crear una orden a un cliente congelado
|
||||
You can't create an order for an inactive client: No puedes crear una orden a un cliente inactivo
|
||||
You can't create an order for a client that doesn't has tax data verified:
|
||||
No puedes crear una orden a un cliente cuyos datos fiscales no han sido verificados
|
||||
You can't create an order for a client that has a debt: No puedes crear una orden a un cliente que tiene deuda
|
||||
New order: Nueva orden
|
|
@ -1,78 +0,0 @@
|
|||
<vn-descriptor-content
|
||||
module="order"
|
||||
description="$ctrl.order.client.name"
|
||||
summary="$ctrl.$.summary">
|
||||
<slot-menu>
|
||||
<vn-item
|
||||
ng-click="deleteOrderConfirmation.show()"
|
||||
translate>
|
||||
Delete order
|
||||
</vn-item>
|
||||
</slot-menu>
|
||||
<slot-body>
|
||||
<div class="attributes">
|
||||
<vn-label-value
|
||||
label="State"
|
||||
value="{{$ctrl.$t($ctrl.order.isConfirmed ? 'Confirmed' : 'Not confirmed')}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value
|
||||
label="Sales person">
|
||||
<span
|
||||
ng-click="workerDescriptor.show($event, $ctrl.order.client.salesPersonFk)"
|
||||
class="link">
|
||||
{{$ctrl.order.client.salesPersonUser.name}}
|
||||
</span>
|
||||
</vn-label-value>
|
||||
<vn-label-value
|
||||
label="Landed"
|
||||
value="{{$ctrl.order.landed | date: 'dd/MM/yyyy' }}">
|
||||
</vn-label-value>
|
||||
<vn-label-value
|
||||
label="Agency"
|
||||
value="{{$ctrl.order.agencyMode.name}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value
|
||||
label="Alias"
|
||||
value="{{$ctrl.order.address.nickname}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value
|
||||
label="Items"
|
||||
value="{{$ctrl.order.rows.length || 0}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value
|
||||
label="Total"
|
||||
value="{{$ctrl.order.total | currency: 'EUR': 2}}">
|
||||
</vn-label-value>
|
||||
</div>
|
||||
<div class="quicklinks">
|
||||
<div ng-transclude="btnOne">
|
||||
<vn-quick-link
|
||||
tooltip="Order ticket list"
|
||||
state="['ticket.index', {q: $ctrl.ticketFilter}]"
|
||||
icon="icon-ticket">
|
||||
</vn-quick-link>
|
||||
</div>
|
||||
<div ng-transclude="btnTwo">
|
||||
<vn-quick-link
|
||||
tooltip="Client card"
|
||||
state="['client.card.summary', {id: $ctrl.order.clientFk}]"
|
||||
icon="person">
|
||||
</vn-quick-link>
|
||||
</div>
|
||||
<div ng-transclude="btnThree">
|
||||
</div>
|
||||
</div>
|
||||
</slot-body>
|
||||
</vn-descriptor-content>
|
||||
<vn-confirm
|
||||
vn-id="deleteOrderConfirmation"
|
||||
on-accept="$ctrl.deleteOrder()"
|
||||
message="You are going to delete this order"
|
||||
question="continue anyway?">
|
||||
</vn-confirm>
|
||||
<vn-worker-descriptor-popover
|
||||
vn-id="workerDescriptor">
|
||||
</vn-worker-descriptor-popover>
|
||||
<vn-popup vn-id="summary">
|
||||
<vn-order-summary order="$ctrl.order"></vn-order-summary>
|
||||
</vn-popup>
|
|
@ -1,32 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
import Descriptor from 'salix/components/descriptor';
|
||||
|
||||
class Controller extends Descriptor {
|
||||
get order() {
|
||||
return this.entity;
|
||||
}
|
||||
|
||||
set order(value) {
|
||||
this.entity = value;
|
||||
}
|
||||
|
||||
get ticketFilter() {
|
||||
return JSON.stringify({orderFk: this.id});
|
||||
}
|
||||
|
||||
deleteOrder() {
|
||||
return this.$http.delete(`Orders/${this.id}`)
|
||||
.then(() => {
|
||||
this.$state.go('order.index');
|
||||
this.vnApp.showSuccess(this.$t('Order deleted'));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnOrderDescriptor', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
order: '<'
|
||||
}
|
||||
});
|
|
@ -1,29 +0,0 @@
|
|||
import './index.js';
|
||||
|
||||
describe('Order Component vnOrderDescriptor', () => {
|
||||
let $httpBackend;
|
||||
let controller;
|
||||
const order = {id: 1};
|
||||
|
||||
beforeEach(ngModule('order'));
|
||||
|
||||
beforeEach(inject(($componentController, _$httpBackend_) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
controller = $componentController('vnOrderDescriptor', {$element: null}, {order});
|
||||
}));
|
||||
|
||||
describe('deleteOrder()', () => {
|
||||
it(`should perform a DELETE query`, () => {
|
||||
jest.spyOn(controller.vnApp, 'showSuccess');
|
||||
jest.spyOn(controller.$state, 'go');
|
||||
|
||||
$httpBackend.expectDELETE(`Orders/${order.id}`).respond();
|
||||
controller.deleteOrder();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
|
||||
expect(controller.$state.go).toHaveBeenCalledWith('order.index');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue