Merge branch 'dev' into 7646-deleteColumnsProductionConfig
gitea/salix/pipeline/pr-dev This commit looks good Details

This commit is contained in:
Guillermo Bonet 2024-08-12 06:04:06 +00:00
commit 8655ca0a21
179 changed files with 2280 additions and 8649 deletions

View File

@ -1,3 +1,61 @@
# Version 24.32 - 2024-08-06
### Added 🆕
- chore: refs #7197 add supplierActivityFk filter by:jorgep
- feat checkExpeditionPrintOut refs #7751 by:sergiodt
- feat(defaulter_filter): add department by:alexm
- feat: redirect to lilium page not found by:alexm
- feat: refactor buyUltimate refs #7736 by:Carlos Andrés
- feat: refs #6403 add delete by:pablone
- feat: refs #7126 Added manaClaim calc by:guillermo
- feat: refs #7126 Refactor and added columns in bs.waste table & proc by:guillermo
- feat: refs #7197 filter by correcting by:jorgep
- feat: refs #7297 add new columns by:pablone
- feat: refs #7356 new parameters in sql for Weekly tickets front by:Jon
- feat: refs #7401 redirect lilium by:pablone
- feat: refs #7511 Fix tests by:guillermo
- feat: refs #7511 Rename to multiConfig tables by:guillermo
- feat: refs #7589 Added display (item_valuateInventory) by:guillermo
- feat: refs #7589 Added vItemTypeFk & vItemCategoryFk (item_valuateInventory) by:guillermo
- feat: refs #7681 Changes by:guillermo
- feat: refs #7681 Optimization and refactor by:guillermo
- feat: refs #7683 drop temporary table by:robert
- feat: refs #7683 productionControl by:robert
- feat: refs #7728 Added throw due date by:guillermo
- feat: refs #7740 Ticket before update added restriction by:guillermo
- feat(salix): #7648 Add field for endpoint as buyLabel report by:Javier Segarra
- feat(salix): #7648 remove white line by:Javier Segarra
- feat: tabla config dias margen vctos. refs #7728 by:Carlos Andrés
### Changed 📦
- eat: refactor buyUltimate refs #7736 by:Carlos Andrés
- feat: refactor buyUltimate refs #7736 by:Carlos Andrés
- feat: refs #7681 Optimization and refactor by:guillermo
- refactor: refs #7126 Requested changes by:guillermo
- refactor: refs #7511 Minor change by:guillermo
- refactor: refs #7640 Multipleinventory available by:guillermo
- refactor: refs #7681 Changes by:guillermo
- refactor: refs #7681 Requested changes by:guillermo
### Fixed 🛠️
- add prefix (hotFix_liliumRedirection) by:alexm
- fix(client_filter): add recovery by:alexm
- fix: defaulter filter correct sql (6943-fix_defaulter_filter) by:alexm
- fix(deletExpeditions): merge test → dev by:guillermo
- fix: refs #6403 fix mrw cancel shipment return type by:pablone
- fix: refs #7126 Added addressWaste type by:guillermo
- fix: refs #7126 Fix by:guillermo
- fix: refs #7126 Minor change by:guillermo
- fix: refs #7126 Primary key no unique data by:guillermo
- fix: refs #7126 Slow update by:guillermo
- fix: refs #7511 Minor change by:guillermo
- fix: refs #7546 Deleted insert util.binlogQueue by:guillermo
- fix: refs #7811 Variables pm2 by:guillermo
- fix: without path by:alexm
# Version 24.28 - 2024-07-09 # Version 24.28 - 2024-07-09
### Added 🆕 ### Added 🆕

View File

@ -67,7 +67,9 @@ module.exports = Self => {
if (vnUser.twoFactor === 'email') { if (vnUser.twoFactor === 'email') {
const $ = Self.app.models; const $ = Self.app.models;
const code = String(Math.floor(Math.random() * 999999)); const min = 100000;
const max = 999999;
const code = String(Math.floor(Math.random() * (max - min + 1)) + min);
const maxTTL = ((60 * 1000) * 5); // 5 min const maxTTL = ((60 * 1000) * 5); // 5 min
await $.AuthCode.upsertWithWhere({userFk: vnUser.id}, { await $.AuthCode.upsertWithWhere({userFk: vnUser.id}, {
userFk: vnUser.id, userFk: vnUser.id,

View File

@ -58,7 +58,7 @@ module.exports = Self => {
fields: ['name', 'twoFactor'] fields: ['name', 'twoFactor']
}, myOptions); }, myOptions);
if (user.name !== username) if (user.name.toLowerCase() !== username.toLowerCase())
throw new UserError('Authentication failed'); throw new UserError('Authentication failed');
await authCode.destroy(myOptions); await authCode.destroy(myOptions);

View File

@ -0,0 +1,50 @@
module.exports = Self => {
Self.remoteMethodCtx('add', {
description: 'Add activity if the activity is different or is the same but have exceed time for break',
accessType: 'WRITE',
accepts: [
{
arg: 'code',
type: 'string',
description: 'Code for activity'
},
{
arg: 'model',
type: 'string',
description: 'Origin model from insert'
},
],
http: {
path: `/add`,
verb: 'POST'
}
});
Self.add = async(ctx, code, model, options) => {
const userId = ctx.req.accessToken.userId;
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
return await Self.rawSql(`
INSERT INTO workerActivity (workerFk, workerActivityTypeFk, model)
SELECT ?, ?, ?
FROM workerTimeControlParams wtcp
LEFT JOIN (
SELECT wa.workerFk,
wa.created,
wat.code
FROM workerActivity wa
LEFT JOIN workerActivityType wat ON wat.code = wa.workerActivityTypeFk
WHERE wa.workerFk = ?
ORDER BY wa.created DESC
LIMIT 1
) sub ON TRUE
WHERE sub.workerFk IS NULL
OR sub.code <> ?
OR TIMESTAMPDIFF(SECOND, sub.created, util.VN_NOW()) > wtcp.dayBreak;`
, [userId, code, model, userId, code], myOptions);
};
};

View File

@ -0,0 +1,30 @@
const {models} = require('vn-loopback');
describe('workerActivity insert()', () => {
const ctx = beforeAll.getCtx(1106);
it('should insert in workerActivity', async() => {
const tx = await models.WorkerActivity.beginTransaction({});
let count = 0;
const options = {transaction: tx};
try {
await models.WorkerActivityType.create(
{'code': 'STOP', 'description': 'STOP'}, options
);
await models.WorkerActivity.add(ctx, 'STOP', 'APP', options);
count = await models.WorkerActivity.count(
{'workerFK': 1106}, options
);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
expect(count).toEqual(1);
});
});

View File

@ -0,0 +1,3 @@
module.exports = Self => {
require('../methods/workerActivity/add')(Self);
};

View File

@ -22,18 +22,18 @@
}, },
"description": { "description": {
"type": "string" "type": "string"
}
},
"relations": {
"workerFk": {
"type": "belongsTo",
"model": "Worker",
"foreignKey": "workerFk"
}, },
"relations": { "workerActivityTypeFk": {
"workerFk": { "type": "belongsTo",
"type": "belongsTo", "model": "WorkerActivityType",
"model": "Worker", "foreignKey": "workerActivityTypeFk"
"foreignKey": "workerFk"
},
"workerActivityTypeFk": {
"type": "belongsTo",
"model": "WorkerActivityType",
"foreignKey": "workerActivityTypeFk"
}
} }
} }
} }

View File

@ -3,7 +3,7 @@ USE `util`;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
INSERT INTO `version` VALUES ('vn-database','11154','04ff3e0cc79b00272d1ebbde7196292eab651c1d','2024-07-23 09:24:55','11163'); INSERT INTO `version` VALUES ('vn-database','11161','36dee872d62ba2421c05503f374f6b208c40ecfa','2024-08-06 07:53:56','11180');
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','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); INSERT INTO `versionLog` VALUES ('vn-database','10112','00-firstScript.sql','jenkins@10.0.2.69','2022-05-09 09:14:53',NULL,NULL);
@ -822,6 +822,7 @@ INSERT INTO `versionLog` VALUES ('vn-database','11034','00-firstScript.sql','jen
INSERT INTO `versionLog` VALUES ('vn-database','11037','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-05-28 07:32:17',NULL,NULL); INSERT INTO `versionLog` VALUES ('vn-database','11037','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-05-28 07:32:17',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11038','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-05-28 07:32:17',NULL,NULL); INSERT INTO `versionLog` VALUES ('vn-database','11038','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-05-28 07:32:17',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11040','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-05-28 07:32:31',NULL,NULL); INSERT INTO `versionLog` VALUES ('vn-database','11040','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-05-28 07:32:31',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11042','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-08-06 07:53:54',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11044','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-05-28 07:32:31',NULL,NULL); INSERT INTO `versionLog` VALUES ('vn-database','11044','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-05-28 07:32:31',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11045','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-05-10 14:53:29',NULL,NULL); INSERT INTO `versionLog` VALUES ('vn-database','11045','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-05-10 14:53:29',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11046','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-05-28 07:32:46',NULL,NULL); INSERT INTO `versionLog` VALUES ('vn-database','11046','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-05-28 07:32:46',NULL,NULL);
@ -896,14 +897,22 @@ INSERT INTO `versionLog` VALUES ('vn-database','11138','00-firstScript.sql','jen
INSERT INTO `versionLog` VALUES ('vn-database','11139','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-07-08 10:58:01',NULL,NULL); INSERT INTO `versionLog` VALUES ('vn-database','11139','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-07-08 10:58:01',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11140','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-07-23 08:23:34',NULL,NULL); INSERT INTO `versionLog` VALUES ('vn-database','11140','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-07-23 08:23:34',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11145','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-07-09 13:55:46',NULL,NULL); INSERT INTO `versionLog` VALUES ('vn-database','11145','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-07-09 13:55:46',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11146','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-08-06 07:53:54',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11149','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-07-23 08:23:35',NULL,NULL); INSERT INTO `versionLog` VALUES ('vn-database','11149','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-07-23 08:23:35',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11150','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-07-23 08:23:35',NULL,NULL); INSERT INTO `versionLog` VALUES ('vn-database','11150','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-07-23 08:23:35',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11152','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-07-16 09:06:11',NULL,NULL); INSERT INTO `versionLog` VALUES ('vn-database','11152','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-07-16 09:06:11',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11154','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-07-23 08:23:35',NULL,NULL); INSERT INTO `versionLog` VALUES ('vn-database','11154','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-07-23 08:23:35',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11155','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-08-06 07:53:54',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11156','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-08-06 07:53:54',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11157','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-07-16 13:11:00',NULL,NULL); INSERT INTO `versionLog` VALUES ('vn-database','11157','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-07-16 13:11:00',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11158','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-07-17 17:06:30',NULL,NULL); INSERT INTO `versionLog` VALUES ('vn-database','11158','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-07-17 17:06:30',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11159','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-07-18 17:23:32',NULL,NULL); INSERT INTO `versionLog` VALUES ('vn-database','11159','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-07-18 17:23:32',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11160','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-07-18 13:46:16',NULL,NULL); INSERT INTO `versionLog` VALUES ('vn-database','11160','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-07-18 13:46:16',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11161','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-08-06 07:53:54',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11164','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-07-23 11:03:16',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11168','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-07-25 08:58:34',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11169','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-07-25 12:38:13',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);
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
@ -2046,13 +2055,14 @@ INSERT INTO `ACL` VALUES (892,'WorkerIncome','*','*','ALLOW','ROLE','hr');
INSERT INTO `ACL` VALUES (893,'PayrollComponent','*','*','ALLOW','ROLE','hr'); INSERT INTO `ACL` VALUES (893,'PayrollComponent','*','*','ALLOW','ROLE','hr');
INSERT INTO `ACL` VALUES (894,'Worker','__get__incomes','*','ALLOW','ROLE','hr'); INSERT INTO `ACL` VALUES (894,'Worker','__get__incomes','*','ALLOW','ROLE','hr');
INSERT INTO `ACL` VALUES (895,'ItemShelvingLog','*','READ','ALLOW','ROLE','production'); INSERT INTO `ACL` VALUES (895,'ItemShelvingLog','*','READ','ALLOW','ROLE','production');
INSERT INTO `ACL` VALUES (896,'Expedition_PrintOut','*','READ','ALLOW','ROLE','production');
INSERT INTO `ACL` VALUES (897,'WorkerLog','*','READ','ALLOW','ROLE','employee'); INSERT INTO `ACL` VALUES (897,'WorkerLog','*','READ','ALLOW','ROLE','employee');
INSERT INTO `ACL` VALUES (901,'WorkerTimeControl','sendMail','WRITE','ALLOW','ROLE','system'); INSERT INTO `ACL` VALUES (901,'WorkerTimeControl','sendMail','WRITE','ALLOW','ROLE','system');
INSERT INTO `ACL` VALUES (902,'Entry','filter','READ','ALLOW','ROLE','supplier'); INSERT INTO `ACL` VALUES (902,'Entry','filter','READ','ALLOW','ROLE','supplier');
INSERT INTO `ACL` VALUES (903,'Entry','getBuys','READ','ALLOW','ROLE','supplier'); INSERT INTO `ACL` VALUES (903,'Entry','getBuys','READ','ALLOW','ROLE','supplier');
INSERT INTO `ACL` VALUES (904,'Entry','buyLabel','READ','ALLOW','ROLE','supplier'); INSERT INTO `ACL` VALUES (904,'Entry','buyLabel','READ','ALLOW','ROLE','supplier');
INSERT INTO `ACL` VALUES (905,'AddressWaste','*','READ','ALLOW','ROLE','production'); INSERT INTO `ACL` VALUES (905,'AddressWaste','*','READ','ALLOW','ROLE','production');
INSERT INTO `ACL` VALUES (906,'Entry','print','READ','ALLOW','ROLE','supplier');
INSERT INTO `ACL` VALUES (907,'Expedition_PrintOut','*','*','ALLOW','ROLE','production');
INSERT INTO `fieldAcl` VALUES (1,'Client','name','update','employee'); INSERT INTO `fieldAcl` VALUES (1,'Client','name','update','employee');
INSERT INTO `fieldAcl` VALUES (2,'Client','contact','update','employee'); INSERT INTO `fieldAcl` VALUES (2,'Client','contact','update','employee');
@ -2137,11 +2147,11 @@ INSERT INTO `module` VALUES ('wagon');
INSERT INTO `module` VALUES ('worker'); INSERT INTO `module` VALUES ('worker');
INSERT INTO `module` VALUES ('zone'); INSERT INTO `module` VALUES ('zone');
INSERT INTO `defaultViewConfig` VALUES ('itemsIndex','{\"intrastat\":false,\"stemMultiplier\":false,\"landed\":false,\"producer\":false}'); INSERT INTO `defaultViewMultiConfig` VALUES ('itemsIndex','{\"intrastat\":false,\"stemMultiplier\":false,\"landed\":false,\"producer\":false}');
INSERT INTO `defaultViewConfig` VALUES ('latestBuys','{\"intrastat\":false,\"description\":false,\"density\":false,\"isActive\":false,\n \"freightValue\":false,\"packageValue\":false,\"isIgnored\":false,\"price2\":false,\"ektFk\":false,\"weight\":false,\n \"size\":false,\"comissionValue\":false,\"landing\":false}'); INSERT INTO `defaultViewMultiConfig` VALUES ('latestBuys','{\"intrastat\":false,\"description\":false,\"density\":false,\"isActive\":false,\n \"freightValue\":false,\"packageValue\":false,\"isIgnored\":false,\"price2\":false,\"ektFk\":false,\"weight\":false,\n \"size\":false,\"comissionValue\":false,\"landing\":false}');
INSERT INTO `defaultViewConfig` VALUES ('ticketsMonitor','{\"id\":false}'); INSERT INTO `defaultViewMultiConfig` VALUES ('ticketsMonitor','{\"id\":false}');
INSERT INTO `defaultViewConfig` VALUES ('clientsDetail','{\"id\":true,\"phone\":true,\"city\":true,\"socialName\":true,\"salesPersonFk\":true,\"email\":true,\"name\":false,\"fi\":false,\"credit\":false,\"creditInsurance\":false,\"mobile\":false,\"street\":false,\"countryFk\":false,\"provinceFk\":false,\"postcode\":false,\"created\":false,\"businessTypeFk\":false,\"payMethodFk\":false,\"sageTaxTypeFk\":false,\"sageTransactionTypeFk\":false,\"isActive\":false,\"isVies\":false,\"isTaxDataChecked\":false,\"isEqualizated\":false,\"isFreezed\":false,\"hasToInvoice\":false,\"hasToInvoiceByAddress\":false,\"isToBeMailed\":false,\"hasLcr\":false,\"hasCoreVnl\":false,\"hasSepaVnl\":false}'); INSERT INTO `defaultViewMultiConfig` VALUES ('clientsDetail','{\"id\":true,\"phone\":true,\"city\":true,\"socialName\":true,\"salesPersonFk\":true,\"email\":true,\"name\":false,\"fi\":false,\"credit\":false,\"creditInsurance\":false,\"mobile\":false,\"street\":false,\"countryFk\":false,\"provinceFk\":false,\"postcode\":false,\"created\":false,\"businessTypeFk\":false,\"payMethodFk\":false,\"sageTaxTypeFk\":false,\"sageTransactionTypeFk\":false,\"isActive\":false,\"isVies\":false,\"isTaxDataChecked\":false,\"isEqualizated\":false,\"isFreezed\":false,\"hasToInvoice\":false,\"hasToInvoiceByAddress\":false,\"isToBeMailed\":false,\"hasLcr\":false,\"hasCoreVnl\":false,\"hasSepaVnl\":false}');
INSERT INTO `defaultViewConfig` VALUES ('routesList','{\"ID\":true,\"worker\":true,\"agency\":true,\"vehicle\":true,\"date\":true,\"volume\":true,\"description\":true,\"started\":true,\"finished\":true,\"actions\":true}'); INSERT INTO `defaultViewMultiConfig` VALUES ('routesList','{\"ID\":true,\"worker\":true,\"agency\":true,\"vehicle\":true,\"date\":true,\"volume\":true,\"description\":true,\"started\":true,\"finished\":true,\"actions\":true}');
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
@ -2153,6 +2163,7 @@ USE `vn`;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
INSERT INTO `alertLevel` VALUES ('FREE',0,1); INSERT INTO `alertLevel` VALUES ('FREE',0,1);
INSERT INTO `alertLevel` VALUES ('ON_PREVIOUS',1,1);
INSERT INTO `alertLevel` VALUES ('ON_PREPARATION',2,1); INSERT INTO `alertLevel` VALUES ('ON_PREPARATION',2,1);
INSERT INTO `alertLevel` VALUES ('PACKED',3,0); INSERT INTO `alertLevel` VALUES ('PACKED',3,0);
INSERT INTO `alertLevel` VALUES ('DELIVERED',4,0); INSERT INTO `alertLevel` VALUES ('DELIVERED',4,0);
@ -2384,7 +2395,7 @@ INSERT INTO `department` VALUES (37,'PROD','PRODUCCION',14,37,NULL,72,1,1,1,11,1
INSERT INTO `department` VALUES (38,'picking','SACADO',17,18,NULL,72,1,0,2,0,37,'/1/37/',NULL,0,NULL,0,0,0,1,NULL,NULL,NULL,NULL); INSERT INTO `department` VALUES (38,'picking','SACADO',17,18,NULL,72,1,0,2,0,37,'/1/37/',NULL,0,NULL,0,0,0,1,NULL,NULL,NULL,NULL);
INSERT INTO `department` VALUES (39,'packing','ENCAJADO',19,20,NULL,72,1,0,2,0,37,'/1/37/',NULL,0,NULL,0,0,0,1,NULL,NULL,NULL,NULL); INSERT INTO `department` VALUES (39,'packing','ENCAJADO',19,20,NULL,72,1,0,2,0,37,'/1/37/',NULL,0,NULL,0,0,0,1,NULL,NULL,NULL,NULL);
INSERT INTO `department` VALUES (41,'administration','ADMINISTRACION',38,39,NULL,72,0,0,1,0,1,'/1/',NULL,1,NULL,1,0,0,0,NULL,NULL,NULL,NULL); INSERT INTO `department` VALUES (41,'administration','ADMINISTRACION',38,39,NULL,72,0,0,1,0,1,'/1/',NULL,1,NULL,1,0,0,0,NULL,NULL,NULL,NULL);
INSERT INTO `department` VALUES (43,'VT','VENTAS',40,71,NULL,0,0,0,1,15,1,'/1/',NULL,1,'',1,0,0,0,NULL,NULL,NULL,NULL); INSERT INTO `department` VALUES (43,'VT','VENTAS',40,71,NULL,0,0,0,1,15,1,'/1/',NULL,1,NULL,1,0,0,0,NULL,NULL,NULL,NULL);
INSERT INTO `department` VALUES (44,'management','GERENCIA',72,73,NULL,72,0,0,1,0,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL,NULL,NULL); INSERT INTO `department` VALUES (44,'management','GERENCIA',72,73,NULL,72,0,0,1,0,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL,NULL,NULL);
INSERT INTO `department` VALUES (45,'logistic','LOGISTICA',74,75,NULL,72,0,0,1,0,1,'/1/',NULL,1,NULL,0,0,0,0,NULL,NULL,NULL,NULL); INSERT INTO `department` VALUES (45,'logistic','LOGISTICA',74,75,NULL,72,0,0,1,0,1,'/1/',NULL,1,NULL,0,0,0,0,NULL,NULL,NULL,NULL);
INSERT INTO `department` VALUES (46,'delivery','REPARTO',76,77,NULL,72,0,0,1,0,1,'/1/',NULL,0,NULL,0,1,0,0,NULL,NULL,NULL,NULL); INSERT INTO `department` VALUES (46,'delivery','REPARTO',76,77,NULL,72,0,0,1,0,1,'/1/',NULL,0,NULL,0,1,0,0,NULL,NULL,NULL,NULL);
@ -2722,6 +2733,7 @@ INSERT INTO `state` VALUES (36,'Previa Revisando',3,0,'PREVIOUS_CONTROL',2,37,1,
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 (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 (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 (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 `ticketUpdateAction` VALUES (1,'Cambiar los precios en el ticket','renewPrices'); INSERT INTO `ticketUpdateAction` VALUES (1,'Cambiar los precios en el ticket','renewPrices');
INSERT INTO `ticketUpdateAction` VALUES (2,'Convertir en maná','mana'); INSERT INTO `ticketUpdateAction` VALUES (2,'Convertir en maná','mana');

View File

@ -1292,6 +1292,8 @@ INSERT IGNORE INTO `tables_priv` VALUES ('','srt','grafana','buffer','juan@db-p
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','greuge','juan@db-proxy2.static.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','greuge','juan@db-proxy2.static.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','buyer','item','jenkins@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','','Select,Update'); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','buyer','item','jenkins@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','','Select,Update');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','coolerBoss','itemShelving','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Update',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','coolerBoss','itemShelving','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Update','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','buyer','agencyIncoming','alexm@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select,Insert,Update,Delete','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','addressObservation','carlosap@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','negativeOrigin','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','negativeOrigin','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn2008','deliveryBoss','Vehiculos_consumo','carlosap@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select,Insert,Update,Delete',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn2008','deliveryBoss','Vehiculos_consumo','carlosap@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select,Insert,Update,Delete','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','buyer','entryOrder','jenkins@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select,Insert,Delete',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','buyer','entryOrder','jenkins@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select,Insert,Delete','');
@ -1357,6 +1359,8 @@ INSERT IGNORE INTO `tables_priv` VALUES ('','vn','administrative','accounting',
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','hr','accounting','jenkins@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','hr','accounting','jenkins@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','employee','workerActivity','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select,Insert',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','employee','workerActivity','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select,Insert','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','ticketRequest','guillermo@10.5.1.3','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','ticketRequest','guillermo@10.5.1.3','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn2008','deliveryAssistant','Vehiculos_consumo','carlosap@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','administrative','budgetState','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','deliveryBoss','vehicleState','jgallego@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','deliveryBoss','vehicleState','jgallego@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','srt','grafana','expeditionState','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','srt','grafana','expeditionState','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','buyer','specialPrice','jgallego@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select,Insert,Update,Delete',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','buyer','specialPrice','jgallego@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select,Insert,Update,Delete','');
@ -1379,6 +1383,7 @@ INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','professionalCategor
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','production','ticketObservation','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Insert',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','production','ticketObservation','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Insert','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','deliveryNoteState','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','deliveryNoteState','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','deliveryNote','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','deliveryNote','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','inventoryConfig','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','comparative','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','comparative','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','invoiceOutExpense','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','invoiceOutExpense','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','delivery','carlosap@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','delivery','carlosap@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
@ -1404,6 +1409,7 @@ INSERT IGNORE INTO `tables_priv` VALUES ('','vn','teamBoss','business','guiller
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','ticketServiceType','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','ticketServiceType','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','employee','business','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','','Select'); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','employee','business','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','','Select');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','supplierAgencyTerm','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','supplierAgencyTerm','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','itemMinimumQuantity','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','clientRate','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','clientRate','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn2008','entryEditor','Entradas','guillermo@10.5.1.3','0000-00-00 00:00:00','Insert','Update'); INSERT IGNORE INTO `tables_priv` VALUES ('','vn2008','entryEditor','Entradas','guillermo@10.5.1.3','0000-00-00 00:00:00','Insert','Update');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','administrative','clientInforma','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','administrative','clientInforma','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
@ -1428,6 +1434,8 @@ INSERT IGNORE INTO `tables_priv` VALUES ('','vn','hr','businessReasonEnd','guil
INSERT IGNORE INTO `tables_priv` VALUES ('','vn2008','buyer','buy_edi','alexm@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn2008','buyer','buy_edi','alexm@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn2008','buyer','buySource','alexm@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn2008','buyer','buySource','alexm@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','bi','salesPerson','claims_ratio','alexm@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','bi','salesPerson','claims_ratio','alexm@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','hedera','employee','shelfMultiConfig','jenkins@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','clientConfig','carlosap@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn2008','deliveryBoss','albaran','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn2008','deliveryBoss','albaran','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn2008','deliveryBoss','albaran_gestdoc','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn2008','deliveryBoss','albaran_gestdoc','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn2008','deliveryBoss','albaran_state','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn2008','deliveryBoss','albaran_state','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');

File diff suppressed because it is too large Load Diff

View File

@ -6325,10 +6325,6 @@ BEGIN
SET NEW.userFk = account.myUser_getId(); SET NEW.userFk = account.myUser_getId();
END IF; END IF;
IF (NEW.visible <> OLD.visible) THEN
SET NEW.available = GREATEST(NEW.available + NEW.visible - OLD.visible, 0);
END IF;
END */;; END */;;
DELIMITER ; DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ; /*!50003 SET sql_mode = @saved_sql_mode */ ;
@ -9224,13 +9220,16 @@ BEGIN
SET NEW.editorFk = account.myUser_getId(); SET NEW.editorFk = account.myUser_getId();
IF NOT (NEW.routeFk <=> OLD.routeFk) THEN IF NOT (NEW.routeFk <=> OLD.routeFk) THEN
INSERT IGNORE INTO `vn`.`routeRecalc` (`routeFk`) IF NEW.isSigned THEN
SELECT r.id CALL util.throw('A signed ticket cannot be rerouted');
FROM vn.route r END IF;
WHERE r.isOk = FALSE INSERT IGNORE INTO routeRecalc(routeFk)
AND r.id IN (OLD.routeFk,NEW.routeFk) SELECT id
AND r.created >= util.VN_CURDATE() FROM `route`
GROUP BY r.id; WHERE NOT isOk
AND id IN (OLD.routeFk, NEW.routeFk)
AND created >= util.VN_CURDATE()
GROUP BY id;
END IF; END IF;
IF NOT (DATE(NEW.shipped) <=> DATE(OLD.shipped)) THEN IF NOT (DATE(NEW.shipped) <=> DATE(OLD.shipped)) THEN
@ -11143,4 +11142,4 @@ USE `vn2008`;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2024-07-23 8:19:41 -- Dump completed on 2024-08-06 6:03:19

View File

@ -1516,7 +1516,7 @@ INSERT INTO `vn`.`entry`(`id`, `supplierFk`, `created`, `travelFk`, `isConfirmed
(9, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL +2 DAY), 10, 0, 442, 'IN2009', 'Movement 9', 1, 1, ''), (9, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL +2 DAY), 10, 0, 442, 'IN2009', 'Movement 9', 1, 1, ''),
(10, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL +2 DAY), 10, 0, 442, 'IN2009', 'Movement 9', 1, 1, ''); (10, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL +2 DAY), 10, 0, 442, 'IN2009', 'Movement 9', 1, 1, '');
INSERT INTO `bs`.`waste`(`buyerFk`, `year`, `week`, `itemFk`, `itemTypeFk`, `saleTotal`, `saleQuantity`, `saleInternalWaste`, `saleExternalWaste`) INSERT INTO `bs`.`waste`(`buyerFk`, `year`, `week`, `itemFk`, `itemTypeFk`, `saleTotal`, `saleWasteQuantity`, `saleInternalWaste`, `saleExternalWaste`)
VALUES VALUES
('35', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 1, 1, '1062', '51', '56.20', '56.20'), ('35', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 1, 1, '1062', '51', '56.20', '56.20'),
('35', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 2, 1, '35074', '687', '53.12', '89.69'), ('35', YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 WEEK), 1), 2, 1, '35074', '687', '53.12', '89.69'),

View File

@ -1,7 +1,7 @@
DELIMITER $$ DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `bs`.`waste_addSales`() CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `bs`.`waste_addSales`()
BEGIN BEGIN
DECLARE vDateFrom DATE DEFAULT util.VN_CURDATE() - INTERVAL WEEKDAY(CURDATE()) DAY; DECLARE vDateFrom DATE DEFAULT util.VN_CURDATE() - INTERVAL WEEKDAY(util.VN_CURDATE()) DAY;
DECLARE vDateTo DATE DEFAULT vDateFrom + INTERVAL 6 DAY; DECLARE vDateTo DATE DEFAULT vDateFrom + INTERVAL 6 DAY;
CALL cache.last_buy_refresh(FALSE); CALL cache.last_buy_refresh(FALSE);
@ -12,25 +12,22 @@ BEGIN
it.workerFk, it.workerFk,
it.id, it.id,
s.itemFk, s.itemFk,
SUM(s.quantity), SUM((b.buyingValue + b.freightValue + b.comissionValue + b.packageValue) * s.quantity),
SUM((b.buyingValue + b.freightValue + b.comissionValue + b.packageValue) * s.quantity) `value`, SUM(IF(aw.`type`, s.quantity, 0)),
SUM ( SUM(
IF( IF(
aw.`type` = 'internal', aw.`type` = 'internal',
(b.buyingValue + b.freightValue + b.comissionValue + b.packageValue) * s.quantity, (b.buyingValue + b.freightValue + b.comissionValue + b.packageValue) * s.quantity,
0 0
) )
) internalWaste, ),
SUM ( SUM(
IF( IF(
aw.`type` = 'external', aw.`type` = 'external',
(b.buyingValue + b.freightValue + b.comissionValue + b.packageValue) * s.quantity, (b.buyingValue + b.freightValue + b.comissionValue + b.packageValue) * s.quantity,
IF(c.code = 'manaClaim', 0
sc.value * s.quantity,
0
)
) )
) externalWaste )
FROM vn.sale s FROM vn.sale s
JOIN vn.item i ON i.id = s.itemFk JOIN vn.item i ON i.id = s.itemFk
JOIN vn.itemType it ON it.id = i.typeFk JOIN vn.itemType it ON it.id = i.typeFk
@ -41,10 +38,8 @@ BEGIN
JOIN cache.last_buy lb ON lb.item_id = i.id JOIN cache.last_buy lb ON lb.item_id = i.id
AND lb.warehouse_id = w.id AND lb.warehouse_id = w.id
JOIN vn.buy b ON b.id = lb.buy_id JOIN vn.buy b ON b.id = lb.buy_id
LEFT JOIN vn.saleComponent sc ON sc.saleFk = s.id
LEFT JOIN vn.component c ON c.id = sc.componentFk
WHERE t.shipped BETWEEN vDateFrom AND vDateTo WHERE t.shipped BETWEEN vDateFrom AND vDateTo
AND w.isManaged AND w.isManaged
GROUP BY it.id, i.id; GROUP BY i.id;
END$$ END$$
DELIMITER ; DELIMITER ;

View File

@ -1,59 +1,62 @@
DELIMITER $$ DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `hedera`.`order_confirmWithUser`(vSelf INT, vUserId INT) CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `hedera`.`order_confirmWithUser`(
vSelf INT,
vUserFk INT
)
BEGIN BEGIN
/** /**
* Confirms an order, creating each of its tickets on the corresponding * Confirms an order, creating each of its tickets
* date, store and user. * on the corresponding date, store and user.
* *
* @param vSelf The order identifier * @param vSelf The order identifier
* @param vUser The user identifier * @param vUser The user identifier
*/ */
DECLARE vOk BOOL; DECLARE vHasRows BOOL;
DECLARE vDone BOOL DEFAULT FALSE; DECLARE vDone BOOL;
DECLARE vWarehouse INT; DECLARE vWarehouseFk INT;
DECLARE vShipment DATE; DECLARE vShipment DATE;
DECLARE vTicket INT; DECLARE vShipmentDayEnd DATETIME;
DECLARE vTicketFk INT;
DECLARE vNotes VARCHAR(255); DECLARE vNotes VARCHAR(255);
DECLARE vItem INT; DECLARE vItemFk INT;
DECLARE vConcept VARCHAR(30); DECLARE vConcept VARCHAR(30);
DECLARE vAmount INT; DECLARE vAmount INT;
DECLARE vAvailable INT;
DECLARE vPrice DECIMAL(10,2); DECLARE vPrice DECIMAL(10,2);
DECLARE vSale INT; DECLARE vSaleFk INT;
DECLARE vRate INT; DECLARE vRowFk INT;
DECLARE vRowId INT;
DECLARE vPriceFixed DECIMAL(10,2); DECLARE vPriceFixed DECIMAL(10,2);
DECLARE vDelivery DATE; DECLARE vLanded DATE;
DECLARE vAddress INT; DECLARE vAddressFk INT;
DECLARE vIsConfirmed BOOL; DECLARE vClientFk INT;
DECLARE vClientId INT; DECLARE vCompanyFk INT;
DECLARE vCompanyId INT; DECLARE vAgencyModeFk INT;
DECLARE vAgencyModeId INT; DECLARE vCalcFk INT;
DECLARE TICKET_FREE INT DEFAULT 2;
DECLARE vCalc INT;
DECLARE vIsLogifloraItem BOOL;
DECLARE vOldQuantity INT;
DECLARE vNewQuantity INT;
DECLARE vIsTaxDataChecked BOOL; DECLARE vIsTaxDataChecked BOOL;
DECLARE cDates CURSOR FOR DECLARE vDates CURSOR FOR
SELECT zgs.shipped, r.warehouse_id SELECT zgs.shipped, r.warehouseFk
FROM `order` o FROM `order` o
JOIN order_row r ON r.order_id = o.id JOIN orderRow r ON r.orderFk = o.id
LEFT JOIN tmp.zoneGetShipped zgs ON zgs.warehouseFk = r.warehouse_id LEFT JOIN tmp.zoneGetShipped zgs ON zgs.warehouseFk = r.warehouseFk
WHERE o.id = vSelf AND r.amount != 0 WHERE o.id = vSelf
GROUP BY r.warehouse_id; AND r.amount
GROUP BY r.warehouseFk;
DECLARE cRows CURSOR FOR DECLARE vRows CURSOR FOR
SELECT r.id, r.item_id, i.name, r.amount, r.price, r.rate, i.isFloramondo SELECT r.id,
FROM order_row r r.itemFk,
JOIN vn.item i ON i.id = r.item_id i.name,
WHERE r.amount != 0 r.amount,
AND r.warehouse_id = vWarehouse r.price
AND r.order_id = vSelf FROM orderRow r
JOIN vn.item i ON i.id = r.itemFk
WHERE r.amount
AND r.warehouseFk = vWarehouseFk
AND r.orderFk = vSelf
ORDER BY r.rate DESC; ORDER BY r.rate DESC;
DECLARE CONTINUE HANDLER FOR NOT FOUND DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
SET vDone = TRUE;
DECLARE EXIT HANDLER FOR SQLEXCEPTION DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN BEGIN
@ -62,26 +65,36 @@ BEGIN
END; END;
-- Carga los datos del pedido -- Carga los datos del pedido
SELECT o.date_send, o.address_id, o.note, a.clientFk, SELECT o.date_send,
o.company_id, o.agency_id, c.isTaxDataChecked o.address_id,
INTO vDelivery, vAddress, vNotes, vClientId, o.note,
vCompanyId, vAgencyModeId, vIsTaxDataChecked a.clientFk,
FROM hedera.`order` o o.company_id,
o.agency_id,
c.isTaxDataChecked
INTO vLanded,
vAddressFk,
vNotes,
vClientFk,
vCompanyFk,
vAgencyModeFk,
vIsTaxDataChecked
FROM `order` o
JOIN vn.address a ON a.id = o.address_id JOIN vn.address a ON a.id = o.address_id
JOIN vn.client c ON c.id = a.clientFk JOIN vn.client c ON c.id = a.clientFk
WHERE o.id = vSelf; WHERE o.id = vSelf;
-- Verifica si el cliente tiene los datos comprobados -- Verifica si el cliente tiene los datos comprobados
IF NOT vIsTaxDataChecked THEN IF NOT vIsTaxDataChecked THEN
CALL util.throw ('clientNotVerified'); CALL util.throw('clientNotVerified');
END IF; END IF;
-- Carga las fechas de salida de cada almacen -- Carga las fechas de salida de cada almacen
CALL vn.zone_getShipped (vDelivery, vAddress, vAgencyModeId, FALSE); CALL vn.zone_getShipped(vLanded, vAddressFk, vAgencyModeFk, FALSE);
-- Trabajador que realiza la accion -- Trabajador que realiza la accion
IF vUserId IS NULL THEN IF vUserFk IS NULL THEN
SELECT employeeFk INTO vUserId FROM orderConfig; SELECT employeeFk INTO vUserFk FROM orderConfig;
END IF; END IF;
START TRANSACTION; START TRANSACTION;
@ -89,207 +102,188 @@ BEGIN
CALL order_checkEditable(vSelf); CALL order_checkEditable(vSelf);
-- Check order is not empty -- Check order is not empty
SELECT COUNT(*) > 0 INTO vHasRows
FROM orderRow
WHERE orderFk = vSelf
AND amount > 0;
SELECT COUNT(*) > 0 INTO vOk IF NOT vHasRows THEN
FROM order_row WHERE order_id = vSelf AND amount > 0; CALL util.throw('ORDER_EMPTY');
IF NOT vOk THEN
CALL util.throw ('ORDER_EMPTY');
END IF; END IF;
-- Crea los tickets del pedido -- Crea los tickets del pedido
OPEN vDates;
OPEN cDates; lDates: LOOP
SET vTicketFk = NULL;
lDates:
LOOP
SET vTicket = NULL;
SET vDone = FALSE; SET vDone = FALSE;
FETCH cDates INTO vShipment, vWarehouse; FETCH vDates INTO vShipment, vWarehouseFk;
IF vDone THEN IF vDone THEN
LEAVE lDates; LEAVE lDates;
END IF; END IF;
-- Busca un ticket existente que coincida con los parametros SET vShipmentDayEnd = util.dayEnd(vShipment);
WITH tPrevia AS
(SELECT DISTINCT s.ticketFk -- Busca un ticket libre disponible
WITH tPrevia AS (
SELECT DISTINCT s.ticketFk
FROM vn.sale s FROM vn.sale s
JOIN vn.saleGroupDetail sgd ON sgd.saleFk = s.id JOIN vn.saleGroupDetail sgd ON sgd.saleFk = s.id
JOIN vn.ticket t ON t.id = s.ticketFk JOIN vn.ticket t ON t.id = s.ticketFk
WHERE t.shipped BETWEEN vShipment AND util.dayend(vShipment) WHERE t.shipped BETWEEN vShipment AND vShipmentDayEnd
) )
SELECT t.id INTO vTicket SELECT t.id INTO vTicketFk
FROM vn.ticket t FROM vn.ticket t
JOIN vn.alertLevel al ON al.code = 'FREE' JOIN vn.alertLevel al ON al.code = 'FREE'
LEFT JOIN tPrevia tp ON tp.ticketFk = t.id LEFT JOIN tPrevia tp ON tp.ticketFk = t.id
LEFT JOIN vn.ticketState tls on tls.ticketFk = t.id LEFT JOIN vn.ticketState tls ON tls.ticketFk = t.id
JOIN hedera.`order` o JOIN hedera.`order` o ON o.address_id = t.addressFk
ON o.address_id = t.addressFk AND t.shipped BETWEEN vShipment AND vShipmentDayEnd
AND vWarehouse = t.warehouseFk AND t.warehouseFk = vWarehouseFk
AND o.date_send = t.landed AND o.date_send = t.landed
AND DATE(t.shipped) = vShipment
WHERE o.id = vSelf WHERE o.id = vSelf
AND t.refFk IS NULL AND t.refFk IS NULL
AND tp.ticketFk IS NULL AND tp.ticketFk IS NULL
AND (tls.alertLevel IS NULL OR tls.alertLevel = al.id) AND (tls.alertLevel IS NULL OR tls.alertLevel = al.id)
LIMIT 1; LIMIT 1;
-- Comprobamos si hay un ticket de previa disponible
IF vTicketFk IS NULL THEN
WITH tItemPackingTypeOrder AS (
SELECT GROUP_CONCAT(
DISTINCT i.itemPackingTypeFk ORDER BY i.itemPackingTypeFk
) distinctItemPackingTypes,
o.address_id
FROM vn.item i
JOIN hedera.orderRow oro ON oro.itemFk = i.id
JOIN hedera.`order` o ON o.id = oro.orderFk
WHERE oro.orderFk = vSelf
),
tItemPackingTypeTicket AS (
SELECT t.id,
GROUP_CONCAT(
DISTINCT i.itemPackingTypeFk ORDER BY i.itemPackingTypeFk
) distinctItemPackingTypes
FROM vn.ticket t
JOIN vn.ticketState tls ON tls.ticketFk = t.id
JOIN vn.alertLevel al ON al.id = tls.alertLevel
JOIN vn.sale s ON s.ticketFk = t.id
JOIN vn.item i ON i.id = s.itemFk
JOIN tItemPackingTypeOrder ipto
WHERE t.shipped BETWEEN vShipment AND vShipmentDayEnd
AND t.refFk IS NULL
AND t.warehouseFk = vWarehouseFk
AND t.addressFk = ipto.address_id
AND al.code = 'ON_PREVIOUS'
GROUP BY t.id
)
SELECT iptt.id INTO vTicketFk
FROM tItemPackingTypeTicket iptt
JOIN tItemPackingTypeOrder ipto
WHERE INSTR(iptt.distinctItemPackingTypes, ipto.distinctItemPackingTypes)
LIMIT 1;
END IF;
-- Crea el ticket en el caso de no existir uno adecuado -- Crea el ticket en el caso de no existir uno adecuado
IF vTicket IS NULL IF vTicketFk IS NULL THEN
THEN
SET vShipment = IFNULL(vShipment, util.VN_CURDATE()); SET vShipment = IFNULL(vShipment, util.VN_CURDATE());
CALL vn.ticket_add( CALL vn.ticket_add(
vClientId, vClientFk,
vShipment, vShipment,
vWarehouse, vWarehouseFk,
vCompanyId, vCompanyFk,
vAddress, vAddressFk,
vAgencyModeId, vAgencyModeFk,
NULL, NULL,
vDelivery, vLanded,
vUserId, vUserFk,
TRUE, TRUE,
vTicket vTicketFk
); );
ELSE ELSE
INSERT INTO vn.ticketTracking INSERT INTO vn.ticketTracking
SET ticketFk = vTicket, SET ticketFk = vTicketFk,
userFk = vUserId, userFk = vUserFk,
stateFk = TICKET_FREE; stateFk = (SELECT id FROM vn.state WHERE code = 'FREE');
END IF; END IF;
INSERT IGNORE INTO vn.orderTicket INSERT IGNORE INTO vn.orderTicket
SET orderFk = vSelf, SET orderFk = vSelf,
ticketFk = vTicket; ticketFk = vTicketFk;
-- Añade las notas -- Añade las notas
IF vNotes IS NOT NULL AND vNotes <> '' THEN
IF vNotes IS NOT NULL AND vNotes != '' INSERT INTO vn.ticketObservation
THEN SET ticketFk = vTicketFk,
INSERT INTO vn.ticketObservation SET observationTypeFk = (SELECT id FROM vn.observationType WHERE code = 'salesPerson'),
ticketFk = vTicket,
observationTypeFk = 4 /* salesperson */ ,
`description` = vNotes `description` = vNotes
ON DUPLICATE KEY UPDATE ON DUPLICATE KEY UPDATE
`description` = CONCAT(VALUES(`description`),'. ', `description`); `description` = CONCAT(VALUES(`description`),'. ', `description`);
END IF; END IF;
-- Añade los movimientos y sus componentes -- Añade los movimientos y sus componentes
OPEN vRows;
OPEN cRows;
lRows: LOOP lRows: LOOP
SET vSaleFk = NULL;
SET vDone = FALSE; SET vDone = FALSE;
FETCH cRows INTO vRowId, vItem, vConcept, vAmount, vPrice, vRate, vIsLogifloraItem; FETCH vRows INTO vRowFk, vItemFk, vConcept, vAmount, vPrice;
IF vDone THEN IF vDone THEN
LEAVE lRows; LEAVE lRows;
END IF; END IF;
SET vSale = NULL; SELECT s.id INTO vSaleFk
SELECT s.id, s.quantity INTO vSale, vOldQuantity
FROM vn.sale s FROM vn.sale s
WHERE ticketFk = vTicket WHERE ticketFk = vTicketFk
AND price = vPrice AND price = vPrice
AND itemFk = vItem AND itemFk = vItemFk
AND discount = 0 AND discount = 0
LIMIT 1; LIMIT 1;
IF vSale THEN IF vSaleFk THEN
UPDATE vn.sale UPDATE vn.sale
SET quantity = quantity + vAmount, SET quantity = quantity + vAmount,
originalQuantity = quantity originalQuantity = quantity
WHERE id = vSale; WHERE id = vSaleFk;
SELECT s.quantity INTO vNewQuantity
FROM vn.sale s
WHERE id = vSale;
ELSE ELSE
-- Obtiene el coste -- Obtiene el coste
SELECT SUM(rc.`price`) valueSum INTO vPriceFixed SELECT SUM(rc.`price`) valueSum INTO vPriceFixed
FROM orderRowComponent rc FROM orderRowComponent rc
JOIN vn.component c ON c.id = rc.componentFk JOIN vn.component c ON c.id = rc.componentFk
JOIN vn.componentType ct ON ct.id = c.typeFk AND ct.isBase JOIN vn.componentType ct ON ct.id = c.typeFk
WHERE rc.rowFk = vRowId; AND ct.isBase
WHERE rc.rowFk = vRowFk;
INSERT INTO vn.sale INSERT INTO vn.sale
SET itemFk = vItem, SET itemFk = vItemFk,
ticketFk = vTicket, ticketFk = vTicketFk,
concept = vConcept, concept = vConcept,
quantity = vAmount, quantity = vAmount,
price = vPrice, price = vPrice,
priceFixed = vPriceFixed, priceFixed = vPriceFixed,
isPriceFixed = TRUE; isPriceFixed = TRUE;
SET vSale = LAST_INSERT_ID(); SET vSaleFk = LAST_INSERT_ID();
INSERT INTO vn.saleComponent INSERT INTO vn.saleComponent (saleFk, componentFk, `value`)
(saleFk, componentFk, `value`) SELECT vSaleFk, rc.componentFk, rc.price
SELECT vSale, rc.componentFk, rc.price
FROM orderRowComponent rc FROM orderRowComponent rc
JOIN vn.component c ON c.id = rc.componentFk JOIN vn.component c ON c.id = rc.componentFk
WHERE rc.rowFk = vRowId WHERE rc.rowFk = vRowFk
GROUP BY vSale, rc.componentFk; GROUP BY vSaleFk, rc.componentFk;
END IF; END IF;
UPDATE order_row SET Id_Movimiento = vSale UPDATE orderRow
WHERE id = vRowId; SET saleFk = vSaleFk
WHERE id = vRowFk;
-- Inserta en putOrder si la compra es de Floramondo
IF vIsLogifloraItem THEN
CALL cache.availableNoRaids_refresh(vCalc,FALSE,vWarehouse,vShipment);
SET @available := 0;
SELECT GREATEST(0,available) INTO @available
FROM cache.availableNoRaids
WHERE calc_id = vCalc
AND item_id = vItem;
UPDATE cache.availableNoRaids
SET available = GREATEST(0,available - vAmount)
WHERE item_id = vItem
AND calc_id = vCalc;
INSERT INTO edi.putOrder (
deliveryInformationID,
supplyResponseId,
quantity ,
EndUserPartyId,
EndUserPartyGLN,
FHAdminNumber,
saleFk
)
SELECT di.ID,
i.supplyResponseFk,
CEIL((vAmount - @available)/ sr.NumberOfItemsPerCask),
o.address_id ,
vClientId,
IFNULL(ca.fhAdminNumber, fhc.defaultAdminNumber),
vSale
FROM edi.deliveryInformation di
JOIN vn.item i ON i.supplyResponseFk = di.supplyResponseID
JOIN edi.supplyResponse sr ON sr.ID = i.supplyResponseFk
LEFT JOIN edi.clientFHAdminNumber ca ON ca.clientFk = vClientId
JOIN edi.floraHollandConfig fhc
JOIN hedera.`order` o ON o.id = vSelf
WHERE i.id = vItem
AND di.LatestOrderDateTime > util.VN_NOW()
AND vAmount > @available
LIMIT 1;
END IF;
END LOOP; END LOOP;
CLOSE vRows;
CLOSE cRows;
END LOOP; END LOOP;
CLOSE vDates;
CLOSE cDates; UPDATE `order`
SET confirmed = TRUE,
UPDATE `order` SET confirmed = TRUE, confirm_date = util.VN_NOW() confirm_date = util.VN_NOW()
WHERE id = vSelf; WHERE id = vSelf;
COMMIT; COMMIT;

View File

@ -0,0 +1,12 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `salix`.`ACL_afterDelete`
AFTER DELETE ON `ACL`
FOR EACH ROW
BEGIN
INSERT INTO ACL
SET `action` = 'delete',
`changedModel` = 'Acl',
`changedModelId` = OLD.id,
`userFk` = account.myUser_getId();
END$$
DELIMITER ;

View File

@ -0,0 +1,8 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `salix`.`ACL_beforeInsert`
BEFORE INSERT ON `ACL`
FOR EACH ROW
BEGIN
SET NEW.editorFk = account.myUser_getId();
END$$
DELIMITER ;

View File

@ -0,0 +1,8 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `salix`.`ACL_beforeUpdate`
BEFORE UPDATE ON `ACL`
FOR EACH ROW
BEGIN
SET NEW.editorFk = account.myUser_getId();
END$$
DELIMITER ;

View File

@ -1,8 +1,8 @@
DELIMITER $$ DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`address_updateCoordinates`( CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`address_updateCoordinates`(
vTicketFk INT, vTicketFk INT,
vLongitude INT, vLongitude DECIMAL(11,7),
vLatitude INT) vLatitude DECIMAL(11,7))
BEGIN BEGIN
/** /**
* Actualiza las coordenadas de una dirección. * Actualiza las coordenadas de una dirección.

View File

@ -32,7 +32,7 @@ BEGIN
JOIN duaEntry de ON de.entryFk = e.id JOIN duaEntry de ON de.entryFk = e.id
JOIN invoiceInConfig iic JOIN invoiceInConfig iic
WHERE de.duaFk = vDuaFk WHERE de.duaFk = vDuaFk
AND iidd.dueDated <= util.VN_CURDATE() + INTERVAL iic.dueDateMarginDays DAY; AND iidd.dueDated < util.VN_CURDATE() + INTERVAL iic.dueDateMarginDays DAY;
IF vIncorrectInvoiceInDueDay THEN IF vIncorrectInvoiceInDueDay THEN
CALL util.throw(CONCAT('Incorrect due date, invoice: ', vIncorrectInvoiceInDueDay)); CALL util.throw(CONCAT('Incorrect due date, invoice: ', vIncorrectInvoiceInDueDay));

View File

@ -15,7 +15,7 @@ BEGIN
DECLARE cur CURSOR FOR DECLARE cur CURSOR FOR
SELECT bb.id buyFk, SELECT bb.id buyFk,
FLOOR(ish.visible / ish.packing) ishStickers, LEAST(bb.stickers, FLOOR(ish.visible / ish.packing)) ishStickers,
bb.stickers buyStickers bb.stickers buyStickers
FROM itemShelving ish FROM itemShelving ish
JOIN (SELECT b.id, b.itemFk, b.stickers JOIN (SELECT b.id, b.itemFk, b.stickers
@ -23,7 +23,6 @@ BEGIN
WHERE b.entryFk = vFromEntryFk WHERE b.entryFk = vFromEntryFk
ORDER BY b.stickers DESC ORDER BY b.stickers DESC
LIMIT 10000000000000000000) bb ON bb.itemFk = ish.itemFk LIMIT 10000000000000000000) bb ON bb.itemFk = ish.itemFk
AND bb.stickers >= FLOOR(ish.visible / ish.packing)
WHERE ish.shelvingFk = vShelvingFk COLLATE utf8_general_ci WHERE ish.shelvingFk = vShelvingFk COLLATE utf8_general_ci
AND NOT ish.isSplit AND NOT ish.isSplit
GROUP BY ish.id; GROUP BY ish.id;
@ -110,7 +109,7 @@ BEGIN
UPDATE itemShelving UPDATE itemShelving
SET isSplit = TRUE SET isSplit = TRUE
WHERE shelvingFk = vShelvingFk; WHERE shelvingFk = vShelvingFk COLLATE utf8_general_ci;
END LOOP; END LOOP;
CLOSE cur; CLOSE cur;
END$$ END$$

View File

@ -1,11 +1,18 @@
DELIMITER $$ DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`expeditionScan_Put`(vPalletFk INT, vExpeditionFk INT) CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`expeditionScan_Put`(
vPalletFk INT,
vExpeditionFk INT
)
BEGIN BEGIN
IF NOT (SELECT TRUE FROM expedition WHERE id = vExpeditionFk LIMIT 1) THEN
REPLACE vn.expeditionScan(expeditionFk, palletFk) CALL util.throw('Expedition not exists');
VALUES(vExpeditionFk, vPalletFk); END IF;
SELECT LAST_INSERT_ID() INTO vPalletFk; IF NOT (SELECT TRUE FROM expeditionPallet WHERE id = vPalletFk LIMIT 1) THEN
CALL util.throw('Pallet not exists');
END IF;
REPLACE expeditionScan(expeditionFk, palletFk)
VALUES(vExpeditionFk, vPalletFk);
END$$ END$$
DELIMITER ; DELIMITER ;

View File

@ -16,9 +16,11 @@ BEGIN
DECLARE vHasRepeatedTransactions BOOL; DECLARE vHasRepeatedTransactions BOOL;
SELECT TRUE INTO vHasRepeatedTransactions SELECT TRUE INTO vHasRepeatedTransactions
FROM invoiceInTax FROM invoiceInTax iit
WHERE invoiceInFk = vSelf JOIN invoiceIn ii ON ii.id = iit.invoiceInFk
HAVING COUNT(DISTINCT transactionTypeSageFk) > 1 WHERE ii.id = vSelf
AND ii.serial = 'E'
HAVING COUNT(DISTINCT iit.transactionTypeSageFk) > 1
LIMIT 1; LIMIT 1;
IF vHasRepeatedTransactions THEN IF vHasRepeatedTransactions THEN

View File

@ -0,0 +1,46 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`itemShelvingSale_addBySaleGroup`(
vSaleGroupFk INT(11)
)
BEGIN
/**
* Reserva cantidades con ubicaciones para el contenido de una preparación previa
* a través del saleGroup
*
* @param vSaleGroupFk Identificador de saleGroup
*/
DECLARE vDone BOOL DEFAULT FALSE;
DECLARE vSaleFk INT;
DECLARE vSectorFk INT;
DECLARE vSales CURSOR FOR
SELECT s.id
FROM saleGroupDetail sgd
JOIN sale s ON sgd.saleFk = s.id
JOIN saleTracking str ON str.saleFk = s.id
JOIN `state` st ON st.id = str.stateFk
AND st.code = 'PREVIOUS_PREPARATION'
LEFT JOIN itemShelvingSale iss ON iss.saleFk = s.id
WHERE sgd.saleGroupFk = vSaleGroupFk
AND str.workerFk = account.myUser_getId()
AND iss.id IS NULL;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
SELECT sectorFk INTO vSectorFk
FROM operator
WHERE workerFk = account.myUser_getId();
OPEN vSales;
l: LOOP
SET vDone = FALSE;
FETCH vSales INTO vSaleFk;
IF vDone THEN
LEAVE l;
END IF;
CALL itemShelvingSale_addBySale(vSaleFk, vSectorFk);
END LOOP;
CLOSE vSales;
END$$
DELIMITER ;

View File

@ -16,7 +16,8 @@ BEGIN
ish.id, ish.id,
s.priority, s.priority,
ish.isChecked, ish.isChecked,
ic.url ic.url,
ish.available
FROM itemShelving ish FROM itemShelving ish
JOIN item i ON i.id = ish.itemFk JOIN item i ON i.id = ish.itemFk
JOIN shelving s ON vSelf = s.code COLLATE utf8_unicode_ci JOIN shelving s ON vSelf = s.code COLLATE utf8_unicode_ci

View File

@ -1,37 +1,40 @@
DELIMITER $$ DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`item_getMinacum`(IN vWarehouseFk TINYINT, IN vDatedFrom DATETIME, IN vRange INT, IN vItemFk INT) CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`item_getMinacum`(
vWarehouseFk TINYINT,
vDated DATE,
vRange INT,
vItemFk INT
)
BEGIN BEGIN
/** /**
* Cálculo del mínimo acumulado, para un item/almacén especificado, en caso de * Cálculo del mínimo acumulado, para un item/almacén
* NULL para todo. * especificado, en caso de NULL para todos.
* *
* @param vWarehouseFk -> warehouseFk * @param vWarehouseFk Id warehouse
* @param vDatedFrom -> fecha inicio * @param vDated Fecha inicio
* @param vRange -> número de días a considerar * @param vRange Número de días a considerar
* @param vItemFk -> Identificador de item * @param vItemFk Id de artículo
* @return tmp.itemMinacum * @return tmp.itemMinacum
*/ */
DECLARE vDatedTo DATETIME; DECLARE vDatedTo DATETIME DEFAULT util.dayEnd(vDated + INTERVAL vRange DAY);
SET vDatedFrom = TIMESTAMP(DATE(vDatedFrom), '00:00:00'); CREATE OR REPLACE TEMPORARY TABLE tmp.itemCalc
SET vDatedTo = TIMESTAMP(TIMESTAMPADD(DAY, vRange, vDatedFrom), '23:59:59');
DROP TEMPORARY TABLE IF EXISTS tmp.itemCalc;
CREATE TEMPORARY TABLE tmp.itemCalc
(INDEX (itemFk, warehouseFk)) (INDEX (itemFk, warehouseFk))
ENGINE = MEMORY
SELECT sub.itemFk, SELECT sub.itemFk,
sub.dated, sub.dated,
CAST(SUM(sub.quantity) AS SIGNED) quantity, CAST(SUM(sub.quantity) AS SIGNED) quantity,
sub.warehouseFk sub.warehouseFk
FROM (SELECT s.itemFk, FROM (
SELECT s.itemFk,
DATE(t.shipped) dated, DATE(t.shipped) dated,
-s.quantity quantity, -s.quantity quantity,
t.warehouseFk t.warehouseFk
FROM sale s FROM sale s
JOIN ticket t ON t.id = s.ticketFk JOIN ticket t ON t.id = s.ticketFk
WHERE t.shipped BETWEEN vDatedFrom AND vDatedTo WHERE t.shipped BETWEEN vDated AND vDatedTo
AND t.warehouseFk AND t.warehouseFk
AND s.quantity != 0 AND s.quantity <> 0
AND (vItemFk IS NULL OR s.itemFk = vItemFk) AND (vItemFk IS NULL OR s.itemFk = vItemFk)
AND (vWarehouseFk IS NULL OR t.warehouseFk = vWarehouseFk) AND (vWarehouseFk IS NULL OR t.warehouseFk = vWarehouseFk)
UNION ALL UNION ALL
@ -42,10 +45,10 @@ BEGIN
FROM buy b FROM buy b
JOIN entry e ON e.id = b.entryFk JOIN entry e ON e.id = b.entryFk
JOIN travel t ON t.id = e.travelFk JOIN travel t ON t.id = e.travelFk
WHERE t.landed BETWEEN vDatedFrom AND vDatedTo WHERE t.landed BETWEEN vDated AND vDatedTo
AND (vWarehouseFk IS NULL OR t.warehouseInFk = vWarehouseFk) AND (vWarehouseFk IS NULL OR t.warehouseInFk = vWarehouseFk)
AND !e.isExcludedFromAvailable AND NOT e.isExcludedFromAvailable
AND b.quantity != 0 AND b.quantity <> 0
AND (vItemFk IS NULL OR b.itemFk = vItemFk) AND (vItemFk IS NULL OR b.itemFk = vItemFk)
UNION ALL UNION ALL
SELECT b.itemFk, SELECT b.itemFk,
@ -55,28 +58,45 @@ BEGIN
FROM buy b FROM buy b
JOIN entry e ON e.id = b.entryFk JOIN entry e ON e.id = b.entryFk
JOIN travel t ON t.id = e.travelFk JOIN travel t ON t.id = e.travelFk
WHERE t.shipped BETWEEN vDatedFrom AND vDatedTo WHERE t.shipped BETWEEN vDated AND vDatedTo
AND (vWarehouseFk IS NULL OR t.warehouseOutFk = vWarehouseFk) AND (vWarehouseFk IS NULL OR t.warehouseOutFk = vWarehouseFk)
AND !e.isExcludedFromAvailable AND NOT e.isExcludedFromAvailable
AND b.quantity != 0 AND b.quantity <> 0
AND (vItemFk IS NULL OR b.itemFk = vItemFk) AND (vItemFk IS NULL OR b.itemFk = vItemFk)
AND !e.isRaid AND NOT e.isRaid
UNION ALL
SELECT r.itemFk,
r.shipment,
-r.amount,
r.warehouseFk
FROM hedera.orderRow r
JOIN hedera.`order` o ON o.id = r.orderFk
JOIN client c ON c.id = o.customer_id
WHERE r.shipment BETWEEN vDated AND vDatedTo
AND (vWarehouseFk IS NULL OR r.warehouseFk = vWarehouseFk)
AND r.created >= (
SELECT util.VN_NOW() - INTERVAL TIME_TO_SEC(reserveTime) SECOND
FROM hedera.orderConfig
)
AND NOT o.confirmed
AND (vItemFk IS NULL OR r.itemFk = vItemFk)
AND r.amount <> 0
) sub ) sub
GROUP BY sub.itemFk, sub.warehouseFk, sub.dated; GROUP BY sub.itemFk, sub.warehouseFk, sub.dated;
CALL item_getAtp(vDatedFrom); CALL item_getAtp(vDated);
DROP TEMPORARY TABLE tmp.itemCalc;
DROP TEMPORARY TABLE IF EXISTS tmp.itemMinacum; CREATE OR REPLACE TEMPORARY TABLE tmp.itemMinacum
CREATE TEMPORARY TABLE tmp.itemMinacum
(INDEX(itemFk)) (INDEX(itemFk))
ENGINE = MEMORY ENGINE = MEMORY
SELECT i.itemFk, SELECT itemFk,
i.warehouseFk, warehouseFk,
i.quantity amount quantity amount
FROM tmp.itemAtp i FROM tmp.itemAtp
HAVING amount != 0; WHERE quantity <> 0;
DROP TEMPORARY TABLE tmp.itemAtp; DROP TEMPORARY TABLE
tmp.itemAtp,
tmp.itemCalc;
END$$ END$$
DELIMITER ; DELIMITER ;

View File

@ -13,7 +13,7 @@ BEGIN
DECLARE vAvailableCache INT; DECLARE vAvailableCache INT;
DECLARE vVisibleCache INT; DECLARE vVisibleCache INT;
DECLARE vDone BOOL; DECLARE vDone BOOL;
DECLARE vComponentCount INT; DECLARE vRequiredComponent INT;
DECLARE vCursor CURSOR FOR DECLARE vCursor CURSOR FOR
SELECT DISTINCT tt.warehouseFk, IF(vIsTodayRelative, util.VN_CURDATE(), DATE(tt.shipped)) SELECT DISTINCT tt.warehouseFk, IF(vIsTodayRelative, util.VN_CURDATE(), DATE(tt.shipped))
@ -54,7 +54,7 @@ BEGIN
SELECT ticketFk, clientFk SELECT ticketFk, clientFk
FROM tmp.sale_getProblems; FROM tmp.sale_getProblems;
SELECT COUNT(*) INTO vComponentCount SELECT COUNT(*) INTO vRequiredComponent
FROM component FROM component
WHERE isRequired; WHERE isRequired;
@ -96,20 +96,18 @@ BEGIN
-- Faltan componentes -- Faltan componentes
INSERT INTO tmp.sale_problems(ticketFk, hasComponentLack, saleFk) INSERT INTO tmp.sale_problems(ticketFk, hasComponentLack, saleFk)
SELECT ticketFk, (vComponentCount > nComp) hasComponentLack, saleFk SELECT t.id, COUNT(c.id) < vRequiredComponent hasComponentLack, s.id
FROM ( FROM tmp.ticket_list tl
SELECT COUNT(s.id) nComp, tl.ticketFk, s.id saleFk JOIN ticket t ON t.id = tl.ticketFk
FROM tmp.ticket_list tl JOIN sale s ON s.ticketFk = t.id
JOIN sale s ON s.ticketFk = tl.ticketFk JOIN agencyMode am ON am.id = t.agencyModeFk
LEFT JOIN saleComponent sc ON sc.saleFk = s.id JOIN deliveryMethod dm ON dm.id = am.deliveryMethodFk
LEFT JOIN component c ON c.id = sc.componentFk AND c.isRequired LEFT JOIN saleComponent sc ON sc.saleFk = s.id
JOIN ticket t ON t.id = tl.ticketFk LEFT JOIN component c ON c.id = sc.componentFk
JOIN agencyMode am ON am.id = t.agencyModeFk AND c.isRequired
JOIN deliveryMethod dm ON dm.id = am.deliveryMethodFk WHERE dm.code IN ('AGENCY','DELIVERY','PICKUP')
WHERE dm.code IN ('AGENCY','DELIVERY','PICKUP') AND s.quantity > 0
AND s.quantity > 0 GROUP BY s.id
GROUP BY s.id
) sub
HAVING hasComponentLack; HAVING hasComponentLack;
-- Cliente congelado -- Cliente congelado

View File

@ -11,24 +11,29 @@ BEGIN
*/ */
DECLARE vSaleFk INT; DECLARE vSaleFk INT;
DECLARE vHasProblem INT; DECLARE vHasProblem INT;
DECLARE vIsProblemCalcNeeded BOOL;
DECLARE vDone BOOL; DECLARE vDone BOOL;
DECLARE vSaleList CURSOR FOR SELECT saleFk, hasProblem FROM tmp.sale; DECLARE vSaleList CURSOR FOR
SELECT saleFk, hasProblem, isProblemCalcNeeded
FROM tmp.sale;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE; DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
OPEN vSaleList; OPEN vSaleList;
l: LOOP l: LOOP
SET vDone = FALSE; SET vDone = FALSE;
FETCH vSaleList INTO vSaleFk, vHasProblem; FETCH vSaleList INTO vSaleFk, vHasProblem, vIsProblemCalcNeeded;
IF vDone THEN IF vDone THEN
LEAVE l; LEAVE l;
END IF; END IF;
UPDATE sale UPDATE sale
SET problem = CONCAT( SET problem = IF (vIsProblemCalcNeeded,
IF(vHasProblem, CONCAT(
CONCAT(problem, ',', vProblemCode), IF(vHasProblem,
REPLACE(problem, vProblemCode , ''))) CONCAT(problem, ',', vProblemCode),
REPLACE(problem, vProblemCode , ''))),
NULL)
WHERE id = vSaleFk; WHERE id = vSaleFk;
END LOOP; END LOOP;
CLOSE vSaleList; CLOSE vSaleList;

View File

@ -14,7 +14,7 @@ BEGIN
ENGINE = MEMORY ENGINE = MEMORY
SELECT vSelf saleFk, SELECT vSelf saleFk,
sale_hasComponentLack(vSelf) hasProblem, sale_hasComponentLack(vSelf) hasProblem,
ticket_isProblemCalcNeeded(ticketFk) isProblemCalcNeeded (ticket_isProblemCalcNeeded(ticketFk) AND quantity > 0) isProblemCalcNeeded
FROM sale FROM sale
WHERE id = vSelf; WHERE id = vSelf;

View File

@ -14,9 +14,9 @@ BEGIN
ENGINE = MEMORY ENGINE = MEMORY
SELECT saleFk, SELECT saleFk,
sale_hasComponentLack(saleFk) hasProblem, sale_hasComponentLack(saleFk) hasProblem,
ticket_isProblemCalcNeeded(ticketFk) isProblemCalcNeeded (ticket_isProblemCalcNeeded(ticketFk) AND quantity > 0) isProblemCalcNeeded
FROM ( FROM (
SELECT s.id saleFk, s.ticketFk SELECT s.id saleFk, s.ticketFk, s.quantity
FROM ticket t FROM ticket t
JOIN sale s ON s.ticketFk = t.id JOIN sale s ON s.ticketFk = t.id
LEFT JOIN saleComponent sc ON sc.saleFk = s.id LEFT JOIN saleComponent sc ON sc.saleFk = s.id

View File

@ -1,139 +0,0 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`supplier_statement`(
vSupplierFk INT,
vCurrencyFk INT,
vCompanyFk INT,
vOrderBy VARCHAR(15),
vIsConciliated BOOL
)
BEGIN
/**
* Crea un estado de cuenta de proveedores calculando
* los saldos en euros y en la moneda especificada.
*
* @param vSupplierFk Id del proveedor
* @param vCurrencyFk Id de la moneda
* @param vCompanyFk Id de la empresa
* @param vOrderBy Criterio de ordenación
* @param vIsConciliated Indica si está conciliado o no
* @return tmp.supplierStatement
*/
SET @euroBalance:= 0;
SET @currencyBalance:= 0;
CREATE OR REPLACE TEMPORARY TABLE tmp.supplierStatement
ENGINE = MEMORY
SELECT *,
@euroBalance:= ROUND(
@euroBalance + IFNULL(paymentEuros, 0) -
IFNULL(invoiceEuros, 0), 2
) euroBalance,
@currencyBalance:= ROUND(
@currencyBalance + IFNULL(paymentCurrency, 0) -
IFNULL(invoiceCurrency, 0), 2
) currencyBalance
FROM (
SELECT * FROM
(
SELECT NULL bankFk,
ii.companyFk,
ii.serial,
ii.id,
CASE
WHEN vOrderBy = 'issued' THEN ii.issued
WHEN vOrderBy = 'bookEntried' THEN ii.bookEntried
WHEN vOrderBy = 'booked' THEN ii.booked
WHEN vOrderBy = 'dueDate' THEN iid.dueDated
END dated,
CONCAT('S/Fra ', ii.supplierRef) sref,
IF(ii.currencyFk > 1,
ROUND(SUM(iid.foreignValue) / SUM(iid.amount), 3),
NULL
) changeValue,
CAST(SUM(iid.amount) AS DECIMAL(10,2)) invoiceEuros,
CAST(SUM(iid.foreignValue) AS DECIMAL(10,2)) invoiceCurrency,
NULL paymentEuros,
NULL paymentCurrency,
ii.currencyFk,
ii.isBooked,
c.code,
'invoiceIn' statementType
FROM invoiceIn ii
JOIN invoiceInDueDay iid ON iid.invoiceInFk = ii.id
JOIN currency c ON c.id = ii.currencyFk
WHERE ii.issued > '2014-12-31'
AND ii.supplierFk = vSupplierFk
AND vCurrencyFk IN (ii.currencyFk, 0)
AND vCompanyFk IN (ii.companyFk, 0)
AND (vIsConciliated = ii.isBooked OR NOT vIsConciliated)
GROUP BY iid.id
UNION ALL
SELECT p.bankFk,
p.companyFk,
NULL,
p.id,
CASE
WHEN vOrderBy = 'issued' THEN p.received
WHEN vOrderBy = 'bookEntried' THEN p.received
WHEN vOrderBy = 'booked' THEN p.received
WHEN vOrderBy = 'dueDate' THEN p.dueDated
END,
CONCAT(IFNULL(pm.name, ''),
IF(pn.concept <> '',
CONCAT(' : ', pn.concept),
'')
),
IF(p.currencyFk > 1, p.divisa / p.amount, NULL),
NULL,
NULL,
p.amount,
p.divisa,
p.currencyFk,
p.isConciliated,
c.code,
'payment'
FROM payment p
LEFT JOIN currency c ON c.id = p.currencyFk
LEFT JOIN accounting a ON a.id = p.bankFk
LEFT JOIN payMethod pm ON pm.id = p.payMethodFk
LEFT JOIN promissoryNote pn ON pn.paymentFk = p.id
WHERE p.received > '2014-12-31'
AND p.supplierFk = vSupplierFk
AND vCurrencyFk IN (p.currencyFk, 0)
AND vCompanyFk IN (p.companyFk, 0)
AND (vIsConciliated = p.isConciliated OR NOT vIsConciliated)
UNION ALL
SELECT NULL,
companyFk,
NULL,
se.id,
CASE
WHEN vOrderBy = 'issued' THEN se.dated
WHEN vOrderBy = 'bookEntried' THEN se.dated
WHEN vOrderBy = 'booked' THEN se.dated
WHEN vOrderBy = 'dueDate' THEN se.dueDated
END,
se.description,
1,
amount,
NULL,
NULL,
NULL,
currencyFk,
isConciliated,
c.`code`,
'expense'
FROM supplierExpense se
JOIN currency c ON c.id = se.currencyFk
WHERE se.supplierFk = vSupplierFk
AND vCurrencyFk IN (se.currencyFk,0)
AND vCompanyFk IN (se.companyFk,0)
AND (vIsConciliated = se.isConciliated OR NOT vIsConciliated)
) sub
ORDER BY (dated IS NULL AND NOT isBooked),
dated,
IF(vOrderBy = 'dueDate', id, NULL)
LIMIT 10000000000000000000
) t;
END$$
DELIMITER ;

View File

@ -0,0 +1,166 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE vn.supplier_statementWithEntries(
vSupplierFk INT,
vCurrencyFk INT,
vCompanyFk INT,
vOrderBy VARCHAR(15),
vIsConciliated BOOL,
vHasEntries BOOL
)
BEGIN
/**
* Creates a supplier statement, calculating balances in euros and the specified currency.
*
* @param vSupplierFk Supplier ID
* @param vCurrencyFk Currency ID
* @param vCompanyFk Company ID
* @param vOrderBy Order by criteria
* @param vIsConciliated Indicates whether it is reconciled or not
* @param vHasEntries Indicates if future entries must be shown
* @return tmp.supplierStatement
*/
DECLARE vBalanceStartingDate DATETIME;
SET @euroBalance:= 0;
SET @currencyBalance:= 0;
SELECT balanceStartingDate
INTO vBalanceStartingDate
FROM invoiceInConfig;
CREATE OR REPLACE TEMPORARY TABLE tmp.supplierStatement
ENGINE = MEMORY
SELECT *,
@euroBalance:= ROUND(
@euroBalance + IFNULL(paymentEuros, 0) -
IFNULL(invoiceEuros, 0), 2
) euroBalance,
@currencyBalance:= ROUND(
@currencyBalance + IFNULL(paymentCurrency, 0) -
IFNULL(invoiceCurrency, 0), 2
) currencyBalance
FROM (
SELECT NULL bankFk,
ii.companyFk,
ii.serial,
ii.id,
CASE
WHEN vOrderBy = 'issued' THEN ii.issued
WHEN vOrderBy = 'bookEntried' THEN ii.bookEntried
WHEN vOrderBy = 'booked' THEN ii.booked
WHEN vOrderBy = 'dueDate' THEN iid.dueDated
END dated,
CONCAT('S/Fra ', ii.supplierRef) sref,
IF(ii.currencyFk > 1,
ROUND(SUM(iid.foreignValue) / SUM(iid.amount), 3),
NULL
) changeValue,
CAST(SUM(iid.amount) AS DECIMAL(10,2)) invoiceEuros,
CAST(SUM(iid.foreignValue) AS DECIMAL(10,2)) invoiceCurrency,
NULL paymentEuros,
NULL paymentCurrency,
ii.currencyFk,
ii.isBooked,
c.code,
'invoiceIn' statementType
FROM invoiceIn ii
JOIN invoiceInDueDay iid ON iid.invoiceInFk = ii.id
JOIN currency c ON c.id = ii.currencyFk
WHERE ii.issued >= vBalanceStartingDate
AND ii.supplierFk = vSupplierFk
AND vCurrencyFk IN (ii.currencyFk, 0)
AND vCompanyFk IN (ii.companyFk, 0)
AND (vIsConciliated = ii.isBooked OR NOT vIsConciliated)
GROUP BY iid.id
UNION ALL
SELECT p.bankFk,
p.companyFk,
NULL,
p.id,
CASE
WHEN vOrderBy = 'issued' THEN p.received
WHEN vOrderBy = 'bookEntried' THEN p.received
WHEN vOrderBy = 'booked' THEN p.received
WHEN vOrderBy = 'dueDate' THEN p.dueDated
END,
CONCAT(IFNULL(pm.name, ''),
IF(pn.concept <> '',
CONCAT(' : ', pn.concept),
'')
),
IF(p.currencyFk > 1, p.divisa / p.amount, NULL),
NULL,
NULL,
p.amount,
p.divisa,
p.currencyFk,
p.isConciliated,
c.code,
'payment'
FROM payment p
LEFT JOIN currency c ON c.id = p.currencyFk
LEFT JOIN accounting a ON a.id = p.bankFk
LEFT JOIN payMethod pm ON pm.id = p.payMethodFk
LEFT JOIN promissoryNote pn ON pn.paymentFk = p.id
WHERE p.received >= vBalanceStartingDate
AND p.supplierFk = vSupplierFk
AND vCurrencyFk IN (p.currencyFk, 0)
AND vCompanyFk IN (p.companyFk, 0)
AND (vIsConciliated = p.isConciliated OR NOT vIsConciliated)
UNION ALL
SELECT NULL,
companyFk,
NULL,
se.id,
CASE
WHEN vOrderBy = 'issued' THEN se.dated
WHEN vOrderBy = 'bookEntried' THEN se.dated
WHEN vOrderBy = 'booked' THEN se.dated
WHEN vOrderBy = 'dueDate' THEN se.dueDated
END,
se.description,
1,
amount,
NULL,
NULL,
NULL,
currencyFk,
isConciliated,
c.`code`,
'expense'
FROM supplierExpense se
JOIN currency c ON c.id = se.currencyFk
WHERE se.supplierFk = vSupplierFk
AND vCurrencyFk IN (se.currencyFk,0)
AND vCompanyFk IN (se.companyFk,0)
AND (vIsConciliated = se.isConciliated OR NOT vIsConciliated)
UNION ALL
SELECT NULL bankFk,
e.companyFk,
'E' serial,
e.invoiceNumber id,
tr.landed dated,
CONCAT('Ent. ',e.id) sref,
1 / ((e.commission/100)+1) changeValue,
e.invoiceAmount * (1 + (e.commission/100)),
e.invoiceAmount,
NULL,
NULL,
e.currencyFk,
FALSE isBooked,
c.code,
'order'
FROM entry e
JOIN travel tr ON tr.id = e.travelFk
JOIN currency c ON c.id = e.currencyFk
WHERE e.supplierFk = vSupplierFk
AND tr.landed >= CURDATE()
AND e.invoiceInFk IS NULL
AND vHasEntries
ORDER BY (dated IS NULL AND NOT isBooked),
dated,
IF(vOrderBy = 'dueDate', id, NULL)
LIMIT 10000000000000000000
) t;
END$$
DELIMITER ;

View File

@ -12,24 +12,28 @@ BEGIN
*/ */
DECLARE vTicketFk INT; DECLARE vTicketFk INT;
DECLARE vHasProblem INT; DECLARE vHasProblem INT;
DECLARE vIsProblemCalcNeeded BOOL;
DECLARE vDone BOOL; DECLARE vDone BOOL;
DECLARE vTicketList CURSOR FOR SELECT ticketFk, hasProblem FROM tmp.ticket; DECLARE vTicketList CURSOR FOR
SELECT ticketFk, hasProblem, isProblemCalcNeeded
FROM tmp.ticket;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE; DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
OPEN vTicketList; OPEN vTicketList;
l: LOOP l: LOOP
SET vDone = FALSE; SET vDone = FALSE;
FETCH vTicketList INTO vTicketFk, vHasProblem; FETCH vTicketList INTO vTicketFk, vHasProblem, vIsProblemCalcNeeded;
IF vDone THEN IF vDone THEN
LEAVE l; LEAVE l;
END IF; END IF;
UPDATE ticket UPDATE ticket
SET problem = CONCAT( SET problem = IF(vIsProblemCalcNeeded,
IF(vHasProblem, CONCAT(IF(vHasProblem,
CONCAT(problem, ',', vProblemCode), CONCAT(problem, ',', vProblemCode),
REPLACE(problem, vProblemCode , ''))) REPLACE(problem, vProblemCode , ''))),
NULL)
WHERE id = vTicketFk; WHERE id = vTicketFk;
END LOOP; END LOOP;
CLOSE vTicketList; CLOSE vTicketList;

View File

@ -0,0 +1,35 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_setProblemRiskByClient`(
vClientFk INT
)
BEGIN
/**
* Updates future ticket risk for a client.
*
* @param vClientFk Id client
*/
DECLARE vDone INT DEFAULT FALSE;
DECLARE vTicketFk INT;
DECLARE vTickets CURSOR FOR
SELECT id
FROM ticket
WHERE clientFk = vClientFk
AND shipped >= util.VN_CURDATE()
AND refFk IS NULL;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
OPEN vTickets;
l: LOOP
SET vDone = FALSE;
FETCH vTickets INTO vTicketFk;
IF vDone THEN
LEAVE l;
END IF;
CALL vn.ticket_setProblemRisk(vTicketFk);
END LOOP;
CLOSE vTickets;
END$$
DELIMITER ;

View File

@ -1,94 +1,83 @@
DELIMITER $$ DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_setRisk`( CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_setRisk`(
vClientFk INT) vClientFk INT
)
BEGIN BEGIN
/** /**
* Update the risk for a client with pending tickets * Update the risk for a client with pending tickets.
* *
* @param vClientFk Id cliente * @param vClientFk Id cliente
*/ */
DECLARE vHasDebt BOOL; IF (SELECT COUNT(*) FROM client WHERE id = vClientFk AND typeFk = 'normal') THEN
DECLARE vStarted DATETIME;
SELECT COUNT(*) INTO vHasDebt
FROM `client`
WHERE id = vClientFk
AND typeFk = 'normal';
IF vHasDebt THEN
SELECT util.VN_CURDATE() - INTERVAL riskScope MONTH INTO vStarted
FROM clientConfig;
CREATE OR REPLACE TEMPORARY TABLE tTicketRisk CREATE OR REPLACE TEMPORARY TABLE tTicketRisk
(KEY (ticketFk)) (PRIMARY KEY (ticketFk))
ENGINE = MEMORY ENGINE = MEMORY
WITH ticket AS( WITH ticket AS (
SELECT id ticketFk, SELECT t.id ticketFk,
companyFk, t.companyFk,
DATE(shipped) dated, DATE(t.shipped) dated,
totalWithVat, t.totalWithVat,
ticket_isProblemCalcNeeded(id) isProblemCalcNeeded ticket_isProblemCalcNeeded(t.id) isProblemCalcNeeded
FROM vn.ticket FROM vn.ticket t
WHERE clientFk = vClientFk JOIN vn.clientConfig cc
AND refFk IS NULL WHERE t.clientFk = vClientFk
AND NOT isDeleted AND t.refFk IS NULL
AND IFNULL(totalWithVat, 0) <> 0 AND NOT t.isDeleted
AND shipped > vStarted AND IFNULL(t.totalWithVat, 0) <> 0
), balance AS( AND t.shipped > (util.VN_CURDATE() - INTERVAL cc.riskScope MONTH)
SELECT SUM(amount)amount, companyFk ), uninvoiced AS (
FROM (
SELECT amount, companyFk
FROM vn.clientRisk
WHERE clientFk = vClientFk
UNION ALL
SELECT -(SUM(amount) / 100) amount, tm.companyFk
FROM hedera.tpvTransaction t
JOIN hedera.tpvMerchant tm ON t.id = t.merchantFk
WHERE clientFk = vClientFk
AND receiptFk IS NULL
AND status = 'ok'
) sub
WHERE companyFk
GROUP BY companyFk
), uninvoiced AS(
SELECT companyFk, dated, SUM(totalWithVat) amount SELECT companyFk, dated, SUM(totalWithVat) amount
FROM ticket FROM ticket
GROUP BY companyFk, dated GROUP BY companyFk, dated
), receipt AS( ), companies AS (
SELECT companyFk, DATE(payed) dated, SUM(amountPaid) amount SELECT DISTINCT companyFk FROM uninvoiced
FROM vn.receipt ), balance AS (
WHERE clientFk = vClientFk SELECT SUM(IFNULL(amount, 0))amount, companyFk
AND payed > util.VN_CURDATE() FROM (
GROUP BY companyFk, DATE(payed) SELECT cr.amount, c.companyFk
), risk AS( FROM companies c
LEFT JOIN vn.clientRisk cr ON cr.companyFk = c.companyFk
AND cr.clientFk = vClientFk
UNION ALL
SELECT -(SUM(t.amount) / 100) amount, c.companyFk
FROM companies c
LEFT JOIN hedera.tpvMerchant tm ON tm.companyFk = c.companyFk
LEFT JOIN hedera.tpvTransaction t ON t.merchantFk = tm.id
AND t.clientFk = vClientFk
AND t.receiptFk IS NULL
AND t.`status` = 'ok'
) sub
WHERE companyFk
GROUP BY companyFk
), receipt AS (
SELECT r.companyFk, DATE(r.payed) dated, SUM(r.amountPaid) amount
FROM vn.receipt r
JOIN companies c ON c.companyFk = r.companyFk
WHERE r.clientFk = vClientFk
AND r.payed > util.VN_CURDATE()
GROUP BY r.companyFk, DATE(r.payed)
), risk AS (
SELECT b.companyFk, SELECT b.companyFk,
ui.dated, ui.dated,
SUM(ui.amount) OVER (PARTITION BY b.companyFk ORDER BY ui.dated ) + SUM(ui.amount) OVER (PARTITION BY b.companyFk ORDER BY ui.dated) +
b.amount + b.amount +
SUM(IFNULL(r.amount, 0)) amount SUM(IFNULL(r.amount, 0)) amount
FROM balance b FROM balance b
JOIN uninvoiced ui ON ui.companyFk = b.companyFk JOIN uninvoiced ui ON ui.companyFk = b.companyFk
LEFT JOIN receipt r ON r.dated > ui.dated AND r.companyFk = ui.companyFk LEFT JOIN receipt r ON r.dated > ui.dated
AND r.companyFk = ui.companyFk
GROUP BY b.companyFk, ui.dated GROUP BY b.companyFk, ui.dated
) )
SELECT ti.ticketFk, r.amount, ti.isProblemCalcNeeded SELECT ti.ticketFk, r.amount, ti.isProblemCalcNeeded
FROM ticket ti FROM ticket ti
JOIN risk r ON r.dated = ti.dated AND r.companyFk = ti.companyFk; JOIN risk r ON r.dated = ti.dated
AND r.companyFk = ti.companyFk;
UPDATE ticket t UPDATE ticket t
JOIN tTicketRisk tr ON tr.ticketFk = t.id JOIN tTicketRisk tr ON tr.ticketFk = t.id
SET t.risk = tr.amount SET t.risk = IF(tr.isProblemCalcNeeded, tr.amount, NULL);
WHERE tr.isProblemCalcNeeded
ORDER BY t.id;
UPDATE ticket t
JOIN tTicketRisk tr ON tr.ticketFk = t.id
SET t.risk = NULL
WHERE tr.isProblemCalcNeeded
ORDER BY t.id;
DROP TEMPORARY TABLE tTicketRisk; DROP TEMPORARY TABLE tTicketRisk;
END IF; END IF;
END$$ END$$
DELIMITER ; DELIMITER ;

View File

@ -9,9 +9,5 @@ BEGIN
SET NEW.userFk = account.myUser_getId(); SET NEW.userFk = account.myUser_getId();
END IF; END IF;
IF (NEW.visible <> OLD.visible) THEN
SET NEW.available = GREATEST(NEW.available + NEW.visible - OLD.visible, 0);
END IF;
END$$ END$$
DELIMITER ; DELIMITER ;

View File

@ -8,7 +8,13 @@ BEGIN
SET NEW.editorFk = account.myUser_getId(); SET NEW.editorFk = account.myUser_getId();
IF NOT (NEW.routeFk <=> OLD.routeFk) THEN IF NOT (NEW.routeFk <=> OLD.routeFk) THEN
IF NEW.isSigned THEN IF NEW.isSigned AND NOT (
SELECT (COUNT(s.id) = COUNT(cb.saleFk)
AND SUM(s.quantity) = SUM(cb.quantity))
FROM sale s
LEFT JOIN claimBeginning cb ON cb.saleFk = s.id
WHERE s.ticketFk = NEW.id
) THEN
CALL util.throw('A signed ticket cannot be rerouted'); CALL util.throw('A signed ticket cannot be rerouted');
END IF; END IF;
INSERT IGNORE INTO routeRecalc(routeFk) INSERT IGNORE INTO routeRecalc(routeFk)

View File

@ -0,0 +1,25 @@
CREATE OR REPLACE TABLE `salix`.`ACLLog` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`originFk` int(11) DEFAULT NULL,
`userFk` int(10) unsigned DEFAULT NULL,
`action` set('insert','update','delete','select') NOT NULL,
`creationDate` timestamp NULL DEFAULT current_timestamp(),
`description` text CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL,
`changedModel` enum('Acl') NOT NULL DEFAULT 'Acl',
`oldInstance` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`oldInstance`)),
`newInstance` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`newInstance`)),
`changedModelId` int(11) NOT NULL,
`changedModelValue` varchar(45) DEFAULT NULL,
`summaryId` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `logRateuserFk` (`userFk`),
KEY `ACLLog_changedModel` (`changedModel`,`changedModelId`,`creationDate`),
KEY `ACLLog_originFk` (`originFk`,`creationDate`),
CONSTRAINT `aclUserFk` FOREIGN KEY (`userFk`) REFERENCES `account`.`user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
ALTER TABLE salix.ACL
ADD editorFk int(10) unsigned DEFAULT NULL NULL;
ALTER TABLE vn.ticket
CHANGE editorFk editorFk int(10) unsigned DEFAULT NULL NULL AFTER risk;

View File

@ -0,0 +1,6 @@
-- Place your SQL code here
ALTER TABLE vn.packingSite DROP COLUMN IF EXISTS hasNewLabelMrwMethod;
ALTER TABLE vn.productionConfig ADD IF NOT EXISTS hasNewLabelMrwMethod BOOL DEFAULT TRUE NOT NULL
COMMENT 'column to activate the new mrw integration';

View File

@ -0,0 +1,2 @@
RENAME TABLE vn.silexACL TO vn.silexACL__;
ALTER TABLE vn.silexACL__ COMMENT='@deprecated 2024-08-05 refs #7820';

View File

@ -0,0 +1,2 @@
-- Place your SQL code here
ALTER TABLE vn.invoiceInConfig ADD balanceStartingDate DATE DEFAULT '2015-01-01' NOT NULL;

View File

@ -0,0 +1,2 @@
ALTER TABLE bs.waste CHANGE saleQuantity saleWasteQuantity decimal(10,2) DEFAULT NULL NULL AFTER saleTotal;
ALTER TABLE bs.waste MODIFY COLUMN saleTotal decimal(10,2) DEFAULT NULL NULL COMMENT 'Coste';

View File

@ -738,69 +738,6 @@ export default {
worker: 'vn-worker-autocomplete[ng-model="$ctrl.userFk"]', worker: 'vn-worker-autocomplete[ng-model="$ctrl.userFk"]',
saveStateButton: `button[type=submit]` saveStateButton: `button[type=submit]`
}, },
claimsIndex: {
searchResult: 'vn-claim-index vn-card > vn-table > div > vn-tbody > a'
},
claimDescriptor: {
moreMenu: 'vn-claim-descriptor vn-icon-button[icon=more_vert]',
moreMenuDeleteClaim: '.vn-menu [name="deleteClaim"]',
acceptDeleteClaim: '.vn-confirm.shown button[response="accept"]'
},
claimSummary: {
header: 'vn-claim-summary > vn-card > h5',
state: 'vn-claim-summary vn-label-value[label="State"] > section > span',
observation: 'vn-claim-summary vn-horizontal.text',
firstSaleItemId: 'vn-claim-summary vn-horizontal > vn-auto:nth-child(5) vn-table > div > vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(1) > span',
firstSaleDescriptorImage: '.vn-popover.shown vn-item-descriptor img',
itemDescriptorPopover: '.vn-popover.shown vn-item-descriptor',
itemDescriptorPopoverItemDiaryButton: '.vn-popover vn-item-descriptor vn-quick-link[icon="icon-transaction"] > a',
firstDevelopmentWorker: 'vn-claim-summary vn-horizontal > vn-auto:nth-child(4) vn-table > div > vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(4) > span',
firstDevelopmentWorkerGoToClientButton: '.vn-popover vn-worker-descriptor vn-quick-link[icon="person"] > a',
firstActionTicketId: 'vn-claim-summary > vn-card > vn-horizontal > vn-auto:nth-child(5) vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(2) > span',
firstActionTicketDescriptor: '.vn-popover.shown vn-ticket-descriptor'
},
claimBasicData: {
claimState: 'vn-claim-basic-data vn-autocomplete[ng-model="$ctrl.claim.claimStateFk"]',
packages: 'vn-input-number[ng-model="$ctrl.claim.packages"]',
saveButton: `button[type=submit]`
},
claimDetail: {
secondItemDiscount: 'vn-claim-detail > vn-vertical > vn-card > vn-vertical > vn-table > div > vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(6) > span',
discount: '.vn-popover.shown vn-input-number[ng-model="$ctrl.newDiscount"]',
discoutPopoverMana: '.vn-popover.shown .content > div > vn-horizontal > h5',
addItemButton: 'vn-claim-detail a vn-float-button',
firstClaimableSaleFromTicket: '.vn-dialog.shown vn-tbody > vn-tr',
claimDetailLine: 'vn-claim-detail > vn-vertical > vn-card > vn-vertical > vn-table > div > vn-tbody > vn-tr',
totalClaimed: 'vn-claim-detail > vn-vertical > vn-card > vn-vertical > vn-horizontal > div > vn-label-value:nth-child(2) > section > span',
secondItemDeleteButton: 'vn-claim-detail > vn-vertical > vn-card > vn-vertical > vn-table > div > vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(8) > vn-icon-button > button > vn-icon > i'
},
claimDevelopment: {
addDevelopmentButton: 'vn-claim-development > vn-vertical > vn-card > vn-vertical > vn-one > vn-icon-button > button > vn-icon',
firstDeleteDevelopmentButton: 'vn-claim-development > vn-vertical > vn-card > vn-vertical > form > vn-horizontal:nth-child(2) > vn-icon-button > button > vn-icon',
firstClaimReason: 'vn-claim-development vn-horizontal:nth-child(1) vn-autocomplete[ng-model="claimDevelopment.claimReasonFk"]',
firstClaimResult: 'vn-claim-development vn-horizontal:nth-child(1) vn-autocomplete[ng-model="claimDevelopment.claimResultFk"]',
firstClaimResponsible: 'vn-claim-development vn-horizontal:nth-child(1) vn-autocomplete[ng-model="claimDevelopment.claimResponsibleFk"]',
firstClaimWorker: 'vn-claim-development vn-horizontal:nth-child(1) vn-worker-autocomplete[ng-model="claimDevelopment.workerFk"]',
firstClaimRedelivery: 'vn-claim-development vn-horizontal:nth-child(1) vn-autocomplete[ng-model="claimDevelopment.claimRedeliveryFk"]',
secondClaimReason: 'vn-claim-development vn-horizontal:nth-child(2) vn-autocomplete[ng-model="claimDevelopment.claimReasonFk"]',
secondClaimResult: 'vn-claim-development vn-horizontal:nth-child(2) vn-autocomplete[ng-model="claimDevelopment.claimResultFk"]',
secondClaimResponsible: 'vn-claim-development vn-horizontal:nth-child(2) vn-autocomplete[ng-model="claimDevelopment.claimResponsibleFk"]',
secondClaimWorker: 'vn-claim-development vn-horizontal:nth-child(2) vn-worker-autocomplete[ng-model="claimDevelopment.workerFk"]',
secondClaimRedelivery: 'vn-claim-development vn-horizontal:nth-child(2) vn-autocomplete[ng-model="claimDevelopment.claimRedeliveryFk"]',
saveDevelopmentButton: 'button[type=submit]'
},
claimNote: {
addNoteFloatButton: 'vn-float-button',
note: 'vn-textarea[ng-model="$ctrl.note.text"]',
saveButton: 'button[type=submit]',
firstNoteText: 'vn-claim-note .text'
},
claimAction: {
importClaimButton: 'vn-claim-action vn-button[label="Import claim"]',
anyLine: 'vn-claim-action vn-tbody > vn-tr',
firstDeleteLine: 'vn-claim-action tr:nth-child(2) vn-icon-button[icon="delete"]',
isPaidWithManaCheckbox: 'vn-claim-action vn-check[ng-model="$ctrl.claim.isChargedToMana"]'
},
ordersIndex: { ordersIndex: {
secondSearchResultTotal: 'vn-order-index vn-card > vn-table > div > vn-tbody .vn-tr:nth-child(2) vn-td:nth-child(9)', secondSearchResultTotal: 'vn-order-index vn-card > vn-table > div > vn-tbody .vn-tr:nth-child(2) vn-td:nth-child(9)',
advancedSearchButton: 'vn-order-search-panel vn-submit[label="Search"]', advancedSearchButton: 'vn-order-search-panel vn-submit[label="Search"]',

View File

@ -1,29 +0,0 @@
import selectors from '../../../helpers/selectors.js';
import getBrowser from '../../../helpers/puppeteer';
describe('department summary path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('hr', 'worker');
await page.accessToSection('worker.department');
await page.doSearch('INFORMATICA');
await page.click(selectors.department.firstDepartment);
});
afterAll(async() => {
await browser.close();
});
it('should reach the employee summary section and check all properties', async() => {
expect(await page.waitToGetProperty(selectors.departmentSummary.header, 'innerText')).toEqual('INFORMATICA');
expect(await page.getProperty(selectors.departmentSummary.name, 'innerText')).toEqual('INFORMATICA');
expect(await page.getProperty(selectors.departmentSummary.code, 'innerText')).toEqual('it');
expect(await page.getProperty(selectors.departmentSummary.chat, 'innerText')).toEqual('informatica-cau');
expect(await page.getProperty(selectors.departmentSummary.bossDepartment, 'innerText')).toEqual('');
expect(await page.getProperty(selectors.departmentSummary.email, 'innerText')).toEqual('-');
expect(await page.getProperty(selectors.departmentSummary.clientFk, 'innerText')).toEqual('-');
});
});

View File

@ -1,43 +0,0 @@
import getBrowser from '../../../helpers/puppeteer';
import selectors from '../../../helpers/selectors.js';
const $ = {
form: 'vn-worker-department-basic-data form',
};
describe('department summary path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('hr', 'worker');
await page.accessToSection('worker.department');
await page.doSearch('INFORMATICA');
await page.click(selectors.department.firstDepartment);
});
beforeEach(async() => {
await page.accessToSection('worker.department.card.basicData');
});
afterAll(async() => {
await browser.close();
});
it(`should edit the department basic data and confirm the department data was edited`, async() => {
const values = {
Name: 'Informatica',
Code: 'IT',
Chat: 'informatica-cau',
Email: 'it@verdnatura.es',
};
await page.fillForm($.form, values);
const formValues = await page.fetchForm($.form, Object.keys(values));
const message = await page.sendForm($.form, values);
expect(message.isSuccess).toBeTrue();
expect(formValues).toEqual(values);
});
});

View File

@ -1,34 +0,0 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Worker summary path', () => {
const workerId = 3;
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('employee', 'worker');
const httpDataResponse = page.waitForResponse(response => {
return response.status() === 200 && response.url().includes(`Workers/${workerId}`);
});
await page.accessToSearchResult('agencyNick');
await httpDataResponse;
});
afterAll(async() => {
await browser.close();
});
it('should reach the employee summary section and check all properties', async() => {
expect(await page.getProperty(selectors.workerSummary.header, 'innerText')).toEqual('agency agency');
expect(await page.getProperty(selectors.workerSummary.id, 'innerText')).toEqual('3');
expect(await page.getProperty(selectors.workerSummary.email, 'innerText')).toEqual('agency@verdnatura.es');
expect(await page.getProperty(selectors.workerSummary.department, 'innerText')).toEqual('CAMARA');
expect(await page.getProperty(selectors.workerSummary.userId, 'innerText')).toEqual('3');
expect(await page.getProperty(selectors.workerSummary.userName, 'innerText')).toEqual('agency');
expect(await page.getProperty(selectors.workerSummary.role, 'innerText')).toEqual('agency');
expect(await page.getProperty(selectors.workerSummary.extension, 'innerText')).toEqual('1101');
expect(await page.getProperty(selectors.workerSummary.locker, 'innerText')).toEqual('-');
});
});

View File

@ -1,40 +0,0 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Worker basic data path', () => {
const workerId = 1106;
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('hr', 'worker');
const httpDataResponse = page.waitForResponse(response => {
return response.status() === 200 && response.url().includes(`Workers/${workerId}`);
});
await page.accessToSearchResult('David Charles Haller');
await httpDataResponse;
await page.accessToSection('worker.card.basicData');
});
afterAll(async() => {
await browser.close();
});
it('should edit the form and then reload the section and check the data was edited', async() => {
await page.overwrite(selectors.workerBasicData.name, 'David C.');
await page.overwrite(selectors.workerBasicData.surname, 'H.');
await page.overwrite(selectors.workerBasicData.phone, '444332211');
await page.click(selectors.workerBasicData.saveButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
await page.reloadSection('worker.card.basicData');
expect(await page.waitToGetProperty(selectors.workerBasicData.name, 'value')).toEqual('David C.');
expect(await page.waitToGetProperty(selectors.workerBasicData.surname, 'value')).toEqual('H.');
expect(await page.waitToGetProperty(selectors.workerBasicData.phone, 'value')).toEqual('444332211');
});
});

View File

@ -1,32 +0,0 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Worker pbx path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('hr', 'worker');
await page.accessToSearchResult('employee');
await page.accessToSection('worker.card.pbx');
});
afterAll(async() => {
await browser.close();
});
it('should receive an error when the extension exceeds 4 characters and then sucessfully save the changes', async() => {
await page.write(selectors.workerPbx.extension, '55555');
await page.click(selectors.workerPbx.saveButton);
let message = await page.waitForSnackbar();
expect(message.text).toContain('Extension format is invalid');
await page.overwrite(selectors.workerPbx.extension, '4444');
await page.click(selectors.workerPbx.saveButton);
message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved! User must access web');
});
});

View File

@ -1,65 +0,0 @@
/* eslint max-len: ["error", { "code": 150 }]*/
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Worker time control path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('salesBoss', 'worker');
await page.accessToSearchResult('HankPym');
await page.accessToSection('worker.card.timeControl');
});
afterAll(async() => {
await browser.close();
});
const eightAm = '08:00';
const fourPm = '16:00';
const hankPymId = 1107;
it('should go to the next month, go to current month and go 1 month in the past', async() => {
let date = Date.vnNew();
date.setDate(1);
date.setMonth(date.getMonth() + 1);
let month = date.toLocaleString('default', {month: 'long'});
await page.waitToClick(selectors.workerTimeControl.nextMonthButton);
let result = await page.getProperty(selectors.workerTimeControl.monthName, 'innerText');
expect(result).toContain(month);
date = Date.vnNew();
date.setDate(1);
month = date.toLocaleString('default', {month: 'long'});
await page.waitToClick(selectors.workerTimeControl.previousMonthButton);
result = await page.getProperty(selectors.workerTimeControl.monthName, 'innerText');
expect(result).toContain(month);
date = Date.vnNew();
date.setDate(1);
date.setMonth(date.getMonth() - 1);
const timestamp = Math.round(date.getTime() / 1000);
month = date.toLocaleString('default', {month: 'long'});
await page.loginAndModule('salesBoss', 'worker');
await page.goto(`http://localhost:5000/#!/worker/${hankPymId}/time-control?timestamp=${timestamp}`);
await page.waitToClick(selectors.workerTimeControl.secondWeekDay);
result = await page.getProperty(selectors.workerTimeControl.monthName, 'innerText');
expect(result).toContain(month);
});
it('should change week of month', async() => {
await page.click(selectors.workerTimeControl.thrirdWeekDay);
const result = await page.getProperty(selectors.workerTimeControl.mondayWorkedHours, 'innerText');
expect(result).toEqual('00:00 h.');
});
});

View File

@ -1,114 +0,0 @@
/* eslint-disable max-len */
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Worker calendar path', () => {
const reasonableTimeBetweenClicks = 300;
const date = Date.vnNew();
const lastYear = (date.getFullYear() - 1).toString();
let browser;
let page;
async function accessAs(user) {
await page.loginAndModule(user, 'worker');
await page.accessToSearchResult('Charles Xavier');
await page.accessToSection('worker.card.calendar');
}
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
accessAs('hr');
});
afterAll(async() => {
await browser.close();
});
describe('as hr', () => {
it('should set two days as holidays on the calendar and check the total holidays increased by 1.5', async() => {
await page.waitToClick(selectors.workerCalendar.holidays);
await page.waitForTimeout(reasonableTimeBetweenClicks);
await page.click(selectors.workerCalendar.penultimateMondayOfJanuary);
await page.waitForTimeout(reasonableTimeBetweenClicks);
await page.click(selectors.workerCalendar.absence);
await page.waitForTimeout(reasonableTimeBetweenClicks);
await page.click(selectors.workerCalendar.lastMondayOfMarch);
await page.waitForTimeout(reasonableTimeBetweenClicks);
await page.click(selectors.workerCalendar.halfHoliday);
await page.waitForTimeout(reasonableTimeBetweenClicks);
await page.click(selectors.workerCalendar.fistMondayOfMay);
await page.waitForTimeout(reasonableTimeBetweenClicks);
await page.click(selectors.workerCalendar.furlough);
await page.waitForTimeout(reasonableTimeBetweenClicks);
await page.click(selectors.workerCalendar.secondTuesdayOfMay);
await page.waitForTimeout(reasonableTimeBetweenClicks);
await page.click(selectors.workerCalendar.secondWednesdayOfMay);
await page.waitForTimeout(reasonableTimeBetweenClicks);
await page.click(selectors.workerCalendar.secondThursdayOfMay);
await page.waitForTimeout(reasonableTimeBetweenClicks);
await page.click(selectors.workerCalendar.halfFurlough);
await page.waitForTimeout(reasonableTimeBetweenClicks);
await page.click(selectors.workerCalendar.secondFridayOfJun);
expect(await page.getProperty(selectors.workerCalendar.totalHolidaysUsed, 'innerText')).toContain(' 1.5 ');
});
});
describe(`as salesBoss`, () => {
it(`should log in, get to Charles Xavier's calendar, undo what was done here, and check the total holidays used are back to what it was`, async() => {
accessAs('salesBoss');
await page.waitToClick(selectors.workerCalendar.holidays);
await page.waitForTimeout(reasonableTimeBetweenClicks);
await page.waitToClick(selectors.workerCalendar.penultimateMondayOfJanuary);
await page.waitForTimeout(reasonableTimeBetweenClicks);
await page.waitToClick(selectors.workerCalendar.absence);
await page.waitForTimeout(reasonableTimeBetweenClicks);
await page.waitToClick(selectors.workerCalendar.lastMondayOfMarch);
await page.waitForTimeout(reasonableTimeBetweenClicks);
await page.waitToClick(selectors.workerCalendar.halfHoliday);
await page.waitForTimeout(reasonableTimeBetweenClicks);
await page.waitToClick(selectors.workerCalendar.fistMondayOfMay);
await page.waitForTimeout(reasonableTimeBetweenClicks);
await page.waitToClick(selectors.workerCalendar.furlough);
await page.waitForTimeout(reasonableTimeBetweenClicks);
await page.waitToClick(selectors.workerCalendar.secondTuesdayOfMay);
await page.waitForTimeout(reasonableTimeBetweenClicks);
await page.waitToClick(selectors.workerCalendar.secondWednesdayOfMay);
await page.waitForTimeout(reasonableTimeBetweenClicks);
await page.waitToClick(selectors.workerCalendar.secondThursdayOfMay);
await page.waitForTimeout(reasonableTimeBetweenClicks);
await page.waitToClick(selectors.workerCalendar.halfFurlough);
await page.waitForTimeout(reasonableTimeBetweenClicks);
await page.waitToClick(selectors.workerCalendar.secondFridayOfJun);
expect(await page.getProperty(selectors.workerCalendar.totalHolidaysUsed, 'innerText')).toContain(' 0 ');
});
});
describe(`as Charles Xavier`, () => {
it('should log in and get to his calendar, make a futile attempt to add holidays, check the total holidays used are now the initial ones and use the year selector to go to the previous year', async() => {
accessAs('CharlesXavier');
await page.waitToClick(selectors.workerCalendar.holidays);
await page.waitForTimeout(reasonableTimeBetweenClicks);
await page.click(selectors.workerCalendar.penultimateMondayOfJanuary);
expect(await page.getProperty(selectors.workerCalendar.totalHolidaysUsed, 'innerText')).toContain(' 0 ');
await page.autocompleteSearch(selectors.workerCalendar.year, lastYear);
expect(await page.getProperty(selectors.workerCalendar.totalHolidaysUsed, 'innerText')).toContain(' 0 ');
});
});
});

View File

@ -1,73 +0,0 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Worker create path', () => {
let browser;
let page;
let newWorker;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('hr', 'worker');
await page.waitToClick(selectors.workerCreate.newWorkerButton);
await page.waitForState('worker.create');
});
afterAll(async() => {
await browser.close();
});
it('should insert default data', async() => {
await page.write(selectors.workerCreate.firstname, 'Victor');
await page.write(selectors.workerCreate.lastname, 'Von Doom');
await page.write(selectors.workerCreate.fi, '78457139E');
await page.write(selectors.workerCreate.phone, '12356789');
await page.write(selectors.workerCreate.postcode, '46680');
await page.write(selectors.workerCreate.street, 'S/ DOOMSTADT');
await page.write(selectors.workerCreate.email, 'doctorDoom@marvel.com');
await page.write(selectors.workerCreate.iban, 'ES9121000418450200051332');
// should check for autocompleted worker code and worker user name
const workerCode = await page
.waitToGetProperty(selectors.workerCreate.code, 'value');
newWorker = await page
.waitToGetProperty(selectors.workerCreate.user, 'value');
expect(workerCode).toEqual('VVD');
expect(newWorker).toContain('victorvd');
// should fail if necessary data is void
await page.waitToClick(selectors.workerCreate.createButton);
let message = await page.waitForSnackbar();
expect(message.text).toContain('is a required argument');
// should create a new worker and go to worker basic data'
await page.pickDate(selectors.workerCreate.birth, new Date(1962, 8, 5));
await page.autocompleteSearch(selectors.workerCreate.boss, 'deliveryAssistant');
await page.waitToClick(selectors.workerCreate.createButton);
message = await page.waitForSnackbar();
await page.waitForState('worker.card.basicData');
expect(message.text).toContain('Data saved!');
// 'rollback'
await page.loginAndModule('itManagement', 'account');
await page.accessToSearchResult(newWorker);
await page.waitToClick(selectors.accountDescriptor.menuButton);
await page.waitToClick(selectors.accountDescriptor.deactivateUser);
await page.waitToClick(selectors.accountDescriptor.acceptButton);
message = await page.waitForSnackbar();
expect(message.text).toContain('User deactivated!');
await page.waitToClick(selectors.accountDescriptor.menuButton);
await page.waitToClick(selectors.accountDescriptor.disableAccount);
await page.waitToClick(selectors.accountDescriptor.acceptButton);
message = await page.waitForSnackbar();
expect(message.text).toContain('Account disabled!');
});
});

View File

@ -1,42 +0,0 @@
import selectors from '../../helpers/selectors';
import getBrowser from '../../helpers/puppeteer';
describe('Worker Add notes path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('hr', 'worker');
await page.accessToSearchResult('Bruce Banner');
await page.accessToSection('worker.card.note.index');
});
afterAll(async() => {
await browser.close();
});
it(`should reach the notes index`, async() => {
await page.waitForState('worker.card.note.index');
});
it(`should click on the add note button`, async() => {
await page.waitToClick(selectors.workerNotes.addNoteFloatButton);
await page.waitForState('worker.card.note.create');
});
it(`should create a note`, async() => {
await page.waitForSelector(selectors.workerNotes.note);
await page.type(`${selectors.workerNotes.note} textarea`, 'Meeting with Black Widow 21st 9am');
await page.waitToClick(selectors.workerNotes.saveButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it('should confirm the note was created', async() => {
const result = await page.waitToGetProperty(selectors.workerNotes.firstNoteText, 'innerText');
expect(result).toEqual('Meeting with Black Widow 21st 9am');
});
});

View File

@ -19,7 +19,9 @@ describe('Ticket Edit sale path', () => {
it(`should click on the first sale claim icon to navigate over there`, async() => { it(`should click on the first sale claim icon to navigate over there`, async() => {
await page.waitToClick(selectors.ticketSales.firstSaleClaimIcon); await page.waitToClick(selectors.ticketSales.firstSaleClaimIcon);
await page.waitForState('claim.card.basicData'); await page.waitForNavigation();
await page.goBack();
await page.goBack();
}); });
it('should navigate to the tickets index', async() => { it('should navigate to the tickets index', async() => {
@ -243,29 +245,13 @@ describe('Ticket Edit sale path', () => {
await page.waitToClick(selectors.ticketSales.moreMenu); await page.waitToClick(selectors.ticketSales.moreMenu);
await page.waitToClick(selectors.ticketSales.moreMenuCreateClaim); await page.waitToClick(selectors.ticketSales.moreMenuCreateClaim);
await page.waitToClick(selectors.globalItems.acceptButton); await page.waitToClick(selectors.globalItems.acceptButton);
await page.waitForState('claim.card.basicData'); await page.waitForNavigation();
});
it('should click on the Claims button of the top bar menu', async() => {
await page.waitToClick(selectors.globalItems.applicationsMenuButton);
await page.waitForSelector(selectors.globalItems.applicationsMenuVisible);
await page.waitToClick(selectors.globalItems.claimsButton);
await page.waitForState('claim.index');
});
it('should search for the claim with id 4', async() => {
await page.accessToSearchResult('4');
await page.waitForState('claim.card.summary');
});
it('should click the Tickets button of the top bar menu', async() => {
await page.waitToClick(selectors.globalItems.applicationsMenuButton);
await page.waitForSelector(selectors.globalItems.applicationsMenuVisible);
await page.waitToClick(selectors.globalItems.ticketsButton);
await page.waitForState('ticket.index');
}); });
it('should search for a ticket then access to the sales section', async() => { it('should search for a ticket then access to the sales section', async() => {
await page.goBack();
await page.goBack();
await page.loginAndModule('salesPerson', 'ticket');
await page.accessToSearchResult('16'); await page.accessToSearchResult('16');
await page.accessToSection('ticket.card.sale'); await page.accessToSection('ticket.card.sale');
}); });

View File

@ -1,61 +0,0 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Claim edit basic data path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
});
afterAll(async() => {
await browser.close();
});
it(`should log in as claimManager then reach basic data of the target claim`, async() => {
await page.loginAndModule('claimManager', 'claim');
await page.accessToSearchResult('1');
await page.accessToSection('claim.card.basicData');
});
it(`should edit claim state and observation fields`, async() => {
await page.autocompleteSearch(selectors.claimBasicData.claimState, 'Resuelto');
await page.clearInput(selectors.claimBasicData.packages);
await page.write(selectors.claimBasicData.packages, '2');
await page.waitToClick(selectors.claimBasicData.saveButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it(`should have been redirected to the next section of claims as the role is claimManager`, async() => {
await page.waitForState('claim.card.detail');
});
it('should confirm the claim state was edited', async() => {
await page.reloadSection('claim.card.basicData');
await page.waitForSelector(selectors.claimBasicData.claimState);
const result = await page.waitToGetProperty(selectors.claimBasicData.claimState, 'value');
expect(result).toEqual('Resuelto');
});
it('should confirm the claim packages was edited', async() => {
const result = await page
.waitToGetProperty(selectors.claimBasicData.packages, 'value');
expect(result).toEqual('2');
});
it(`should edit the claim to leave it untainted`, async() => {
await page.autocompleteSearch(selectors.claimBasicData.claimState, 'Pendiente');
await page.clearInput(selectors.claimBasicData.packages);
await page.write(selectors.claimBasicData.packages, '0');
await page.waitToClick(selectors.claimBasicData.saveButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
});

View File

@ -1,54 +0,0 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer.js';
describe('Claim action path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('claimManager', 'claim');
await page.accessToSearchResult('2');
await page.accessToSection('claim.card.action');
});
afterAll(async() => {
await browser.close();
});
it('should import the claim', async() => {
await page.waitToClick(selectors.claimAction.importClaimButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it('should delete the first line', async() => {
await page.waitToClick(selectors.claimAction.firstDeleteLine);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it('should refresh the view to check not have lines', async() => {
await page.reloadSection('claim.card.action');
const result = await page.countElement(selectors.claimAction.anyLine);
expect(result).toEqual(0);
});
it('should check the "is paid with mana" checkbox', async() => {
await page.waitToClick(selectors.claimAction.isPaidWithManaCheckbox);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it('should confirm the "is paid with mana" is checked', async() => {
await page.reloadSection('claim.card.action');
const isPaidWithManaCheckbox = await page.checkboxState(selectors.claimAction.isPaidWithManaCheckbox);
expect(isPaidWithManaCheckbox).toBe('checked');
});
});

View File

@ -1,96 +0,0 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer.js';
describe('Claim summary path', () => {
let browser;
let page;
const claimId = '4';
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
});
afterAll(async() => {
await browser.close();
});
it('should navigate to the target claim summary section', async() => {
await page.loginAndModule('salesPerson', 'claim');
await page.accessToSearchResult(claimId);
await page.waitForState('claim.card.summary');
});
it(`should display details from the claim and it's client on the top of the header`, async() => {
await page.waitForTextInElement(selectors.claimSummary.header, 'Tony Stark');
const result = await page.waitToGetProperty(selectors.claimSummary.header, 'innerText');
expect(result).toContain('4 -');
expect(result).toContain('Tony Stark');
});
it('should display the claim state', async() => {
const result = await page.waitToGetProperty(selectors.claimSummary.state, 'innerText');
expect(result).toContain('Resuelto');
});
it('should display the observation', async() => {
const result = await page.waitToGetProperty(selectors.claimSummary.observation, 'innerText');
expect(result).toContain('Wisi forensibus mnesarchum in cum. Per id impetus abhorreant');
});
it('should display the claimed line(s)', async() => {
const result = await page.waitToGetProperty(selectors.claimSummary.firstSaleItemId, 'innerText');
expect(result).toContain('2');
});
it(`should click on the first sale ID making the item descriptor visible`, async() => {
const firstItem = selectors.claimSummary.firstSaleItemId;
await page.evaluate(selectors => {
document.querySelector(selectors).scrollIntoView();
}, firstItem);
await page.click(firstItem);
await page.waitImgLoad(selectors.claimSummary.firstSaleDescriptorImage);
const visible = await page.isVisible(selectors.claimSummary.itemDescriptorPopover);
expect(visible).toBeTruthy();
});
it(`should check the url for the item diary link of the descriptor is for the right item id`, async() => {
await page.waitForSelector(selectors.claimSummary.itemDescriptorPopoverItemDiaryButton, {visible: true});
await page.closePopup();
});
it('should display the claim development details', async() => {
const result = await page.waitToGetProperty(selectors.claimSummary.firstDevelopmentWorker, 'innerText');
expect(result).toContain('salesAssistantNick');
});
it(`should click on the first development worker making the worker descriptor visible`, async() => {
await page.waitToClick(selectors.claimSummary.firstDevelopmentWorker);
const visible = await page.isVisible(selectors.claimSummary.firstDevelopmentWorkerGoToClientButton);
expect(visible).toBeTruthy();
});
it(`should check the url for the go to clientlink of the descriptor is for the right client id`, async() => {
await page.waitForSelector(selectors.claimSummary.firstDevelopmentWorkerGoToClientButton, {visible: true});
await page.closePopup();
});
it(`should click on the first action ticket ID making the ticket descriptor visible`, async() => {
await page.waitToClick(selectors.claimSummary.firstActionTicketId);
await page.waitForSelector(selectors.claimSummary.firstActionTicketDescriptor);
const visible = await page.isVisible(selectors.claimSummary.firstActionTicketDescriptor);
expect(visible).toBeTruthy();
});
});

View File

@ -1,58 +0,0 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer.js';
describe('Claim descriptor path', () => {
let browser;
let page;
const claimId = '1';
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
});
afterAll(async() => {
await browser.close();
});
it('should now navigate to the target claim summary section', async() => {
await page.loginAndModule('salesPerson', 'claim');
await page.accessToSearchResult(claimId);
await page.waitForState('claim.card.summary');
});
it(`should not be able to see the delete claim button of the descriptor more menu`, async() => {
await page.waitToClick(selectors.claimDescriptor.moreMenu);
await page.waitForSelector(selectors.claimDescriptor.moreMenuDeleteClaim, {hidden: true});
});
it(`should log in as claimManager and navigate to the target claim`, async() => {
await page.loginAndModule('claimManager', 'claim');
await page.accessToSearchResult(claimId);
await page.waitForState('claim.card.summary');
});
it(`should be able to see the delete claim button of the descriptor more menu`, async() => {
await page.waitToClick(selectors.claimDescriptor.moreMenu);
await page.waitForSelector(selectors.claimDescriptor.moreMenuDeleteClaim, {visible: true});
});
it(`should delete the claim`, async() => {
await page.waitToClick(selectors.claimDescriptor.moreMenuDeleteClaim);
await page.waitToClick(selectors.claimDescriptor.acceptDeleteClaim);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Claim deleted!');
});
it(`should have been relocated to the claim index`, async() => {
await page.waitForState('claim.index');
});
it(`should search for the deleted claim to find no results`, async() => {
await page.doSearch(claimId);
const nResults = await page.countElement(selectors.claimsIndex.searchResult);
expect(nResults).toEqual(0);
});
});

View File

@ -1,46 +0,0 @@
import selectors from '../../helpers/selectors';
import getBrowser from '../../helpers/puppeteer';
describe('Claim Add note path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('salesPerson', 'claim');
await page.accessToSearchResult('2');
await page.accessToSection('claim.card.note.index');
});
afterAll(async() => {
await browser.close();
});
it(`should reach the claim note index`, async() => {
await page.waitForState('claim.card.note.index');
});
it(`should click on the add new note button`, async() => {
await page.waitToClick(selectors.claimNote.addNoteFloatButton);
await page.waitForState('claim.card.note.create');
});
it(`should create a new note`, async() => {
await page.waitForSelector(selectors.claimNote.note);
await page.type(`${selectors.claimNote.note} textarea`, 'The delivery was unsuccessful');
await page.waitToClick(selectors.claimNote.saveButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it(`should redirect back to the claim notes page`, async() => {
await page.waitForState('claim.card.note.index');
});
it('should confirm the note was created', async() => {
const result = await page.waitToGetProperty(selectors.claimNote.firstNoteText, 'innerText');
expect(result).toEqual('The delivery was unsuccessful');
});
});

View File

@ -41,7 +41,6 @@ async function test() {
`./e2e/paths/03*/*[sS]pec.js`, `./e2e/paths/03*/*[sS]pec.js`,
`./e2e/paths/04*/*[sS]pec.js`, `./e2e/paths/04*/*[sS]pec.js`,
`./e2e/paths/05*/*[sS]pec.js`, `./e2e/paths/05*/*[sS]pec.js`,
`./e2e/paths/06*/*[sS]pec.js`,
`./e2e/paths/07*/*[sS]pec.js`, `./e2e/paths/07*/*[sS]pec.js`,
`./e2e/paths/08*/*[sS]pec.js`, `./e2e/paths/08*/*[sS]pec.js`,
`./e2e/paths/09*/*[sS]pec.js`, `./e2e/paths/09*/*[sS]pec.js`,

View File

@ -368,5 +368,6 @@
"Payment method is required": "El método de pago es obligatorio", "Payment method is required": "El método de pago es obligatorio",
"Cannot send mail": "Não é possível enviar o email", "Cannot send mail": "Não é possível enviar o email",
"CONSTRAINT `supplierAccountTooShort` failed for `vn`.`supplier`": "La cuenta debe tener exactamente 10 dígitos", "CONSTRAINT `supplierAccountTooShort` failed for `vn`.`supplier`": "La cuenta debe tener exactamente 10 dígitos",
"The sale not exists in the item shelving": "La venta no existe en la estantería del artículo" "The sale not exists in the item shelving": "La venta no existe en la estantería del artículo",
"The entry not have stickers": "La entrada no tiene etiquetas"
} }

View File

@ -1,188 +0,0 @@
<vn-crud-model vn-id="model"
url="ClaimEnds/filter"
link="{claimFk: $ctrl.$params.id}"
data="$ctrl.salesClaimed"
auto-load="true"
on-save="$ctrl.onSave()">
</vn-crud-model>
<vn-crud-model
auto-load="true"
url="ClaimDestinations"
data="claimDestinations">
</vn-crud-model>
<vn-card class="vn-mb-md vn-pa-lg vn-w-lg" style="text-align: right"
ng-if="$ctrl.salesClaimed.length > 0">
<vn-label-value label="Total claimed"
value="{{$ctrl.claimedTotal | currency: 'EUR':2}}">
</vn-label-value>
</vn-card>
<vn-card class="vn-pa-md vn-w-lg">
<smart-table
model="model"
options="$ctrl.smartTableOptions"
expr-builder="$ctrl.exprBuilder(param, value)">
<slot-actions>
<section class="header">
<vn-tool-bar class="vn-mb-md">
<vn-button
label="Import claim"
disabled="$ctrl.claim.claimStateFk == $ctrl.resolvedStateId"
vn-http-click="$ctrl.importToNewRefundTicket()"
translate-attr="{title: 'Imports claim details'}">
</vn-button>
<vn-button
label="Change destination"
disabled="$ctrl.checked.length == 0"
ng-click="changeDestination.show()">
</vn-button>
<vn-range
label="Responsability"
min-label="Company"
max-label="Sales/Client"
ng-model="$ctrl.claim.responsibility"
max="$ctrl.maxResponsibility"
min="1"
step="1"
on-change="$ctrl.save({responsibility: value})">
</vn-range>
<vn-check class="right"
vn-one
label="Is paid with mana"
ng-model="$ctrl.claim.isChargedToMana"
on-change="$ctrl.save({isChargedToMana: value})">
</vn-check>
</vn-tool-bar>
</section>
</slot-actions>
<slot-table>
<table model="model">
<thead>
<tr>
<th shrink>
<vn-multi-check
model="model"
check-field="$checked">
</vn-multi-check>
</th>
<th number field="itemFk">Id</th>
<th number field="ticketFk">Ticket</th>
<th field="claimDestinationFk">
<span translate>Destination</span>
</th>
<th expand field="landed">
<span translate>Landed</span>
</th>
<th number field="quantity">
<span translate>Quantity</span>
</th>
<th field="concept">
<span translate>Description</span>
</th>
<th number field="price">
<span translate>Price</span>
</th>
<th number field="discount">
<span translate>Disc.</span>
</th>
<th number field="total">Total</th>
</tr>
</thead>
<tbody>
<tr
ng-repeat="saleClaimed in $ctrl.salesClaimed"
vn-repeat-last on-last="$ctrl.focusLastInput()">
<td>
<vn-check
ng-model="saleClaimed.$checked"
vn-click-stop>
</vn-check>
</td>
<td number>
<vn-span
ng-click="itemDescriptor.show($event, saleClaimed.itemFk)"
class="link">
{{::saleClaimed.itemFk}}
</vn-span>
</td>
<td number>
<vn-span
class="link"
ng-click="ticketDescriptor.show($event, saleClaimed.ticketFk)">
{{::saleClaimed.ticketFk}}
</vn-span>
</td>
<td expand>
<vn-autocomplete vn-one id="claimDestinationFk"
ng-model="saleClaimed.claimDestinationFk"
data="claimDestinations"
on-change="$ctrl.updateDestination(saleClaimed, value)"
fields="['id','description']"
value-field="id"
show-field="description">
</vn-autocomplete>
</td>
<td expand>{{::saleClaimed.landed | date: 'dd/MM/yyyy'}}</td>
<td number>{{::saleClaimed.quantity}}</td>
<td expand>{{::saleClaimed.concept}}</td>
<td number>{{::saleClaimed.price | currency: 'EUR':2}}</td>
<td number>{{::saleClaimed.discount}} %</td>
<td number>{{saleClaimed.total | currency: 'EUR':2}}</td>
<td shrink>
<vn-icon-button
vn-tooltip="Remove line"
icon="delete"
ng-click="$ctrl.removeSales(saleClaimed)"
tabindex="-1">
</vn-icon-button>
</td>
</tr>
</tbody>
</table>
</slot-table>
</smart-table>
<button-bar class="vn-pa-md">
<vn-button
label="Regularize"
disabled="$ctrl.claim.claimStateFk == $ctrl.resolvedStateId"
vn-http-click="$ctrl.regularize()">
</vn-button>
</button-bar>
</vn-card>
<vn-item-descriptor-popover
vn-id="item-descriptor"
warehouse-fk="$ctrl.vnConfig.warehouseFk">
</vn-item-descriptor-popover>
<vn-ticket-descriptor-popover
vn-id="ticket-descriptor">
</vn-ticket-descriptor-popover>
<vn-confirm
vn-id="update-greuge"
question="Insert greuges on client card"
message="Do you want to insert greuges?"
on-accept="$ctrl.onUpdateGreugeAccept()">
</vn-confirm>
<!-- Dialog of change destionation -->
<vn-dialog
vn-id="changeDestination"
on-accept="$ctrl.onResponse()">
<tpl-body>
<section class="SMSDialog">
<h5 class="vn-py-sm">{{$ctrl.$t('Change destination to all selected rows', {total: $ctrl.checked.length})}}</h5>
<vn-horizontal>
<vn-autocomplete vn-one id="claimDestinationFk"
ng-model="$ctrl.newDestination"
data="claimDestinations"
fields="['id','description']"
value-field="id"
show-field="description"
vn-focus>
</vn-autocomplete>
</vn-horizontal>
</section>
</tpl-body>
<tpl-buttons>
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
<button response="accept" translate>Save</button>
</tpl-buttons>
</vn-dialog>

View File

@ -1,233 +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.newDestination;
this.filter = {
include: [
{relation: 'sale',
scope: {
fields: ['concept', 'ticketFk', 'price', 'quantity', 'discount', 'itemFk'],
include: {
relation: 'ticket'
}
}
},
{relation: 'claimBeggining'},
{relation: 'claimDestination'}
]
};
this.getResolvedState();
this.maxResponsibility = 5;
this.smartTableOptions = {
activeButtons: {
search: true
},
columns: [
{
field: 'claimDestinationFk',
autocomplete: {
url: 'ClaimDestinations',
showField: 'description',
valueField: 'id'
}
},
{
field: 'landed',
searchable: false
}
]
};
}
exprBuilder(param, value) {
switch (param) {
case 'itemFk':
case 'ticketFk':
case 'claimDestinationFk':
case 'quantity':
case 'price':
case 'discount':
case 'total':
return {[param]: value};
case 'concept':
return {[param]: {like: `%${value}%`}};
case 'landed':
return {[param]: {between: this.dateRange(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];
}
get checked() {
const salesClaimed = this.$.model.data || [];
const checkedSalesClaimed = [];
for (let saleClaimed of salesClaimed) {
if (saleClaimed.$checked)
checkedSalesClaimed.push(saleClaimed);
}
return checkedSalesClaimed;
}
updateDestination(saleClaimed, claimDestinationFk) {
const data = {rows: [saleClaimed], claimDestinationFk: claimDestinationFk};
this.$http.post(`Claims/updateClaimDestination`, data).then(() => {
this.vnApp.showSuccess(this.$t('Data saved!'));
}).catch(e => {
this.$.model.refresh();
throw e;
});
}
removeSales(saleClaimed) {
const params = {sales: [saleClaimed]};
this.$http.post(`ClaimEnds/deleteClamedSales`, params).then(() => {
this.$.model.refresh();
this.vnApp.showSuccess(this.$t('Data saved!'));
});
}
getResolvedState() {
const query = `ClaimStates/findOne`;
const params = {
filter: {
where: {
code: 'resolved'
}
}
};
this.$http.get(query, params).then(res =>
this.resolvedStateId = res.data.id
);
}
importToNewRefundTicket() {
let query = `ClaimBeginnings/${this.$params.id}/importToNewRefundTicket`;
return this.$http.post(query).then(() => {
this.$.model.refresh();
this.vnApp.showSuccess(this.$t('Data saved!'));
});
}
focusLastInput() {
let inputs = document.querySelectorAll('#claimDestinationFk');
inputs[inputs.length - 1].querySelector('input').focus();
this.calculateTotals();
}
calculateTotals() {
this.claimedTotal = 0;
this.salesClaimed.forEach(sale => {
const price = sale.quantity * sale.price;
const discount = (sale.discount * (sale.quantity * sale.price)) / 100;
this.claimedTotal += price - discount;
});
}
regularize() {
const query = `Claims/${this.$params.id}/regularizeClaim`;
return this.$http.post(query).then(() => {
if (this.claim.responsibility >= Math.ceil(this.maxResponsibility) / 2)
this.$.updateGreuge.show();
else
this.vnApp.showSuccess(this.$t('Data saved!'));
this.card.reload();
});
}
getGreugeTypeId() {
const params = {filter: {where: {code: 'freightPickUp'}}};
const query = `GreugeTypes/findOne`;
return this.$http.get(query, {params}).then(res => {
this.greugeTypeFreightId = res.data.id;
return res;
});
}
getGreugeConfig() {
const query = `GreugeConfigs/findOne`;
return this.$http.get(query).then(res => {
this.freightPickUpPrice = res.data.freightPickUpPrice;
return res;
});
}
onUpdateGreugeAccept() {
const promises = [];
promises.push(this.getGreugeTypeId());
promises.push(this.getGreugeConfig());
return Promise.all(promises).then(() => {
return this.updateGreuge({
clientFk: this.claim.clientFk,
description: this.$t('ClaimGreugeDescription', {
claimId: this.claim.id
}).toUpperCase(),
amount: this.freightPickUpPrice,
greugeTypeFk: this.greugeTypeFreightId,
ticketFk: this.claim.ticketFk
});
});
}
updateGreuge(data) {
return this.$http.post(`Greuges`, data).then(() => {
this.vnApp.showSuccess(this.$t('Data saved!'));
this.vnApp.showMessage(this.$t('Greuge added'));
});
}
save(data) {
const query = `Claims/${this.$params.id}/updateClaimAction`;
this.$http.patch(query, data)
.then(() => this.vnApp.showSuccess(this.$t('Data saved!')));
}
onSave() {
this.vnApp.showSuccess(this.$t('Data saved!'));
}
onResponse() {
const rowsToEdit = [];
for (let row of this.checked)
rowsToEdit.push({id: row.id});
const data = {
rows: rowsToEdit,
claimDestinationFk: this.newDestination
};
const query = `Claims/updateClaimDestination`;
this.$http.post(query, data)
.then(() => {
this.$.model.refresh();
this.vnApp.showSuccess(this.$t('Data saved!'));
});
}
}
ngModule.vnComponent('vnClaimAction', {
template: require('./index.html'),
controller: Controller,
bindings: {
claim: '<'
},
require: {
card: '^vnClaimCard'
}
});

View File

@ -1,167 +0,0 @@
import './index.js';
import crudModel from 'core/mocks/crud-model';
describe('claim', () => {
describe('Component vnClaimAction', () => {
let controller;
let $httpBackend;
let $state;
beforeEach(ngModule('claim'));
beforeEach(inject(($componentController, _$state_, _$httpBackend_) => {
$httpBackend = _$httpBackend_;
$state = _$state_;
$state.params.id = 1;
controller = $componentController('vnClaimAction', {$element: null});
controller.claim = {ticketFk: 1};
controller.$.model = {refresh: () => {}};
controller.$.addSales = {
hide: () => {},
show: () => {}
};
controller.$.lastTicketsModel = crudModel;
controller.$.lastTicketsPopover = {
hide: () => {},
show: () => {}
};
controller.card = {reload: () => {}};
$httpBackend.expectGET(`ClaimStates/findOne`).respond({});
}));
describe('getResolvedState()', () => {
it('should return the resolved state id', () => {
$httpBackend.expectGET(`ClaimStates/findOne`).respond({id: 1});
controller.getResolvedState();
$httpBackend.flush();
expect(controller.resolvedStateId).toEqual(1);
});
});
describe('calculateTotals()', () => {
it('should calculate the total price of the items claimed', () => {
controller.salesClaimed = [
{quantity: 5, price: 2, discount: 0},
{quantity: 10, price: 2, discount: 0},
{quantity: 10, price: 2, discount: 0}
];
controller.calculateTotals();
expect(controller.claimedTotal).toEqual(50);
});
});
describe('importToNewRefundTicket()', () => {
it('should perform a post query and add lines from a new ticket', () => {
jest.spyOn(controller.$.model, 'refresh');
jest.spyOn(controller.vnApp, 'showSuccess');
$httpBackend.expect('POST', `ClaimBeginnings/1/importToNewRefundTicket`).respond({});
controller.importToNewRefundTicket();
$httpBackend.flush();
expect(controller.$.model.refresh).toHaveBeenCalled();
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
});
});
describe('regularize()', () => {
it('should perform a post query and reload the claim card', () => {
jest.spyOn(controller.card, 'reload');
jest.spyOn(controller.vnApp, 'showSuccess');
$httpBackend.expect('POST', `Claims/1/regularizeClaim`).respond({});
controller.regularize();
$httpBackend.flush();
expect(controller.card.reload).toHaveBeenCalledWith();
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
});
});
describe('save()', () => {
it('should perform a patch query and show a success message', () => {
jest.spyOn(controller.vnApp, 'showSuccess');
const data = {pickup: 'agency'};
$httpBackend.expect('PATCH', `Claims/1/updateClaimAction`, data).respond({});
controller.save(data);
$httpBackend.flush();
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
});
});
describe('onUpdateGreugeAccept()', () => {
const greugeTypeId = 7;
const freightPickUpPrice = 11;
it('should make a query and get the greugeTypeId and greuge config', () => {
$httpBackend.expectRoute('GET', `GreugeTypes/findOne`).respond({id: greugeTypeId});
$httpBackend.expectGET(`GreugeConfigs/findOne`).respond({freightPickUpPrice});
controller.onUpdateGreugeAccept();
$httpBackend.flush();
expect(controller.greugeTypeFreightId).toEqual(greugeTypeId);
expect(controller.freightPickUpPrice).toEqual(freightPickUpPrice);
});
it('should perform a insert into greuges', done => {
jest.spyOn(controller, 'getGreugeTypeId').mockReturnValue(new Promise(resolve => {
return resolve({id: greugeTypeId});
}));
jest.spyOn(controller, 'getGreugeConfig').mockReturnValue(new Promise(resolve => {
return resolve({freightPickUpPrice});
}));
jest.spyOn(controller, 'updateGreuge').mockReturnValue(new Promise(resolve => {
return resolve(true);
}));
controller.claim.clientFk = 1101;
controller.claim.id = 11;
controller.onUpdateGreugeAccept().then(() => {
expect(controller.updateGreuge).toHaveBeenCalledWith(jasmine.any(Object));
done();
}).catch(done.fail);
});
});
describe('updateGreuge()', () => {
it('should make a query and then call to showSuccess() and showMessage() methods', () => {
jest.spyOn(controller.vnApp, 'showSuccess');
jest.spyOn(controller.vnApp, 'showMessage');
const freightPickUpPrice = 11;
const greugeTypeId = 7;
const expectedData = {
clientFk: 1101,
description: `claim: ${controller.claim.id}`,
amount: freightPickUpPrice,
greugeTypeFk: greugeTypeId,
ticketFk: controller.claim.ticketFk
};
$httpBackend.expect('POST', `Greuges`, expectedData).respond(200);
controller.updateGreuge(expectedData);
$httpBackend.flush();
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
expect(controller.vnApp.showMessage).toHaveBeenCalledWith('Greuge added');
});
});
describe('onResponse()', () => {
it('should perform a post query and show a success message', () => {
jest.spyOn(controller.vnApp, 'showSuccess');
$httpBackend.expect('POST', `Claims/updateClaimDestination`).respond({});
controller.onResponse();
$httpBackend.flush();
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
});
});
});
});

View File

@ -1 +0,0 @@
ClaimGreugeDescription: Claim id {{claimId}}

View File

@ -1,13 +0,0 @@
Destination: Destino
Action: Actuaciones
Total claimed: Total Reclamado
Import claim: Importar reclamacion
Imports claim details: Importa detalles de la reclamacion
Regularize: Regularizar
Do you want to insert greuges?: Desea insertar greuges?
Insert greuges on client card: Insertar greuges en la ficha del cliente
Greuge added: Greuge añadido
ClaimGreugeDescription: Reclamación id {{claimId}}
Change destination: Cambiar destino
Change destination to all selected rows: Cambiar destino a {{total}} fila(s) seleccionada(s)
Add observation to all selected clients: Añadir observación a {{total}} cliente(s) seleccionado(s)

View File

@ -1,46 +0,0 @@
vn-claim-action {
.header {
display: flex;
justify-content: space-between;
align-items: center;
align-content: center;
vn-tool-bar {
flex: none
}
.vn-check {
flex: none;
}
}
vn-dialog[vn-id=addSales] {
tpl-body {
width: 950px;
div {
div.buttons {
display: none;
}
vn-table{
min-width: 950px;
}
}
}
}
vn-popover.lastTicketsPopover {
vn-table {
min-width: 650px;
overflow: auto
}
div.ticketList {
overflow: auto;
max-height: 350px;
}
}
.right {
margin-left: 370px;
}
}

View File

@ -1,66 +0,0 @@
<mg-ajax path="Claims/updateClaim/{{patch.params.id}}" options="vnPatch"></mg-ajax>
<vn-watcher
vn-id="watcher"
data="$ctrl.claim"
form="form"
save="patch">
</vn-watcher>
<vn-crud-model
auto-load="true"
url="ClaimStates"
data="claimStates">
</vn-crud-model>
<form name="form" ng-submit="$ctrl.onSubmit()" class="vn-w-md">
<vn-card class="vn-pa-lg">
<vn-horizontal>
<vn-textfield
label="Client"
ng-model="$ctrl.claim.client.name"
readonly="true">
</vn-textfield>
<vn-textfield
label="Created"
field="::$ctrl.claim.created | date:'yyyy-MM-dd HH:mm'"
readonly="true">
</vn-textfield>
</vn-horizontal>
<vn-horizontal>
<vn-worker-autocomplete
disabled="false"
show-field="nickname"
ng-model="$ctrl.claim.workerFk"
departments="['VT']"
label="Attended by">
</vn-worker-autocomplete>
<vn-autocomplete
ng-model="$ctrl.claim.claimStateFk"
data="claimStates"
show-field="description"
value-field="id"
label="Claim state"
order="priority ASC"
vn-focus>
</vn-autocomplete>
</vn-horizontal>
<vn-horizontal>
<vn-input-number vn-one
min="0"
type="number"
label="Packages received"
ng-model="$ctrl.claim.packages">
</vn-input-number>
</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>

View File

@ -1,20 +0,0 @@
import ngModule from '../module';
import Section from 'salix/components/section';
import './style.scss';
class Controller extends Section {
onSubmit() {
this.$.watcher.submit().then(() => {
if (this.aclService.hasAny(['claimManager']))
this.$state.go('claim.card.detail');
});
}
}
ngModule.vnComponent('vnClaimBasicData', {
template: require('./index.html'),
controller: Controller,
bindings: {
claim: '<'
}
});

View File

@ -1,28 +0,0 @@
import './index.js';
import watcher from 'core/mocks/watcher';
describe('Claim', () => {
describe('Component vnClaimBasicData', () => {
let controller;
let $scope;
beforeEach(ngModule('claim'));
beforeEach(inject(($componentController, $rootScope) => {
$scope = $rootScope.$new();
$scope.watcher = watcher;
const $element = angular.element('<vn-claim-basic-data></vn-claim-basic-data>');
controller = $componentController('vnClaimBasicData', {$element, $scope});
}));
describe('onSubmit()', () => {
it(`should redirect to 'claim.card.detail' state`, () => {
jest.spyOn(controller.aclService, 'hasAny').mockReturnValue(true);
jest.spyOn(controller.$state, 'go');
controller.onSubmit();
expect(controller.$state.go).toHaveBeenCalledWith('claim.card.detail');
});
});
});
});

View File

@ -1,9 +0,0 @@
Contact: Contacto
Claim state: Estado de la reclamación
Is paid with mana: Cargado al maná
Responsability: Responsabilidad
Company: Empresa
Sales/Client: Comercial/Cliente
Pick up: Recoger
When checked will notify to the salesPerson: Cuando se marque enviará una notificación de recogida al comercial
Packages received: Bultos recibidos

View File

@ -1,3 +0,0 @@
vn-claim-basic-data vn-date-picker {
padding-left: 80px;
}

View File

@ -1,5 +0,0 @@
<vn-portal slot="menu">
<vn-claim-descriptor claim="$ctrl.claim"></vn-claim-descriptor>
<vn-left-menu source="card"></vn-left-menu>
</vn-portal>
<ui-view></ui-view>

View File

@ -1,68 +0,0 @@
import ngModule from '../module';
import ModuleCard from 'salix/components/module-card';
class Controller extends ModuleCard {
reload() {
let filter = {
include: [
{
relation: 'worker',
scope: {
fields: ['id'],
include: {
relation: 'user',
scope: {
fields: ['name']
}
}
}
}, {
relation: 'ticket',
scope: {
fields: ['zoneFk', 'addressFk'],
include: [
{
relation: 'zone',
scope: {
fields: ['name']
}
},
{
relation: 'address',
scope: {
fields: ['provinceFk'],
include: {
relation: 'province',
scope: {
fields: ['name']
}
}
}
}]
}
}, {
relation: 'claimState',
scope: {
fields: ['id', 'description']
}
}, {
relation: 'client',
scope: {
fields: ['salesPersonFk', 'name', 'email'],
include: {
relation: 'salesPersonUser'
}
}
}
]
};
this.$http.get(`Claims/${this.$params.id}`, {filter})
.then(res => this.claim = res.data);
}
}
ngModule.vnComponent('vnClaimCard', {
template: require('./index.html'),
controller: Controller
});

View File

@ -1,29 +0,0 @@
import './index.js';
describe('Claim', () => {
describe('Component vnClaimCard', () => {
let controller;
let $httpBackend;
let data = {id: 1, name: 'fooName'};
beforeEach(ngModule('claim'));
beforeEach(inject(($componentController, _$httpBackend_, $stateParams) => {
$httpBackend = _$httpBackend_;
let $element = angular.element('<div></div>');
controller = $componentController('vnClaimCard', {$element});
$stateParams.id = data.id;
$httpBackend.whenRoute('GET', 'Claims/:id').respond(data);
}));
it('should request data and set it on the controller', () => {
controller.reload();
$httpBackend.flush();
expect(controller.claim).toEqual(data);
});
});
});

View File

@ -29,9 +29,9 @@ class Controller extends Descriptor {
deleteClaim() { deleteClaim() {
return this.$http.delete(`Claims/${this.claim.id}`) return this.$http.delete(`Claims/${this.claim.id}`)
.then(() => { .then(async() => {
this.vnApp.showSuccess(this.$t('Claim deleted!')); this.vnApp.showSuccess(this.$t('Claim deleted!'));
this.$state.go('claim.index'); window.location.href = await this.vnApp.getUrl(`claim/`);
}); });
} }
} }

View File

@ -53,14 +53,12 @@ describe('Item Component vnClaimDescriptor', () => {
describe('deleteClaim()', () => { describe('deleteClaim()', () => {
it('should perform a query and call showSuccess if the response is accept', () => { it('should perform a query and call showSuccess if the response is accept', () => {
jest.spyOn(controller.vnApp, 'showSuccess'); jest.spyOn(controller.vnApp, 'showSuccess');
jest.spyOn(controller.$state, 'go');
$httpBackend.expectDELETE(`Claims/${claim.id}`).respond(); $httpBackend.expectDELETE(`Claims/${claim.id}`).respond();
controller.deleteClaim(); controller.deleteClaim();
$httpBackend.flush(); $httpBackend.flush();
expect(controller.vnApp.showSuccess).toHaveBeenCalled(); expect(controller.vnApp.showSuccess).toHaveBeenCalled();
expect(controller.$state.go).toHaveBeenCalledWith('claim.index');
}); });
}); });
}); });

View File

@ -1,178 +0,0 @@
<vn-crud-model
vn-id="model"
auto-load="true"
url="ClaimBeginnings"
filter="$ctrl.filter"
data="$ctrl.salesClaimed"
on-data-change="$ctrl.calculateTotals()">
</vn-crud-model>
<vn-card
class="vn-mb-md vn-pa-lg vn-w-lg"
style="text-align: right"
ng-if="$ctrl.salesClaimed.length > 0">
<vn-label-value label="Total"
value="{{$ctrl.paidTotal | currency: 'EUR':2}}">
</vn-label-value>
<vn-label-value label="Total claimed"
value="{{$ctrl.claimedTotal | currency: 'EUR':2}}">
</vn-label-value>
</vn-card>
<vn-data-viewer model="model">
<vn-card>
<vn-table model="model">
<vn-thead>
<vn-tr>
<vn-th center expand>Landed</vn-th>
<vn-th number>Quantity</vn-th>
<vn-th>Claimed</vn-th>
<vn-th>Description</vn-th>
<vn-th number>Price</vn-th>
<vn-th number>Disc.</vn-th>
<vn-th number>Total</vn-th>
<vn-th></vn-th>
</vn-tr>
</vn-thead>
<vn-tbody>
<vn-tr ng-repeat="saleClaimed in $ctrl.salesClaimed" vn-repeat-last>
<vn-td center expand>{{::saleClaimed.sale.ticket.landed | date:'dd/MM/yyyy'}}</vn-td>
<vn-td number>{{::saleClaimed.sale.quantity}}</vn-td>
<vn-td>
<vn-input-number
min="0"
step="1"
disabled="!$ctrl.isRewritable"
ng-model="saleClaimed.quantity"
on-change="$ctrl.setClaimedQuantity(saleClaimed.id, saleClaimed.quantity)"
class="dense">
</vn-input-number>
</vn-td>
<vn-td expand title="{{::saleClaimed.sale.concept}}">
<span
ng-click="itemDescriptor.show($event, saleClaimed.sale.itemFk)"
class="link">
{{::saleClaimed.sale.concept}}
</span>
</vn-td>
<vn-td number>{{::saleClaimed.sale.price | currency: 'EUR':2}}</vn-td>
<vn-td number>
<span ng-class="{'link': $ctrl.isRewritable && $ctrl.isClaimManager}"
translate-attr="{title: $ctrl.isRewritable && $ctrl.isClaimManager ? 'Edit discount' : ''}"
ng-click="$ctrl.showEditPopover($event, saleClaimed)">
{{saleClaimed.sale.discount}} %
</span>
</vn-td>
<vn-td number>
{{$ctrl.getSaleTotal(saleClaimed.sale) | currency: 'EUR':2}}
</vn-td>
<vn-td shrink>
<vn-icon-button
vn-tooltip="Remove sale"
ng-if ="$ctrl.isRewritable"
icon="delete"
ng-click="$ctrl.showDeleteConfirm($index)"
tabindex="-1">
</vn-icon-button>
</vn-td>
</vn-tr>
</vn-tbody>
</vn-table>
</vn-card>
</vn-data-viewer>
<vn-button
label="Next"
class="next"
ui-sref="claim.card.photos">
</vn-button>
<vn-float-button
icon="add"
ng-if="$ctrl.isRewritable"
ng-click="$ctrl.openAddSalesDialog()"
vn-tooltip="Add sale item" vn-bind="+"
fixed-bottom-right>
</vn-float-button>
<!-- Add Lines Dialog -->
<vn-dialog vn-id="add-sales" class="modal-form">
<tpl-title>
<span translate>Claimable sales from ticket</span> {{$ctrl.claim.ticketFk}}
</tpl-title>
<tpl-body>
<vn-horizontal class="vn-pa-md">
<vn-table>
<vn-thead>
<vn-tr>
<vn-th number>Landed</vn-th>
<vn-th number>Quantity</vn-th>
<vn-th number>Description</vn-th>
<vn-th number>Price</vn-th>
<vn-th number>Disc.</vn-th>
<vn-th number>Total</vn-th>
</vn-tr>
</vn-thead>
<vn-tbody>
<vn-tr
ng-repeat="sale in $ctrl.salesToClaim"
ng-click="$ctrl.addClaimedSale($index)"
class="clickable">
<vn-td number>{{sale.landed | date: 'dd/MM/yyyy'}}</vn-td>
<vn-td number>{{sale.quantity}}</vn-td>
<vn-td expand title="{{::sale.concept}}">
<span
vn-click-stop="itemDescriptor.show($event, sale.itemFk)"
class="link">
{{sale.itemFk}} - {{sale.concept}}
</span>
</vn-td>
<vn-td number>{{sale.price | currency: 'EUR':2}}</vn-td>
<vn-td number>{{sale.discount}} %</vn-td>
<vn-td number>
{{(sale.quantity * sale.price) - ((sale.discount * (sale.quantity * sale.price))/100) | currency: 'EUR':2}}
</vn-td>
</vn-tr>
</vn-tbody>
</vn-table>
</vn-horizontal>
</tpl-body>
</vn-dialog>
<vn-item-descriptor-popover
vn-id="item-descriptor"
warehouse-fk="$ctrl.vnConfig.warehouseFk">
</vn-item-descriptor-popover>
<vn-popover
class="edit"
vn-id="edit-popover"
on-open="$ctrl.getSalespersonMana()"
on-close="$ctrl.mana = null">
<div class="discount-popover">
<vn-spinner
ng-if="$ctrl.mana == null"
style="padding: 1em;"
enable="true">
</vn-spinner>
<div ng-if="$ctrl.mana != null">
<vn-horizontal class="header vn-pa-md">
<h5>MANÁ: {{$ctrl.mana | currency: 'EUR':0}}</h5>
</vn-horizontal>
<div class="vn-pa-md">
<vn-input-number
vn-focus
label="Discount"
ng-model="$ctrl.newDiscount"
type="text"
step="0.01"
on-change="$ctrl.updateDiscount()"
suffix="€">
</vn-input-number>
<div class="simulator">
<p class="simulatorTitle" translate>Total claimed price</p>
<p>{{$ctrl.newPrice | currency: 'EUR':2}}
</p>
</div>
</div>
</div>
</div>
</vn-popover>
<vn-confirm
vn-id="confirm"
question="Delete sale from claim?"
on-accept="$ctrl.deleteClaimedSale()">
</vn-confirm>

View File

@ -1,203 +0,0 @@
import ngModule from '../module';
import Section from 'salix/components/section';
import './style.scss';
class Controller extends Section {
constructor($element, $) {
super($element, $);
this.edit = {};
this.filter = {
where: {claimFk: this.$params.id},
include: [
{
relation: 'sale',
scope: {
fields: ['concept', 'ticketFk', 'price', 'quantity', 'discount', 'itemFk'],
include: {
relation: 'ticket'
}
}
}
]
};
}
get claim() {
return this._claim;
}
set claim(value) {
this._claim = value;
if (value) {
this.isClaimEditable();
this.isTicketEditable();
}
}
set salesClaimed(value) {
this._salesClaimed = value;
if (value) this.calculateTotals();
}
get salesClaimed() {
return this._salesClaimed;
}
get newDiscount() {
return this._newDiscount;
}
set newDiscount(value) {
this._newDiscount = value;
this.updateNewPrice();
}
get isClaimManager() {
return this.aclService.hasAny(['claimManager']);
}
openAddSalesDialog() {
this.getClaimableFromTicket();
this.$.addSales.show();
}
getClaimableFromTicket() {
let config = {params: {ticketFk: this.claim.ticketFk}};
let query = `Sales/getClaimableFromTicket`;
this.$http.get(query, config).then(res => {
if (res.data)
this.salesToClaim = res.data;
});
}
addClaimedSale(index) {
let sale = this.salesToClaim[index];
let saleToAdd = {saleFk: sale.saleFk, claimFk: this.claim.id, quantity: sale.quantity};
let query = `ClaimBeginnings/`;
this.$http.post(query, saleToAdd).then(() => {
this.$.addSales.hide();
this.$.model.refresh();
this.vnApp.showSuccess(this.$t('Data saved!'));
if (this.aclService.hasAny(['claimManager']))
this.$state.go('claim.card.development');
});
}
showDeleteConfirm($index) {
this.claimedIndex = $index;
this.$.confirm.show();
}
deleteClaimedSale() {
this.$.model.remove(this.claimedIndex);
this.$.model.save().then(() => {
this.vnApp.showSuccess(this.$t('Data saved!'));
this.calculateTotals();
});
}
setClaimedQuantity(id, claimedQuantity) {
let params = {quantity: claimedQuantity};
let query = `ClaimBeginnings/${id}`;
this.$http.patch(query, params).then(() => {
this.vnApp.showSuccess(this.$t('Data saved!'));
this.calculateTotals();
});
}
calculateTotals() {
this.paidTotal = 0.0;
this.claimedTotal = 0.0;
if (!this._salesClaimed) return;
this._salesClaimed.forEach(sale => {
let orgSale = sale.sale;
this.paidTotal += this.getSaleTotal(orgSale);
const price = sale.quantity * orgSale.price;
const discount = ((orgSale.discount * price) / 100);
this.claimedTotal += price - discount;
});
}
getSaleTotal(sale) {
let total = 0.0;
const price = sale.quantity * sale.price;
const discount = ((sale.discount * price) / 100);
total += price - discount;
return total;
}
getSalespersonMana() {
this.$http.get(`Tickets/${this.claim.ticketFk}/getSalesPersonMana`).then(res => {
this.mana = res.data;
});
}
isTicketEditable() {
if (!this.claim) return;
this.$http.get(`Tickets/${this.claim.ticketFk}/isEditable`).then(res => {
this.isEditable = res.data;
});
}
isClaimEditable() {
if (!this.claim) return;
this.$http.get(`ClaimStates/${this.claim.claimStateFk}/isEditable`).then(res => {
this.isRewritable = res.data;
});
}
showEditPopover(event, saleClaimed) {
if (this.aclService.hasAny(['claimManager'])) {
this.saleClaimed = saleClaimed;
this.$.editPopover.parent = event.target;
this.$.editPopover.show();
}
}
updateDiscount() {
const claimedSale = this.saleClaimed.sale;
if (this.newDiscount != claimedSale.discount) {
const params = {salesIds: [claimedSale.id], newDiscount: this.newDiscount};
const query = `Tickets/${claimedSale.ticketFk}/updateDiscount`;
this.$http.post(query, params).then(() => {
claimedSale.discount = this.newDiscount;
this.calculateTotals();
this.clearDiscount();
this.vnApp.showSuccess(this.$t('Data saved!'));
});
}
this.$.editPopover.hide();
}
updateNewPrice() {
this.newPrice = (this.saleClaimed.quantity * this.saleClaimed.sale.price) -
((this.newDiscount * (this.saleClaimed.quantity * this.saleClaimed.sale.price)) / 100);
}
clearDiscount() {
this.newDiscount = null;
}
}
Controller.$inject = ['$element', '$scope'];
ngModule.vnComponent('vnClaimDetail', {
template: require('./index.html'),
controller: Controller,
bindings: {
claim: '<'
}
});

View File

@ -1,150 +0,0 @@
import './index.js';
import crudModel from 'core/mocks/crud-model';
describe('claim', () => {
describe('Component vnClaimDetail', () => {
let $scope;
let controller;
let $httpBackend;
beforeEach(ngModule('claim'));
beforeEach(inject(($componentController, _$httpBackend_, $rootScope) => {
$scope = $rootScope.$new();
$scope.descriptor = {
show: () => {}
};
$httpBackend = _$httpBackend_;
$httpBackend.whenGET('Claims/ClaimBeginnings').respond({});
$httpBackend.whenGET(`Tickets/1/isEditable`).respond(true);
$httpBackend.whenGET(`ClaimStates/2/isEditable`).respond(true);
const $element = angular.element('<vn-claim-detail></vn-claim-detail>');
controller = $componentController('vnClaimDetail', {$element, $scope});
controller.claim = {
ticketFk: 1,
id: 2,
claimStateFk: 2}
;
controller.salesToClaim = [{saleFk: 1}, {saleFk: 2}];
controller.salesClaimed = [{id: 1, sale: {}}];
controller.$.model = crudModel;
controller.$.addSales = {
hide: () => {},
show: () => {}
};
controller.$.editPopover = {
hide: () => {}
};
jest.spyOn(controller.aclService, 'hasAny').mockReturnValue(true);
}));
describe('openAddSalesDialog()', () => {
it('should call getClaimableFromTicket and $.addSales.show', () => {
jest.spyOn(controller, 'getClaimableFromTicket');
jest.spyOn(controller.$.addSales, 'show');
controller.openAddSalesDialog();
expect(controller.getClaimableFromTicket).toHaveBeenCalledWith();
expect(controller.$.addSales.show).toHaveBeenCalledWith();
});
});
describe('getClaimableFromTicket()', () => {
it('should make a query and set salesToClaim', () => {
$httpBackend.expectGET(`Sales/getClaimableFromTicket?ticketFk=1`).respond(200, 1);
controller.getClaimableFromTicket();
$httpBackend.flush();
expect(controller.salesToClaim).toEqual(1);
});
});
describe('addClaimedSale(index)', () => {
it('should make a post and call refresh, hide and showSuccess', () => {
jest.spyOn(controller.$.addSales, 'hide');
jest.spyOn(controller.$state, 'go');
$httpBackend.expectPOST(`ClaimBeginnings/`).respond({});
controller.addClaimedSale(1);
$httpBackend.flush();
expect(controller.$.addSales.hide).toHaveBeenCalledWith();
expect(controller.$state.go).toHaveBeenCalledWith('claim.card.development');
});
});
describe('deleteClaimedSale()', () => {
it('should make a delete and call refresh and showSuccess', () => {
const claimedIndex = 1;
controller.claimedIndex = claimedIndex;
jest.spyOn(controller.$.model, 'remove');
jest.spyOn(controller.$.model, 'save');
jest.spyOn(controller.vnApp, 'showSuccess');
controller.deleteClaimedSale();
expect(controller.$.model.remove).toHaveBeenCalledWith(claimedIndex);
expect(controller.$.model.save).toHaveBeenCalledWith();
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
});
});
describe('setClaimedQuantity(id, claimedQuantity)', () => {
it('should make a patch and call refresh and showSuccess', () => {
const id = 1;
const claimedQuantity = 1;
jest.spyOn(controller.vnApp, 'showSuccess');
$httpBackend.expectPATCH(`ClaimBeginnings/${id}`).respond({});
controller.setClaimedQuantity(id, claimedQuantity);
$httpBackend.flush();
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
});
});
describe('calculateTotals()', () => {
it('should set paidTotal and claimedTotal to 0 if salesClaimed has no data', () => {
controller.salesClaimed = [];
controller.calculateTotals();
expect(controller.paidTotal).toEqual(0);
expect(controller.claimedTotal).toEqual(0);
});
});
describe('updateDiscount()', () => {
it('should perform a query if the new discount differs from the claim discount', () => {
controller.saleClaimed = {sale: {
discount: 5,
id: 7,
ticketFk: 1,
price: 2,
quantity: 10}};
controller.newDiscount = 10;
jest.spyOn(controller.vnApp, 'showSuccess');
jest.spyOn(controller, 'calculateTotals');
jest.spyOn(controller, 'clearDiscount');
jest.spyOn(controller.$.editPopover, 'hide');
$httpBackend.when('POST', 'Tickets/1/updateDiscount').respond({});
controller.updateDiscount();
$httpBackend.flush();
expect(controller.calculateTotals).toHaveBeenCalledWith();
expect(controller.clearDiscount).toHaveBeenCalledWith();
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
expect(controller.$.editPopover.hide).toHaveBeenCalledWith();
});
});
describe('isTicketEditable()', () => {
it('should check if the ticket assigned to the claim is editable', () => {
controller.isTicketEditable();
$httpBackend.flush();
expect(controller.isEditable).toBeTruthy();
});
});
});
});

View File

@ -1,11 +0,0 @@
Claimed: Reclamados
Disc.: Dto.
Attended by: Atendida por
Landed: F. entrega
Price: Precio
Claimable sales from ticket: Lineas reclamables del ticket
Detail: Detalles
Add sale item: Añadir artículo
Insuficient permisos: Permisos insuficientes
Total claimed price: Precio total reclamado
Delete sale from claim?: ¿Borrar la linea de la reclamación?

View File

@ -1,30 +0,0 @@
@import "variables";
.vn-popover .discount-popover {
width: 256px;
.header {
background-color: $color-main;
color: $color-font-dark;
h5 {
color: inherit;
margin: 0 auto;
}
}
.simulatorTitle {
margin-bottom: 0;
font-size: .75rem;
color: $color-main;
}
vn-label-value {
padding-bottom: 20px;
}
.simulator{
text-align: center;
}
}
.next{
float: right;
}

View File

@ -1,2 +0,0 @@
<vn-card>
</vn-card>

View File

@ -1,21 +0,0 @@
import ngModule from '../module';
import Section from 'salix/components/section';
class Controller extends Section {
constructor($element, $) {
super($element, $);
}
async $onInit() {
this.$state.go('claim.card.summary', {id: this.$params.id});
window.location.href = await this.vnApp.getUrl(`claim/${this.$params.id}/development`);
}
}
ngModule.vnComponent('vnClaimDevelopment', {
template: require('./index.html'),
controller: Controller,
bindings: {
claim: '<'
}
});

View File

@ -1,16 +1,4 @@
export * from './module'; export * from './module';
import './main'; import './main';
import './index/';
import './action';
import './basic-data';
import './card';
import './detail';
import './descriptor'; import './descriptor';
import './development';
import './search-panel';
import './summary';
import './photos';
import './log';
import './note/index';
import './note/create';

View File

@ -1,83 +0,0 @@
<vn-auto-search
model="model">
</vn-auto-search>
<vn-card>
<smart-table
model="model"
options="$ctrl.smartTableOptions"
expr-builder="$ctrl.exprBuilder(param, value)">
<slot-table>
<table>
<thead>
<tr>
<th field="clientFk" shrink>
<span translate>Id</span>
</th>
<th field="clientName">
<span translate>Client</span>
</th>
<th field="created" center shrink-date>
<span translate>Created</span>
</th>
<th field="workerFk">
<span translate>Worker</span>
</th>
<th field="claimStateFk">
<span translate>State</span>
</th>
<th></th>
</tr>
</thead>
<tbody>
<tr
ng-repeat="claim in model.data"
vn-anchor="::{
state: 'claim.card.summary',
params: {id: claim.id}
}">
<td>{{::claim.id}}</td>
<td>
<span
vn-click-stop="clientDescriptor.show($event, claim.clientFk)"
class="link">
{{::claim.clientName}}
</span>
</td>
<td center shrink-date>{{::claim.created | date:'dd/MM/yyyy'}}</td>
<td>
<span
vn-click-stop="workerDescriptor.show($event, claim.workerFk)"
class="link" >
{{::claim.workerName}}
</span>
</td>
<td>
<span class="chip {{::$ctrl.stateColor(claim.stateCode)}}">
{{::claim.stateDescription}}
</span>
</td>
<td shrink>
<vn-icon-button
vn-click-stop="$ctrl.preview(claim)"
vn-tooltip="Preview"
icon="preview">
</vn-icon-button>
</td>
</tr>
</tbody>
</table>
</slot-table>
</smart-table>
</vn-card>
<vn-client-descriptor-popover
vn-id="clientDescriptor">
</vn-client-descriptor-popover>
<vn-worker-descriptor-popover
vn-id="workerDescriptor">
</vn-worker-descriptor-popover>
<vn-popup vn-id="summary">
<vn-claim-summary
claim="$ctrl.claimSelected"
parent-reload="$ctrl.reload()">
</vn-claim-summary>
</vn-popup>

View File

@ -1,82 +0,0 @@
import ngModule from '../module';
import Section from 'salix/components/section';
class Controller extends Section {
constructor($element, $) {
super($element, $);
this.smartTableOptions = {
activeButtons: {
search: true
},
columns: [
{
field: 'clientName',
autocomplete: {
url: 'Clients',
showField: 'name',
valueField: 'name'
}
},
{
field: 'workerFk',
autocomplete: {
url: 'Workers/activeWithInheritedRole',
where: `{role: 'salesPerson'}`,
searchFunction: '{firstName: $search}',
showField: 'name',
valueField: 'id',
}
},
{
field: 'claimStateFk',
autocomplete: {
url: 'ClaimStates',
showField: 'description',
valueField: 'id',
}
},
{
field: 'created',
searchable: false
}
]
};
}
exprBuilder(param, value) {
switch (param) {
case 'clientName':
return {'cl.clientName': {like: `%${value}%`}};
case 'clientFk':
case 'claimStateFk':
case 'workerFk':
return {[`cl.${param}`]: value};
}
}
stateColor(code) {
switch (code) {
case 'pending':
return 'warning';
case 'managed':
return 'notice';
case 'resolved':
return 'success';
}
}
preview(claim) {
this.claimSelected = claim;
this.$.summary.show();
}
reload() {
this.$.model.refresh();
}
}
ngModule.vnComponent('vnClaimIndex', {
template: require('./index.html'),
controller: Controller
});

View File

@ -1,4 +0,0 @@
<vn-log
url="ClaimLogs"
origin-id="$ctrl.$params.id">
</vn-log>

View File

@ -1,7 +0,0 @@
import ngModule from '../module';
import Section from 'salix/components/section';
ngModule.vnComponent('vnClaimLog', {
template: require('./index.html'),
controller: Section,
});

View File

@ -1,19 +0,0 @@
<vn-crud-model
vn-id="model"
url="Claims/filter"
limit="20"
order="priority ASC, created DESC"
auto-load="true">
</vn-crud-model>
<vn-portal slot="topbar">
<vn-searchbar
vn-focus
panel="vn-claim-search-panel"
info="Search claim by id or client name"
model="model">
</vn-searchbar>
</vn-portal>
<vn-portal slot="menu">
<vn-left-menu></vn-left-menu>
</vn-portal>
<ui-view></ui-view>

View File

@ -1,7 +1,18 @@
import ngModule from '../module'; import ngModule from '../module';
import ModuleMain from 'salix/components/module-main'; import ModuleMain from 'salix/components/module-main';
export default class Claim extends ModuleMain {
constructor($element, $) {
super($element, $);
}
async $onInit() {
this.$state.go('home');
window.location.href = await this.vnApp.getUrl(`Claim/`);
}
}
ngModule.vnComponent('vnClaim', { ngModule.vnComponent('vnClaim', {
controller: ModuleMain, controller: Claim,
template: require('./index.html') template: require('./index.html')
}); });

View File

@ -1,30 +0,0 @@
<vn-watcher
vn-id="watcher"
url="claimObservations"
id-field="id"
data="$ctrl.note"
insert-mode="true"
form="form">
</vn-watcher>
<form name="form" ng-submit="watcher.submitGo('claim.card.note.index')" class="vn-w-md">
<vn-card class="vn-pa-lg">
<vn-horizontal>
<vn-textarea
vn-one
label="Note"
ng-model="$ctrl.note.text"
vn-focus>
</vn-textarea>
</vn-horizontal>
</vn-card>
<vn-button-bar>
<vn-submit
ng-if="watcher.dataChanged()"
label="Save">
</vn-submit>
<vn-button
ng-click="$ctrl.cancel()"
label="Cancel">
</vn-button>
</vn-button-bar>
</form>

View File

@ -1,22 +0,0 @@
import ngModule from '../../module';
import Section from 'salix/components/section';
export default class Controller extends Section {
constructor($element, $) {
super($element, $);
this.note = {
claimFk: parseInt(this.$params.id),
workerFk: window.localStorage.currentUserWorkerId,
text: null
};
}
cancel() {
this.$state.go('claim.card.note.index', {id: this.$params.id});
}
}
ngModule.vnComponent('vnClaimNoteCreate', {
template: require('./index.html'),
controller: Controller
});

View File

@ -1,32 +0,0 @@
<vn-crud-model
vn-id="model"
url="ClaimObservations"
filter="$ctrl.filter"
where="{claimFk: $ctrl.$params.id}"
include="$ctrl.include"
data="notes"
auto-load="true">
</vn-crud-model>
<vn-data-viewer
model="model"
class="vn-w-md">
<vn-card class="vn-pa-md">
<div
ng-repeat="note in notes"
class="note vn-pa-sm border-solid border-radius vn-mb-md">
<vn-horizontal class="vn-mb-sm" style="color: #666">
<vn-one>{{::note.worker.firstName}} {{::note.worker.lastName}}</vn-one>
<vn-auto>{{::note.created | date:'dd/MM/yyyy HH:mm'}}</vn-auto>
</vn-horizontal>
<vn-horizontal class="text">
{{::note.text}}
</vn-horizontal>
</div>
</vn-card>
</vn-data-viewer>
<a vn-tooltip="New note"
ui-sref="claim.card.note.create({id: $ctrl.$params.id})"
vn-bind="+"
fixed-bottom-right>
<vn-float-button icon="add"></vn-float-button>
</a>

View File

@ -1,25 +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.filter = {
order: 'created DESC',
};
this.include = {
relation: 'worker',
scope: {
fields: ['id', 'firstName', 'lastName']
}
};
}
}
Controller.$inject = ['$element', '$scope'];
ngModule.vnComponent('vnClaimNote', {
template: require('./index.html'),
controller: Controller,
});

View File

@ -1,5 +0,0 @@
vn-client-note {
.note:last-child {
margin-bottom: 0;
}
}

View File

@ -1 +0,0 @@

View File

@ -1,21 +0,0 @@
import ngModule from '../module';
import Section from 'salix/components/section';
class Controller extends Section {
constructor($element, $) {
super($element, $);
}
async $onInit() {
const url = await this.vnApp.getUrl(`claim/${this.$params.id}/photos`);
window.location.href = url;
}
}
ngModule.vnComponent('vnClaimPhotos', {
template: require('./index.html'),
controller: Controller,
bindings: {
claim: '<'
}
});

View File

@ -1,84 +0,0 @@
<div class="search-panel">
<form ng-submit="$ctrl.onSearch()">
<vn-horizontal>
<vn-textfield
vn-one
label="General search"
ng-model="filter.search"
info="Search claim by id or client name"
vn-focus>
</vn-textfield>
</vn-horizontal>
<vn-horizontal>
<vn-textfield
vn-one
label="Client Id"
ng-model="filter.clientFk">
</vn-textfield>
<vn-textfield
vn-one
label="Client"
ng-model="filter.clientName">
</vn-textfield>
</vn-horizontal>
<vn-horizontal>
<vn-worker-autocomplete
vn-one
ng-model="filter.salesPersonFk"
departments="['VT']"
label="Salesperson">
</vn-worker-autocomplete>
<vn-worker-autocomplete
vn-one
ng-model="filter.attenderFk"
departments="['VT']"
label="Attended by">
</vn-worker-autocomplete>
</vn-horizontal>
<vn-horizontal>
<vn-autocomplete vn-one
label="State"
ng-model="filter.claimStateFk"
url="ClaimStates"
show-field="description"
value-field="id">
<tpl-item>{{description}}</tpl-item>
</vn-autocomplete>
<vn-date-picker
vn-one
label="Created"
ng-model="filter.created">
</vn-date-picker>
</vn-horizontal>
<vn-horizontal>
<vn-autocomplete vn-one class="dense"
label="Item"
url="Items/withName"
ng-model="filter.itemFk"
show-field="name"
value-field="id"
search-function="$ctrl.itemSearchFunc($search)"
order="id DESC">
<tpl-item>{{::id}} - {{::name}}</tpl-item>
</vn-autocomplete>
<vn-autocomplete
vn-one
ng-model="filter.claimResponsibleFk"
url="ClaimResponsibles"
show-field="description"
value-field="id"
label="Responsible">
</vn-autocomplete>
</vn-horizontal>
<vn-horizontal>
<vn-check
vn-one
label="My team"
ng-model="filter.myTeam"
triple-state="true">
</vn-horizontal>
<vn-horizontal class="vn-mt-lg">
<vn-submit label="Search"></vn-submit>
</vn-horizontal>
</form>
</div>

View File

@ -1,14 +0,0 @@
import ngModule from '../module';
import SearchPanel from 'core/components/searchbar/search-panel';
class Controller extends SearchPanel {
itemSearchFunc($search) {
return /^\d+$/.test($search)
? {id: $search}
: {name: {like: '%' + $search + '%'}};
}
}
ngModule.vnComponent('vnClaimSearchPanel', {
template: require('./index.html'),
controller: Controller
});

View File

@ -1,7 +0,0 @@
Ticket id: Id ticket
Client id: Id cliente
Nickname: Alias
From: Desde
To: Hasta
Agency: Agencia
Warehouse: Almacén

View File

@ -1,273 +0,0 @@
<vn-crud-model
vn-id="model"
url="ClaimDms"
filter="::$ctrl.filter"
data="photos">
</vn-crud-model>
<vn-card class="summary">
<h5>
<a
ng-if="::$ctrl.summary.claim.id"
vn-tooltip="Go to the claim"
ui-sref="claim.card.summary({id: {{::$ctrl.summary.claim.id}}})"
name="goToSummary">
<vn-icon-button icon="launch"></vn-icon-button>
</a>
<span>{{::$ctrl.summary.claim.id}} - {{::$ctrl.summary.claim.client.name}}</span>
<vn-button-menu
disabled="!$ctrl.summary.isEditable"
class="message"
label="Change state"
value-field="id"
show-field="description"
url="claimStates"
on-change="$ctrl.changeState(value)">
</vn-button-menu>
</h5>
<vn-horizontal>
<vn-auto>
<h4>
<a
ui-sref="claim.card.basicData({id:$ctrl.claim.id})"
target="_self">
<span translate vn-tooltip="Go to">Basic data</span>
</a>
</h4>
<vn-label-value
label="Created"
value="{{$ctrl.summary.claim.created | date: 'dd/MM/yyyy'}}">
</vn-label-value>
<vn-label-value
label="State"
value="{{$ctrl.summary.claim.claimState.description}}">
</vn-label-value>
<vn-label-value
label="Salesperson"
value="{{$ctrl.summary.claim.client.salesPersonUser.name}}">
</vn-label-value>
<vn-label-value
label="Attended by"
value="{{$ctrl.summary.claim.worker.user.nickname}}">
</vn-label-value>
</vn-auto>
<vn-auto>
<h4 ng-show="$ctrl.isSalesPerson && $ctrl.summary.observations.length">
<a
ui-sref="claim.card.note.index({id:$ctrl.claim.id})"
target="_self">
<span translate vn-tooltip="Go to">Observations</span>
</a>
</h4>
<h4
ng-show="!$ctrl.isSalesPerson && $ctrl.summary.observations.length"
translate>
Observations
</h4>
<div
ng-repeat="note in $ctrl.summary.observations"
class="note vn-pa-sm border-solid border-radius vn-mb-md">
<vn-horizontal class="vn-mb-sm" style="color: #666">
<vn-one>{{::note.worker.firstName}} {{::note.worker.lastName}}</vn-one>
<vn-auto>{{::note.created | date:'dd/MM/yyyy HH:mm'}}</vn-auto>
</vn-horizontal>
<vn-horizontal class="text">
{{::note.text}}
</vn-horizontal>
</div>
</vn-auto>
<vn-auto>
<h4 ng-show="$ctrl.isSalesPerson">
<a
ui-sref="claim.card.detail({id:$ctrl.claim.id})"
target="_self">
<span translate vn-tooltip="Go to">Detail</span>
</a>
</h4>
<h4
ng-show="!$ctrl.isSalesPerson"
translate>
Detail
</h4>
<vn-data-viewer data="::$ctrl.summary.salesClaimed">
<vn-table>
<vn-thead>
<vn-tr>
<vn-th number>Item</vn-th>
<vn-th expand>Landed</vn-th>
<vn-th number>Quantity</vn-th>
<vn-th number>Claimed</vn-th>
<vn-th>Description</vn-th>
<vn-th number>Price</vn-th>
<vn-th number>Disc.</vn-th>
<vn-th number>Total</vn-th>
</vn-tr>
</vn-thead>
<vn-tbody>
<vn-tr ng-repeat="saleClaimed in $ctrl.summary.salesClaimed">
<vn-td number>
<span
ng-click="itemDescriptor.show($event, saleClaimed.sale.itemFk, saleClaimed.sale.id)"
class="link">
{{::saleClaimed.sale.itemFk}}
</span>
</vn-td>
<vn-td expand>{{::saleClaimed.sale.ticket.landed | date: 'dd/MM/yyyy'}}</vn-td>
<vn-td number>{{::saleClaimed.sale.quantity}}</vn-td>
<vn-td number>{{::saleClaimed.quantity}}</vn-td>
<vn-td expand>{{::saleClaimed.sale.concept}}</vn-td>
<vn-td number>{{::saleClaimed.sale.price | currency: 'EUR':2}}</vn-td>
<vn-td number>{{::saleClaimed.sale.discount}} %</vn-td>
<vn-td number>
{{saleClaimed.sale.quantity * saleClaimed.sale.price *
((100 - saleClaimed.sale.discount) / 100) | currency: 'EUR':2}}
</vn-td>
</vn-tr>
</vn-tbody>
</vn-table>
</vn-data-viewer>
</vn-auto>
<vn-auto ng-if="photos.length > 0">
<h4 translate>Photos</h4>
<vn-horizontal class="photo-list">
<section class="photo" ng-repeat="photo in photos">
<section class="image" on-error-src
ng-style="{'background': 'url(' + $ctrl.getImagePath(photo.dmsFk) + ')'}"
zoom-image="{{$ctrl.getImagePath(photo.dmsFk)}}"
ng-if="photo.dms.contentType != 'video/mp4'">
</section>
<video id="videobcg" muted="muted" controls ng-if="photo.dms.contentType == 'video/mp4'"
class="video">
<source src="{{$ctrl.getImagePath(photo.dmsFk)}}" type="video/mp4">
</video>
</section>
</vn-horizontal>
</vn-auto>
<vn-auto>
<h4 ng-show="$ctrl.isClaimManager">
<a
ui-sref="claim.card.development({id:$ctrl.claim.id})"
target="_self">
<span translate vn-tooltip="Go to">Development</span>
</a>
</h4>
<h4
translate
ng-show="!$ctrl.isClaimManager">
Development
</h4>
<vn-data-viewer data="::$ctrl.summary.developments">
<vn-table>
<vn-thead>
<vn-tr>
<vn-th>Reason</vn-th>
<vn-th>Result</vn-th>
<vn-th>Responsible</vn-th>
<vn-th>Worker</vn-th>
<vn-th>Redelivery</vn-th>
</vn-tr>
</vn-thead>
<vn-tbody>
<vn-tr ng-repeat="development in $ctrl.summary.developments">
<vn-td>{{::development.claimReason.description}}</vn-td>
<vn-td>{{::development.claimResult.description}}</vn-td>
<vn-td>{{::development.claimResponsible.description}}</vn-td>
<vn-td expand>
<span
class="link"
ng-click="workerDescriptor.show($event, development.workerFk)">
{{::development.worker.user.nickname}}
</span>
</vn-td>
<vn-td>{{::development.claimRedelivery.description}}</vn-td>
</vn-tr>
</vn-tbody>
</vn-table>
</vn-data-viewer>
</vn-auto>
<vn-auto>
<h4 ng-show="$ctrl.isClaimManager">
<a
ui-sref="claim.card.action({id:$ctrl.claim.id})"
target="_self">
<span translate vn-tooltip="Go to">Action</span>
</a>
</h4>
<h4
translate
ng-show="!$ctrl.isClaimManager">
Action
</h4>
<vn-horizontal>
<vn-one>
<vn-range
vn-one
disabled="true"
label="Responsability"
min-label="Company"
max-label="Sales/Client"
ng-model="$ctrl.summary.claim.responsibility"
max="5"
min="1"
step="1"
vn-acl="claimManager">
</vn-range>
</vn-one>
</vn-horizontal>
<vn-data-viewer data="::$ctrl.summary.actions">
<vn-table>
<vn-thead>
<vn-tr>
<vn-th number>Item</vn-th>
<vn-th number>Ticket</vn-th>
<vn-th>Destination</vn-th>
<vn-th number>Landed</vn-th>
<vn-th number>Quantity</vn-th>
<vn-th>Description</vn-th>
<vn-th number>Price</vn-th>
<vn-th number>Disc.</vn-th>
<vn-th number>Total</vn-th>
</vn-tr>
</vn-thead>
<vn-tbody>
<vn-tr ng-repeat="action in $ctrl.summary.actions">
<vn-td number>
<span
ng-click="itemDescriptor.show($event, action.sale.itemFk, action.sale.id)"
class="link">
{{::action.sale.itemFk}}
</span>
</vn-td>
<vn-td number>
<span
ng-click="ticketDescriptor.show($event, action.sale.ticket.id)"
class="link">
{{::action.sale.ticket.id}}
</span>
</vn-td>
<vn-td expand>{{::action.claimBeggining.description}}</vn-td>
<vn-td number>{{::action.sale.ticket.landed | date: 'dd/MM/yyyy'}}</vn-td>
<vn-td number>{{::action.sale.quantity}}</vn-td>
<vn-td expand>{{::action.sale.concept}}</vn-td>
<vn-td number>{{::action.sale.price}}</vn-td>
<vn-td number>{{::action.sale.discount}} %</vn-td>
<vn-td number>
{{action.sale.quantity * action.sale.price *
((100 - action.sale.discount) / 100) | currency: 'EUR':2}}
</vn-td>
</vn-tr>
</vn-tbody>
</vn-table>
</vn-data-viewer>
</vn-auto>
</vn-horizontal>
</vn-card>
<vn-item-descriptor-popover
vn-id="item-descriptor"
warehouse-fk="$ctrl.vnConfig.warehouseFk">
</vn-item-descriptor-popover>
<vn-worker-descriptor-popover
vn-id="worker-descriptor">
</vn-worker-descriptor-popover>
<vn-ticket-descriptor-popover
vn-id="ticket-descriptor">
</vn-ticket-descriptor-popover>

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