Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into puppeteer
gitea/salix/puppeteer There was a failure building this commit
Details
gitea/salix/puppeteer There was a failure building this commit
Details
This commit is contained in:
commit
cb2f94cdaf
|
@ -34,5 +34,5 @@ COPY \
|
||||||
|
|
||||||
CMD ["pm2-runtime", "./back/process.yml"]
|
CMD ["pm2-runtime", "./back/process.yml"]
|
||||||
|
|
||||||
HEALTHCHECK --interval=1m --timeout=10s \
|
HEALTHCHECK --interval=15s --timeout=10s \
|
||||||
CMD curl -f http://localhost:3000/api/Applications/status || exit 1
|
CMD curl -f http://localhost:3000/api/Applications/status || exit 1
|
||||||
|
|
|
@ -6,20 +6,13 @@ pipeline {
|
||||||
disableConcurrentBuilds()
|
disableConcurrentBuilds()
|
||||||
}
|
}
|
||||||
environment {
|
environment {
|
||||||
PROJECT_NAME = 'salix'
|
PROJECT_NAME = 'salix'
|
||||||
REGISTRY = 'registry.verdnatura.es'
|
STACK_NAME = "${env.PROJECT_NAME}-${env.BRANCH_NAME}"
|
||||||
PORT_MASTER_FRONT = '5002'
|
|
||||||
PORT_MASTER_BACK = '3001'
|
|
||||||
PORT_TEST_FRONT = '5001'
|
|
||||||
PORT_TEST_BACK = '4001'
|
|
||||||
TAG = "${env.BRANCH_NAME}"
|
|
||||||
}
|
}
|
||||||
stages {
|
stages {
|
||||||
stage('Checkout') {
|
stage('Checkout') {
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
env.STACK_NAME = "${env.PROJECT_NAME}-${env.BRANCH_NAME}"
|
|
||||||
|
|
||||||
if (!env.GIT_COMMITTER_EMAIL) {
|
if (!env.GIT_COMMITTER_EMAIL) {
|
||||||
env.COMMITTER_EMAIL = sh(
|
env.COMMITTER_EMAIL = sh(
|
||||||
script: 'git --no-pager show -s --format="%ae"',
|
script: 'git --no-pager show -s --format="%ae"',
|
||||||
|
@ -29,16 +22,6 @@ pipeline {
|
||||||
env.COMMITTER_EMAIL = env.GIT_COMMITTER_EMAIL;
|
env.COMMITTER_EMAIL = env.GIT_COMMITTER_EMAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (env.BRANCH_NAME) {
|
|
||||||
case 'master':
|
|
||||||
env.PORT_FRONT = PORT_MASTER_FRONT
|
|
||||||
env.PORT_BACK = PORT_MASTER_BACK
|
|
||||||
break
|
|
||||||
case 'test':
|
|
||||||
env.PORT_FRONT = PORT_TEST_FRONT
|
|
||||||
env.PORT_BACK = PORT_TEST_BACK
|
|
||||||
break
|
|
||||||
}
|
|
||||||
switch (env.BRANCH_NAME) {
|
switch (env.BRANCH_NAME) {
|
||||||
case 'master':
|
case 'master':
|
||||||
env.NODE_ENV = 'production'
|
env.NODE_ENV = 'production'
|
||||||
|
@ -48,6 +31,14 @@ pipeline {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configFileProvider([
|
||||||
|
configFile(fileId: "salix.groovy",
|
||||||
|
variable: 'GROOVY_FILE')
|
||||||
|
]) {
|
||||||
|
load env.GROOVY_FILE
|
||||||
|
}
|
||||||
|
|
||||||
sh 'printenv'
|
sh 'printenv'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,8 +48,8 @@ pipeline {
|
||||||
}
|
}
|
||||||
steps {
|
steps {
|
||||||
nodejs('node-lts') {
|
nodejs('node-lts') {
|
||||||
sh 'npm install --no-audit'
|
sh 'npm install --no-audit --prefer-offline'
|
||||||
sh 'gulp install'
|
sh 'gulp install --ci'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,4 +2,5 @@ apps:
|
||||||
- script: ./loopback/server/server.js
|
- script: ./loopback/server/server.js
|
||||||
name: salix-back
|
name: salix-back
|
||||||
instances: 1
|
instances: 1
|
||||||
max_restarts: 5
|
max_restarts: 3
|
||||||
|
restart_delay: 15000
|
||||||
|
|
|
@ -125,13 +125,13 @@ proc: BEGIN
|
||||||
INSERT INTO tmp.ticketComponent
|
INSERT INTO tmp.ticketComponent
|
||||||
SELECT tcb.warehouseFk,
|
SELECT tcb.warehouseFk,
|
||||||
tcb.itemFk,
|
tcb.itemFk,
|
||||||
cr.id,
|
c.id,
|
||||||
GREATEST(IFNULL(ROUND(tcb.base * cr.tax, 4), 0), tcc.minPrice - tcc.rate3)
|
GREATEST(IFNULL(ROUND(tcb.base * c.tax, 4), 0), tcc.minPrice - tcc.rate3)
|
||||||
FROM tmp.ticketComponentBase tcb
|
FROM tmp.ticketComponentBase tcb
|
||||||
JOIN componentRate cr
|
JOIN component c
|
||||||
JOIN tmp.ticketComponentCalculate tcc ON tcc.itemFk = tcb.itemFk AND tcc.warehouseFk = tcb.warehouseFk
|
JOIN tmp.ticketComponentCalculate tcc ON tcc.itemFk = tcb.itemFk AND tcc.warehouseFk = tcb.warehouseFk
|
||||||
LEFT JOIN specialPrice sp ON sp.clientFk = vClientFk AND sp.itemFk = tcc.itemFk
|
LEFT JOIN specialPrice sp ON sp.clientFk = vClientFk AND sp.itemFk = tcc.itemFk
|
||||||
WHERE cr.id = vDiscountLastItemComponent AND cr.tax <> 0 AND tcc.minPrice < tcc.rate3 AND sp.value IS NULL;
|
WHERE c.id = vDiscountLastItemComponent AND c.tax <> 0 AND tcc.minPrice < tcc.rate3 AND sp.value IS NULL;
|
||||||
|
|
||||||
INSERT INTO tmp.ticketComponent
|
INSERT INTO tmp.ticketComponent
|
||||||
SELECT tcc.warehouseFk, tcc.itemFk, vSellByPacketComponent, tcc.rate2 - tcc.rate3
|
SELECT tcc.warehouseFk, tcc.itemFk, vSellByPacketComponent, tcc.rate2 - tcc.rate3
|
||||||
|
@ -178,9 +178,9 @@ proc: BEGIN
|
||||||
vSpecialPriceComponent,
|
vSpecialPriceComponent,
|
||||||
sp.value - SUM(tcc.cost) sumCost
|
sp.value - SUM(tcc.cost) sumCost
|
||||||
FROM tmp.ticketComponentCopy tcc
|
FROM tmp.ticketComponentCopy tcc
|
||||||
JOIN componentRate cr ON cr.id = tcc.componentFk
|
JOIN component c ON c.id = tcc.componentFk
|
||||||
JOIN specialPrice sp ON sp.clientFk = vClientFK AND sp.itemFk = tcc.itemFk
|
JOIN specialPrice sp ON sp.clientFk = vClientFK AND sp.itemFk = tcc.itemFk
|
||||||
WHERE cr.classRate IS NULL
|
WHERE c.classRate IS NULL
|
||||||
GROUP BY tcc.itemFk, tcc.warehouseFk
|
GROUP BY tcc.itemFk, tcc.warehouseFk
|
||||||
HAVING ABS(sumCost) > 0.001;
|
HAVING ABS(sumCost) > 0.001;
|
||||||
|
|
||||||
|
@ -188,10 +188,10 @@ proc: BEGIN
|
||||||
CREATE TEMPORARY TABLE tmp.ticketComponentSum
|
CREATE TEMPORARY TABLE tmp.ticketComponentSum
|
||||||
(INDEX (itemFk, warehouseFk))
|
(INDEX (itemFk, warehouseFk))
|
||||||
ENGINE = MEMORY
|
ENGINE = MEMORY
|
||||||
SELECT SUM(cost) sumCost, tc.itemFk, tc.warehouseFk, cr.classRate
|
SELECT SUM(cost) sumCost, tc.itemFk, tc.warehouseFk, c.classRate
|
||||||
FROM tmp.ticketComponent tc
|
FROM tmp.ticketComponent tc
|
||||||
JOIN componentRate cr ON cr.id = tc.componentFk
|
JOIN component c ON c.id = tc.componentFk
|
||||||
GROUP BY tc.itemFk, tc.warehouseFk, cr.classRate;
|
GROUP BY tc.itemFk, tc.warehouseFk, c.classRate;
|
||||||
|
|
||||||
DROP TEMPORARY TABLE IF EXISTS tmp.ticketComponentRate;
|
DROP TEMPORARY TABLE IF EXISTS tmp.ticketComponentRate;
|
||||||
CREATE TEMPORARY TABLE tmp.ticketComponentRate ENGINE = MEMORY
|
CREATE TEMPORARY TABLE tmp.ticketComponentRate ENGINE = MEMORY
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('Thermograph', '*', '*', 'ALLOW', 'ROLE', 'buyer');
|
||||||
|
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('TravelThermograph', '*', '*', 'ALLOW', 'ROLE', 'buyer');
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -53,20 +53,20 @@ INSERT INTO `hedera`.`tpvConfig`(`id`, `currency`, `terminal`, `transactionType`
|
||||||
VALUES
|
VALUES
|
||||||
(1, 978, 1, 0, 2000, 9, 0);
|
(1, 978, 1, 0, 2000, 9, 0);
|
||||||
|
|
||||||
INSERT INTO `account`.`user`(`id`,`name`,`password`,`role`,`active`,`email`,`lang`)
|
INSERT INTO `account`.`user`(`id`,`name`,`nickname`, `password`,`role`,`active`,`email`,`lang`)
|
||||||
VALUES
|
VALUES
|
||||||
(101, 'BruceWayne', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'BruceWayne@mydomain.com', 'es'),
|
(101, 'BruceWayne', 'Bruce Wayne', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'BruceWayne@mydomain.com', 'es'),
|
||||||
(102, 'PetterParker', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'PetterParker@mydomain.com', 'en'),
|
(102, 'PetterParker', 'Petter Parker', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'PetterParker@mydomain.com', 'en'),
|
||||||
(103, 'ClarkKent', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'ClarkKent@mydomain.com', 'fr'),
|
(103, 'ClarkKent', 'Clark Kent', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'ClarkKent@mydomain.com', 'fr'),
|
||||||
(104, 'TonyStark', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'TonyStark@mydomain.com', 'es'),
|
(104, 'TonyStark', 'Tony Stark', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'TonyStark@mydomain.com', 'es'),
|
||||||
(105, 'MaxEisenhardt', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'MaxEisenhardt@mydomain.com', 'pt'),
|
(105, 'MaxEisenhardt', 'Max Eisenhardt', 'ac754a330530832ba1bf7687f577da91', 2, 1, 'MaxEisenhardt@mydomain.com', 'pt'),
|
||||||
(106, 'DavidCharlesHaller', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'DavidCharlesHaller@mydomain.com', 'es'),
|
(106, 'DavidCharlesHaller', 'David Charles Haller', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'DavidCharlesHaller@mydomain.com', 'es'),
|
||||||
(107, 'HankPym', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'HankPym@mydomain.com', 'es'),
|
(107, 'HankPym', 'Hank Pym', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'HankPym@mydomain.com', 'es'),
|
||||||
(108, 'CharlesXavier', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'CharlesXavier@mydomain.com', 'es'),
|
(108, 'CharlesXavier', 'Charles Xavier', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'CharlesXavier@mydomain.com', 'es'),
|
||||||
(109, 'BruceBanner', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'BruceBanner@mydomain.com', 'es'),
|
(109, 'BruceBanner', 'Bruce Banner', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'BruceBanner@mydomain.com', 'es'),
|
||||||
(110, 'JessicaJones', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'JessicaJones@mydomain.com', 'es'),
|
(110, 'JessicaJones', 'Jessica Jones', 'ac754a330530832ba1bf7687f577da91', 1, 1, 'JessicaJones@mydomain.com', 'es'),
|
||||||
(111, 'Missing', 'ac754a330530832ba1bf7687f577da91', 2, 0, NULL, 'es'),
|
(111, 'Missing', 'Missing', 'ac754a330530832ba1bf7687f577da91', 2, 0, NULL, 'es'),
|
||||||
(112, 'Trash', 'ac754a330530832ba1bf7687f577da91', 2, 0, NULL, 'es');
|
(112, 'Trash', 'Trash', 'ac754a330530832ba1bf7687f577da91', 2, 0, NULL, 'es');
|
||||||
|
|
||||||
INSERT INTO `vn`.`worker`(`id`, `code`, `firstName`, `lastName`, `userFk`,`bossFk`)
|
INSERT INTO `vn`.`worker`(`id`, `code`, `firstName`, `lastName`, `userFk`,`bossFk`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -643,7 +643,8 @@ INSERT INTO `vn`.`itemType`(`id`, `code`, `name`, `categoryFk`, `life`,`workerFk
|
||||||
(2, 'ITG', 'Anthurium', 1, 31, 5, 0),
|
(2, 'ITG', 'Anthurium', 1, 31, 5, 0),
|
||||||
(3, 'WPN', 'Paniculata', 2, 31, 5, 0),
|
(3, 'WPN', 'Paniculata', 2, 31, 5, 0),
|
||||||
(4, 'PRT', 'Delivery ports', 3, NULL, 5, 1),
|
(4, 'PRT', 'Delivery ports', 3, NULL, 5, 1),
|
||||||
(5, 'CON', 'Container', 3, NULL, 5, 1);
|
(5, 'CON', 'Container', 3, NULL, 5, 1),
|
||||||
|
(6, 'ALS', 'Alstroemeria', 1, 31, 5, 0);
|
||||||
|
|
||||||
INSERT INTO `vn`.`ink`(`id`, `name`, `picture`, `showOrder`)
|
INSERT INTO `vn`.`ink`(`id`, `name`, `picture`, `showOrder`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -1549,7 +1550,7 @@ INSERT INTO `postgresql`.`profile`(`profile_id`, `person_id`, `profile_type_id`)
|
||||||
FROM `postgresql`.`person` `p`;
|
FROM `postgresql`.`person` `p`;
|
||||||
|
|
||||||
INSERT INTO `postgresql`.`business`(`business_id`, `client_id`, `provider_id`, `date_start`, `date_end`, `workerBusiness`, `reasonEndFk`)
|
INSERT INTO `postgresql`.`business`(`business_id`, `client_id`, `provider_id`, `date_start`, `date_end`, `workerBusiness`, `reasonEndFk`)
|
||||||
SELECT p.profile_id, p.profile_id, 1000, CONCAT(YEAR(DATE_ADD(CURDATE(), INTERVAL -1 YEAR)), '-12-31'), CONCAT(YEAR(DATE_ADD(CURDATE(), INTERVAL +1 YEAR)), '-01-25'), CONCAT('E-46-',RPAD(CONCAT(p.profile_id,9),8,p.profile_id)), NULL
|
SELECT p.profile_id, p.profile_id, 1000, CONCAT(YEAR(DATE_ADD(CURDATE(), INTERVAL -1 YEAR)), '-12-25'), CONCAT(YEAR(DATE_ADD(CURDATE(), INTERVAL +1 YEAR)), '-01-25'), CONCAT('E-46-',RPAD(CONCAT(p.profile_id,9),8,p.profile_id)), NULL
|
||||||
FROM `postgresql`.`profile` `p`;
|
FROM `postgresql`.`profile` `p`;
|
||||||
|
|
||||||
INSERT INTO `postgresql`.`business_labour`(`business_id`, `notes`, `department_id`, `professional_category_id`, `incentivo`, `calendar_labour_type_id`, `porhoras`, `labour_agreement_id`, `workcenter_id`)
|
INSERT INTO `postgresql`.`business_labour`(`business_id`, `notes`, `department_id`, `professional_category_id`, `incentivo`, `calendar_labour_type_id`, `porhoras`, `labour_agreement_id`, `workcenter_id`)
|
||||||
|
@ -1586,20 +1587,20 @@ INSERT INTO `postgresql`.`calendar_state` (`calendar_state_id`, `type`, `rgb`, `
|
||||||
|
|
||||||
INSERT INTO `postgresql`.`calendar_employee` (`business_id`, `calendar_state_id`, `date`)
|
INSERT INTO `postgresql`.`calendar_employee` (`business_id`, `calendar_state_id`, `date`)
|
||||||
VALUES
|
VALUES
|
||||||
(106, 1, DATE_ADD(CURDATE(), INTERVAL 10 DAY)),
|
(106, 1, IF(MONTH(CURDATE()) = 12 AND DAY(CURDATE()) > 10, DATE_ADD(CURDATE(), INTERVAL -10 DAY), DATE_ADD(CURDATE(), INTERVAL 10 DAY))),
|
||||||
(106, 1, DATE_ADD(CURDATE(), INTERVAL 11 DAY)),
|
(106, 1, IF(MONTH(CURDATE()) = 12 AND DAY(CURDATE()) > 10, DATE_ADD(CURDATE(), INTERVAL -11 DAY), DATE_ADD(CURDATE(), INTERVAL 11 DAY))),
|
||||||
(106, 1, DATE_ADD(CURDATE(), INTERVAL 12 DAY)),
|
(106, 1, IF(MONTH(CURDATE()) = 12 AND DAY(CURDATE()) > 10, DATE_ADD(CURDATE(), INTERVAL -12 DAY), DATE_ADD(CURDATE(), INTERVAL 12 DAY))),
|
||||||
(106, 1, DATE_ADD(CURDATE(), INTERVAL 20 DAY)),
|
(106, 1, IF(MONTH(CURDATE()) = 12 AND DAY(CURDATE()) > 10, DATE_ADD(CURDATE(), INTERVAL -20 DAY), DATE_ADD(CURDATE(), INTERVAL 20 DAY))),
|
||||||
(106, 2, DATE_ADD(CURDATE(), INTERVAL -10 DAY)),
|
(106, 2, IF(MONTH(CURDATE()) >= 1 AND DAY(CURDATE()) > 20, DATE_ADD(CURDATE(), INTERVAL -13 DAY), DATE_ADD(CURDATE(), INTERVAL 13 DAY))),
|
||||||
(106, 1, DATE_ADD(CURDATE(), INTERVAL -12 DAY)),
|
(106, 1, IF(MONTH(CURDATE()) >= 1 AND DAY(CURDATE()) > 20, DATE_ADD(CURDATE(), INTERVAL -14 DAY), DATE_ADD(CURDATE(), INTERVAL 14 DAY))),
|
||||||
(106, 2, DATE_ADD(CURDATE(), INTERVAL -20 DAY)),
|
(106, 2, IF(MONTH(CURDATE()) >= 1 AND DAY(CURDATE()) > 20, DATE_ADD(CURDATE(), INTERVAL -15 DAY), DATE_ADD(CURDATE(), INTERVAL 15 DAY))),
|
||||||
(107, 1, DATE_ADD(CURDATE(), INTERVAL 15 DAY)),
|
(107, 1, IF(MONTH(CURDATE()) = 12 AND DAY(CURDATE()) > 10, DATE_ADD(CURDATE(), INTERVAL -10 DAY), DATE_ADD(CURDATE(), INTERVAL 10 DAY))),
|
||||||
(107, 1, DATE_ADD(CURDATE(), INTERVAL 16 DAY)),
|
(107, 1, IF(MONTH(CURDATE()) = 12 AND DAY(CURDATE()) > 10, DATE_ADD(CURDATE(), INTERVAL -11 DAY), DATE_ADD(CURDATE(), INTERVAL 11 DAY))),
|
||||||
(107, 1, DATE_ADD(CURDATE(), INTERVAL 20 DAY)),
|
(107, 1, IF(MONTH(CURDATE()) = 12 AND DAY(CURDATE()) > 10, DATE_ADD(CURDATE(), INTERVAL -12 DAY), DATE_ADD(CURDATE(), INTERVAL 12 DAY))),
|
||||||
(107, 1, DATE_ADD(CURDATE(), INTERVAL 30 DAY)),
|
(107, 1, IF(MONTH(CURDATE()) = 12 AND DAY(CURDATE()) > 10, DATE_ADD(CURDATE(), INTERVAL -20 DAY), DATE_ADD(CURDATE(), INTERVAL 20 DAY))),
|
||||||
(107, 2, DATE_ADD(CURDATE(), INTERVAL -10 DAY)),
|
(107, 2, IF(MONTH(CURDATE()) >= 1 AND DAY(CURDATE()) > 20, DATE_ADD(CURDATE(), INTERVAL -13 DAY), DATE_ADD(CURDATE(), INTERVAL 13 DAY))),
|
||||||
(107, 1, DATE_ADD(CURDATE(), INTERVAL -12 DAY)),
|
(107, 1, IF(MONTH(CURDATE()) >= 1 AND DAY(CURDATE()) > 20, DATE_ADD(CURDATE(), INTERVAL -14 DAY), DATE_ADD(CURDATE(), INTERVAL 14 DAY))),
|
||||||
(107, 2, DATE_ADD(CURDATE(), INTERVAL -20 DAY));
|
(107, 2, IF(MONTH(CURDATE()) >= 1 AND DAY(CURDATE()) > 20, DATE_ADD(CURDATE(), INTERVAL -15 DAY), DATE_ADD(CURDATE(), INTERVAL 15 DAY)));
|
||||||
|
|
||||||
INSERT INTO `vn`.`smsConfig` (`id`, `uri`, `title`)
|
INSERT INTO `vn`.`smsConfig` (`id`, `uri`, `title`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -1901,7 +1902,8 @@ INSERT INTO `vn`.`dms`(`id`, `dmsTypeFk`, `file`, `contentType`, `workerFk`, `wa
|
||||||
(1, 14, '1.txt', 'text/plain', 5, 1, 442, NULL, FALSE, 'Ticket:11', 'Ticket:11 dms for the ticket', CURDATE()),
|
(1, 14, '1.txt', 'text/plain', 5, 1, 442, NULL, FALSE, 'Ticket:11', 'Ticket:11 dms for the ticket', CURDATE()),
|
||||||
(2, 5, '2.txt', 'text/plain', 5, 1, 442, 1, TRUE, 'Client:104', 'Client:104 dms for the client', CURDATE()),
|
(2, 5, '2.txt', 'text/plain', 5, 1, 442, 1, TRUE, 'Client:104', 'Client:104 dms for the client', CURDATE()),
|
||||||
(3, 5, '3.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'Client: 104', 'Client:104 readme', CURDATE()),
|
(3, 5, '3.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'Client: 104', 'Client:104 readme', CURDATE()),
|
||||||
(4, 3, '3.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'Worker: 106', 'Worker:106 readme', CURDATE());
|
(4, 3, '4.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'Worker: 106', 'Worker:106 readme', CURDATE()),
|
||||||
|
(5, 5, '5.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'travel: 1', 'dmsForThermograph', CURDATE());
|
||||||
|
|
||||||
INSERT INTO `vn`.`ticketDms`(`ticketFk`, `dmsFk`)
|
INSERT INTO `vn`.`ticketDms`(`ticketFk`, `dmsFk`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -1998,3 +2000,16 @@ INSERT INTO `vn`.`workerTimeControlParams` (`id`, `dayBreak`, `weekBreak`, `week
|
||||||
(1, 43200, 129600, 734400, 43200, 50400);
|
(1, 43200, 129600, 734400, 43200, 50400);
|
||||||
|
|
||||||
INSERT IGNORE INTO `vn`.`greugeConfig` (`id`, `freightPickUpPrice`) VALUES ('1', '11');
|
INSERT IGNORE INTO `vn`.`greugeConfig` (`id`, `freightPickUpPrice`) VALUES ('1', '11');
|
||||||
|
|
||||||
|
INSERT INTO `vn`.`thermograph`(`id`, `model`)
|
||||||
|
VALUES
|
||||||
|
('TMM190901395', 'TEMPMATE'),
|
||||||
|
('TL.BBA85422', 'TL30'),
|
||||||
|
('TZ1905012010', 'DISPOSABLE');
|
||||||
|
|
||||||
|
INSERT INTO `vn`.`travelThermograph`(`thermographFk`, `created`, `warehouseFk`, `travelFk`, `temperature`, `result`, `dmsFk`)
|
||||||
|
VALUES
|
||||||
|
('TMM190901395', CURDATE(), 1, 1, 'WARM', 'Ok', NULL),
|
||||||
|
('TL.BBA85422', DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 2, 2, 'COOL', 'Ok', NULL),
|
||||||
|
('TL.BBA85422', CURDATE(), 2, 1, 'COOL', 'can not read the temperature', NULL),
|
||||||
|
('TZ1905012010', CURDATE(), 1, 1, 'WARM', 'Temperature in range', 5);
|
File diff suppressed because it is too large
Load Diff
|
@ -1,28 +1,45 @@
|
||||||
version: '3.5'
|
version: '3.7'
|
||||||
services:
|
services:
|
||||||
front:
|
front:
|
||||||
image: registry.verdnatura.es/salix-front:${TAG}
|
image: registry.verdnatura.es/salix-front:${BRANCH_NAME:?}
|
||||||
restart: unless-stopped
|
build:
|
||||||
build:
|
context: .
|
||||||
context: .
|
dockerfile: front/Dockerfile
|
||||||
dockerfile: front/Dockerfile
|
ports:
|
||||||
ports:
|
- ${FRONT_PORT:?}:80
|
||||||
- ${PORT_FRONT}:80
|
deploy:
|
||||||
links:
|
replicas: 3
|
||||||
- back
|
back:
|
||||||
deploy:
|
image: registry.verdnatura.es/salix-back:${BRANCH_NAME:?}
|
||||||
replicas: 3
|
build: .
|
||||||
back:
|
ports:
|
||||||
image: registry.verdnatura.es/salix-back:${TAG}
|
- ${BACK_PORT:?}:3000
|
||||||
restart: unless-stopped
|
environment:
|
||||||
build: .
|
- NODE_ENV
|
||||||
ports:
|
configs:
|
||||||
- ${PORT_BACK}:3000
|
- source: datasources
|
||||||
environment:
|
target: /etc/salix/datasources.json
|
||||||
- NODE_ENV
|
- source: datasources_local
|
||||||
volumes:
|
target: /etc/salix/datasources.local.json
|
||||||
- /mnt/storage/containers/salix:/etc/salix
|
- source: print
|
||||||
- /mnt/storage/pdfs:/var/lib/salix/pdfs
|
target: /etc/salix/print.json
|
||||||
- /mnt/storage/dms:/var/lib/salix/dms
|
- source: print_local
|
||||||
deploy:
|
target: /etc/salix/print.local.json
|
||||||
replicas: 6
|
volumes:
|
||||||
|
- /mnt/storage/pdfs:/var/lib/salix/pdfs
|
||||||
|
- /mnt/storage/dms:/var/lib/salix/dms
|
||||||
|
deploy:
|
||||||
|
replicas: 6
|
||||||
|
configs:
|
||||||
|
datasources:
|
||||||
|
external: true
|
||||||
|
name: salix_datasources
|
||||||
|
datasources_local:
|
||||||
|
external: true
|
||||||
|
name: salix-${BRANCH_NAME:?}_datasources
|
||||||
|
print:
|
||||||
|
external: true
|
||||||
|
name: salix_print
|
||||||
|
print_local:
|
||||||
|
external: true
|
||||||
|
name: salix-${BRANCH_NAME:?}_print
|
||||||
|
|
|
@ -164,8 +164,8 @@ export default {
|
||||||
},
|
},
|
||||||
clientBalance: {
|
clientBalance: {
|
||||||
balanceButton: 'vn-left-menu a[ui-sref="client.card.balance.index"]',
|
balanceButton: 'vn-left-menu a[ui-sref="client.card.balance.index"]',
|
||||||
companyAutocomplete: 'vn-client-balance-index vn-autocomplete[ng-model="$ctrl.companyFk"]',
|
companyAutocomplete: 'vn-client-balance-index vn-autocomplete[ng-model="$ctrl.companyId"]',
|
||||||
newPaymentButton: 'vn-float-button',
|
newPaymentButton: `vn-float-button`,
|
||||||
newPaymentBank: '.vn-dialog.shown vn-autocomplete[ng-model="$ctrl.receipt.bankFk"]',
|
newPaymentBank: '.vn-dialog.shown vn-autocomplete[ng-model="$ctrl.receipt.bankFk"]',
|
||||||
newPaymentAmountInput: '.vn-dialog.shown [ng-model="$ctrl.receipt.amountPaid"]',
|
newPaymentAmountInput: '.vn-dialog.shown [ng-model="$ctrl.receipt.amountPaid"]',
|
||||||
saveButton: '.vn-dialog.shown vn-button[label="Save"]',
|
saveButton: '.vn-dialog.shown vn-button[label="Save"]',
|
||||||
|
@ -603,8 +603,8 @@ export default {
|
||||||
orderByAutocomplete: 'vn-autocomplete[label="Order by"]',
|
orderByAutocomplete: 'vn-autocomplete[label="Order by"]',
|
||||||
plantRealmButton: 'vn-order-catalog > vn-side-menu vn-icon[icon="icon-plant"]',
|
plantRealmButton: 'vn-order-catalog > vn-side-menu vn-icon[icon="icon-plant"]',
|
||||||
typeAutocomplete: 'vn-autocomplete[data="$ctrl.itemTypes"]',
|
typeAutocomplete: 'vn-autocomplete[data="$ctrl.itemTypes"]',
|
||||||
itemIdInput: 'vn-catalog-filter [ng-model="$ctrl.itemFk"]',
|
itemIdInput: 'vn-catalog-filter vn-textfield[ng-model="$ctrl.itemId"]',
|
||||||
itemTagValueInput: 'vn-catalog-filter [ng-model="$ctrl.value"]',
|
itemTagValueInput: 'vn-catalog-filter vn-textfield[ng-model="$ctrl.value"]',
|
||||||
openTagSearch: 'vn-catalog-filter > div > vn-vertical > vn-textfield[ng-model="$ctrl.value"] .append i',
|
openTagSearch: 'vn-catalog-filter > div > vn-vertical > vn-textfield[ng-model="$ctrl.value"] .append i',
|
||||||
tagAutocomplete: 'vn-order-catalog-search-panel vn-autocomplete[ng-model="filter.tagFk"]',
|
tagAutocomplete: 'vn-order-catalog-search-panel vn-autocomplete[ng-model="filter.tagFk"]',
|
||||||
tagValueInput: 'vn-order-catalog-search-panel [ng-model="filter.value"]',
|
tagValueInput: 'vn-order-catalog-search-panel [ng-model="filter.value"]',
|
||||||
|
|
|
@ -34,7 +34,7 @@ describe('Route basic Data path', () => {
|
||||||
.waitToGetProperty(`${selectors.routeBasicData.workerAutoComplete} input`, 'value');
|
.waitToGetProperty(`${selectors.routeBasicData.workerAutoComplete} input`, 'value');
|
||||||
|
|
||||||
|
|
||||||
expect(worker).toEqual('adminBossNick');
|
expect(worker).toEqual('adminBoss - adminBossNick');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should confirm the vehicle was edited', async() => {
|
it('should confirm the vehicle was edited', async() => {
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
No service for the specified zone: No hay servicio para la zona especificada
|
|
@ -11,11 +11,9 @@
|
||||||
|
|
||||||
.vn-droppable,
|
.vn-droppable,
|
||||||
[vn-droppable] {
|
[vn-droppable] {
|
||||||
display: block;
|
|
||||||
|
|
||||||
&.dropping {
|
&.dropping {
|
||||||
background-color: $color-hover-cd;
|
background-color: $color-hover-cd;
|
||||||
border-color: $color-bg-dark;
|
border-color: $color-font-secondary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
module.exports = {
|
const crudModel = {
|
||||||
|
_data: [1, 2, 3],
|
||||||
data: [],
|
data: [],
|
||||||
filter: {},
|
filter: {},
|
||||||
order: {},
|
order: {},
|
||||||
|
@ -31,7 +32,28 @@ module.exports = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
refresh: () => {},
|
refresh: () => {
|
||||||
addFilter: () => {},
|
return {
|
||||||
applyFilter: () => {},
|
then: callback => {
|
||||||
|
return callback({data: {id: 1234}});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
addFilter: () => {
|
||||||
|
return {
|
||||||
|
then: callback => {
|
||||||
|
return callback({data: {id: 1234}});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
applyFilter: () => {
|
||||||
|
crudModel.data = crudModel._data;
|
||||||
|
return {
|
||||||
|
then: callback => {
|
||||||
|
return callback({data: {id: 1234}});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module.exports = crudModel;
|
||||||
|
|
|
@ -7,7 +7,7 @@ vn-app {
|
||||||
ui-view {
|
ui-view {
|
||||||
display: block;
|
display: block;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
height: inherit;
|
height: 100%;
|
||||||
|
|
||||||
&.ng-enter {
|
&.ng-enter {
|
||||||
animation-name: nothing, slideIn;
|
animation-name: nothing, slideIn;
|
||||||
|
|
|
@ -87,6 +87,8 @@ vn-layout {
|
||||||
& > * {
|
& > * {
|
||||||
display: block;
|
display: block;
|
||||||
padding: $spacing-md;
|
padding: $spacing-md;
|
||||||
|
box-sizing: border-box;
|
||||||
|
height: 100%
|
||||||
}
|
}
|
||||||
&.ng-enter {
|
&.ng-enter {
|
||||||
vn-side-menu {
|
vn-side-menu {
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
transition: all 0.5s;
|
transition: all 0.5s;
|
||||||
padding: $spacing-sm;
|
padding: $spacing-sm;
|
||||||
position: relative;
|
position: relative;
|
||||||
opacity: 0.7;
|
|
||||||
width: 28em;
|
width: 28em;
|
||||||
|
|
||||||
.image {
|
.image {
|
||||||
|
@ -20,6 +19,7 @@
|
||||||
0 1px 5px 0 rgba(0,0,0,.12);
|
0 1px 5px 0 rgba(0,0,0,.12);
|
||||||
background: no-repeat center center fixed;
|
background: no-repeat center center fixed;
|
||||||
background-size: cover !important;
|
background-size: cover !important;
|
||||||
|
border: 2px solid transparent;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
cursor: zoom-in;
|
cursor: zoom-in;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
top: 1em
|
top: 1em
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.photo:hover {
|
.photo:hover .image {
|
||||||
opacity: 1
|
border: 2px solid $color-primary
|
||||||
}
|
}
|
||||||
}
|
}
|
49
gulpfile.js
49
gulpfile.js
|
@ -101,6 +101,7 @@ async function backTestOnce() {
|
||||||
gulp.src(backSpecFiles)
|
gulp.src(backSpecFiles)
|
||||||
.pipe(jasmine(options))
|
.pipe(jasmine(options))
|
||||||
.on('end', resolve)
|
.on('end', resolve)
|
||||||
|
.on('error', reject)
|
||||||
.resume();
|
.resume();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -110,27 +111,33 @@ backTestOnce.description = `Runs the backend tests once, can receive --junit arg
|
||||||
|
|
||||||
async function backTestDockerOnce() {
|
async function backTestDockerOnce() {
|
||||||
let containerId = await docker();
|
let containerId = await docker();
|
||||||
|
let err;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await backTestOnce();
|
await backTestOnce();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw e;
|
err = e;
|
||||||
} finally {
|
|
||||||
if (argv['random'])
|
|
||||||
await execP(`docker rm -fv ${containerId}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (argv['random'])
|
||||||
|
await execP(`docker rm -fv ${containerId}`);
|
||||||
|
if (err) throw err;
|
||||||
}
|
}
|
||||||
backTestDockerOnce.description = `Runs backend tests using in site container once`;
|
backTestDockerOnce.description = `Runs backend tests using in site container once`;
|
||||||
|
|
||||||
async function backTestDocker() {
|
async function backTestDocker() {
|
||||||
let containerId = await docker();
|
let containerId = await docker();
|
||||||
|
let err;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await backTest();
|
await backTest();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw e;
|
err = e;
|
||||||
} finally {
|
|
||||||
if (argv['random'])
|
|
||||||
await execP(`docker rm -fv ${containerId}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (argv['random'])
|
||||||
|
await execP(`docker rm -fv ${containerId}`);
|
||||||
|
if (err) throw err;
|
||||||
}
|
}
|
||||||
backTestDocker.description = `Runs backend tests restoring fixtures first`;
|
backTestDocker.description = `Runs backend tests restoring fixtures first`;
|
||||||
|
|
||||||
|
@ -283,14 +290,15 @@ function install() {
|
||||||
const install = require('gulp-install');
|
const install = require('gulp-install');
|
||||||
const print = require('gulp-print');
|
const print = require('gulp-print');
|
||||||
|
|
||||||
|
let npmArgs = [];
|
||||||
|
if (argv.ci) npmArgs = ['--no-audit', '--prefer-offline'];
|
||||||
|
|
||||||
let packageFiles = ['front/package.json', 'print/package.json'];
|
let packageFiles = ['front/package.json', 'print/package.json'];
|
||||||
return gulp.src(packageFiles)
|
return gulp.src(packageFiles)
|
||||||
.pipe(print(filepath => {
|
.pipe(print(filepath => {
|
||||||
return `Installing packages in ${filepath}`;
|
return `Installing packages in ${filepath}`;
|
||||||
}))
|
}))
|
||||||
.pipe(install({
|
.pipe(install({npm: npmArgs}));
|
||||||
npm: ['--no-package-lock']
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
install.description = `Installs node dependencies in all directories`;
|
install.description = `Installs node dependencies in all directories`;
|
||||||
|
|
||||||
|
@ -472,15 +480,22 @@ async function docker() {
|
||||||
let result = await execP(`docker run --env RUN_CHOWN=${runChown} -d ${dockerArgs} salix-db`);
|
let result = await execP(`docker run --env RUN_CHOWN=${runChown} -d ${dockerArgs} salix-db`);
|
||||||
containerId = result.stdout;
|
containerId = result.stdout;
|
||||||
|
|
||||||
if (argv['random']) {
|
try {
|
||||||
let inspect = await execP(`docker inspect -f "{{json .NetworkSettings}}" ${containerId}`);
|
if (argv['random']) {
|
||||||
let netSettings = JSON.parse(inspect.stdout);
|
let inspect = await execP(`docker inspect -f "{{json .NetworkSettings}}" ${containerId}`);
|
||||||
|
let netSettings = JSON.parse(inspect.stdout);
|
||||||
|
|
||||||
dbConf.host = netSettings.Gateway;
|
dbConf.host = netSettings.Gateway;
|
||||||
dbConf.port = netSettings.Ports['3306/tcp'][0]['HostPort'];
|
dbConf.port = netSettings.Ports['3306/tcp'][0]['HostPort'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (runChown) await dockerWait();
|
||||||
|
} catch (err) {
|
||||||
|
if (argv['random'])
|
||||||
|
await execP(`docker rm -fv ${containerId}`);
|
||||||
|
throw err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (runChown) await dockerWait();
|
|
||||||
return containerId;
|
return containerId;
|
||||||
}
|
}
|
||||||
docker.description = `Builds the database image and runs a container`;
|
docker.description = `Builds the database image and runs a container`;
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
"multipleStatements": true,
|
"multipleStatements": true,
|
||||||
"legacyUtcDateProcessing": false,
|
"legacyUtcDateProcessing": false,
|
||||||
"timezone": "local",
|
"timezone": "local",
|
||||||
"connectTimeout": 20000,
|
"connectTimeout": 40000,
|
||||||
"acquireTimeout": 20000
|
"acquireTimeout": 20000
|
||||||
},
|
},
|
||||||
"storage": {
|
"storage": {
|
||||||
|
|
|
@ -9,7 +9,7 @@ module.exports = Self => {
|
||||||
description: 'The province id',
|
description: 'The province id',
|
||||||
required: true
|
required: true
|
||||||
}, {
|
}, {
|
||||||
arg: 'search',
|
arg: 'postCode',
|
||||||
type: 'String',
|
type: 'String',
|
||||||
description: 'The postcode'
|
description: 'The postcode'
|
||||||
}, {
|
}, {
|
||||||
|
|
|
@ -8,8 +8,14 @@ class Controller extends Section {
|
||||||
}
|
}
|
||||||
|
|
||||||
onSubmit() {
|
onSubmit() {
|
||||||
|
this.$.data = null;
|
||||||
this.$http.get(`Zones/getEvents`, {params: this.$.params})
|
this.$http.get(`Zones/getEvents`, {params: this.$.params})
|
||||||
.then(res => this.$.data = res.data);
|
.then(res => {
|
||||||
|
let data = res.data;
|
||||||
|
this.$.data = data;
|
||||||
|
if (!data.events.length)
|
||||||
|
this.vnApp.showMessage(this.$t('No service for the specified zone'));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -160,12 +160,12 @@
|
||||||
response="cancel"
|
response="cancel"
|
||||||
translate-attr="{value: 'Cancel'}">
|
translate-attr="{value: 'Cancel'}">
|
||||||
</input>
|
</input>
|
||||||
<button
|
<input
|
||||||
|
type="button"
|
||||||
ng-if="!$ctrl.isNew"
|
ng-if="!$ctrl.isNew"
|
||||||
response="delete"
|
response="delete"
|
||||||
translate>
|
translate-attr="{value: 'Delete'}">
|
||||||
Delete
|
</input>
|
||||||
</button>
|
|
||||||
<button response="accept">
|
<button response="accept">
|
||||||
<span ng-if="$ctrl.isNew" translate>Add</span>
|
<span ng-if="$ctrl.isNew" translate>Add</span>
|
||||||
<span ng-if="!$ctrl.isNew" translate>Save</span>
|
<span ng-if="!$ctrl.isNew" translate>Save</span>
|
||||||
|
|
|
@ -54,8 +54,8 @@
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td number>{{::saleClaimed.sale.price | currency: 'EUR':2}}</vn-td>
|
<vn-td number>{{::saleClaimed.sale.price | currency: 'EUR':2}}</vn-td>
|
||||||
<vn-td number>
|
<vn-td number>
|
||||||
<span class="link"
|
<span ng-class="{'link': $ctrl.isEditable}"
|
||||||
vn-tooltip="Edit discount"
|
title="{{$ctrl.isEditable ? 'Edit discount' : ''}}"
|
||||||
ng-click="$ctrl.showEditPopover($event, saleClaimed)">
|
ng-click="$ctrl.showEditPopover($event, saleClaimed)">
|
||||||
{{saleClaimed.sale.discount}} %
|
{{saleClaimed.sale.discount}} %
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -29,8 +29,10 @@ class Controller {
|
||||||
set salesClaimed(value) {
|
set salesClaimed(value) {
|
||||||
this._salesClaimed = value;
|
this._salesClaimed = value;
|
||||||
|
|
||||||
if (value)
|
if (value) {
|
||||||
this.calculateTotals();
|
this.calculateTotals();
|
||||||
|
this.isClaimEditable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get salesClaimed() {
|
get salesClaimed() {
|
||||||
|
@ -119,13 +121,14 @@ class Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
showEditPopover(event, saleClaimed) {
|
showEditPopover(event, saleClaimed) {
|
||||||
this.saleClaimed = saleClaimed;
|
if (this.isEditable) {
|
||||||
|
if (!this.aclService.hasAny(['salesAssistant']))
|
||||||
|
return this.vnApp.showError(this.$translate.instant('Insuficient permisos'));
|
||||||
|
|
||||||
if (!this.aclService.hasAny(['salesAssistant']))
|
this.saleClaimed = saleClaimed;
|
||||||
return this.vnApp.showError(this.$translate.instant('Insuficient permisos'));
|
this.$.editPopover.parent = event.target;
|
||||||
|
this.$.editPopover.show();
|
||||||
this.$.editPopover.parent = event.target;
|
}
|
||||||
this.$.editPopover.show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getSalespersonMana() {
|
getSalespersonMana() {
|
||||||
|
@ -134,6 +137,12 @@ class Controller {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isClaimEditable() {
|
||||||
|
this.$http.get(`Tickets/${this.claim.ticketFk}/isEditable`).then(res => {
|
||||||
|
this.isEditable = res.data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
updateDiscount() {
|
updateDiscount() {
|
||||||
const claimedSale = this.saleClaimed.sale;
|
const claimedSale = this.saleClaimed.sale;
|
||||||
if (this.newDiscount != claimedSale.discount) {
|
if (this.newDiscount != claimedSale.discount) {
|
||||||
|
|
|
@ -17,13 +17,14 @@ describe('claim', () => {
|
||||||
show: () => {}
|
show: () => {}
|
||||||
};
|
};
|
||||||
$httpBackend = _$httpBackend_;
|
$httpBackend = _$httpBackend_;
|
||||||
$httpBackend.when('GET', 'Claims/ClaimBeginnings').respond({});
|
$httpBackend.whenGET('Claims/ClaimBeginnings').respond({});
|
||||||
|
$httpBackend.whenGET(`Tickets/1/isEditable`).respond(true);
|
||||||
$state = _$state_;
|
$state = _$state_;
|
||||||
aclService = {hasAny: () => true};
|
aclService = {hasAny: () => true};
|
||||||
controller = $componentController('vnClaimDetail', {$state, aclService, $scope});
|
controller = $componentController('vnClaimDetail', {$state, aclService, $scope});
|
||||||
|
controller.claim = {ticketFk: 1};
|
||||||
controller.salesToClaim = [{saleFk: 1}, {saleFk: 2}];
|
controller.salesToClaim = [{saleFk: 1}, {saleFk: 2}];
|
||||||
controller.salesClaimed = [{id: 1, sale: {}}];
|
controller.salesClaimed = [{id: 1, sale: {}}];
|
||||||
controller.claim = {ticketFk: 1};
|
|
||||||
controller.$.model = crudModel;
|
controller.$.model = crudModel;
|
||||||
controller.$.addSales = {
|
controller.$.addSales = {
|
||||||
hide: () => {},
|
hide: () => {},
|
||||||
|
@ -36,7 +37,6 @@ describe('claim', () => {
|
||||||
|
|
||||||
describe('openAddSalesDialog()', () => {
|
describe('openAddSalesDialog()', () => {
|
||||||
it('should call getClaimableFromTicket and $.addSales.show', () => {
|
it('should call getClaimableFromTicket and $.addSales.show', () => {
|
||||||
controller.$ = {addSales: {show: () => {}}};
|
|
||||||
spyOn(controller, 'getClaimableFromTicket');
|
spyOn(controller, 'getClaimableFromTicket');
|
||||||
spyOn(controller.$.addSales, 'show');
|
spyOn(controller.$.addSales, 'show');
|
||||||
controller.openAddSalesDialog();
|
controller.openAddSalesDialog();
|
||||||
|
@ -146,5 +146,14 @@ describe('claim', () => {
|
||||||
expect(controller.$.descriptor.show).toHaveBeenCalledWith();
|
expect(controller.$.descriptor.show).toHaveBeenCalledWith();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('isClaimEditable()', () => {
|
||||||
|
it('should check if the claim is editable', () => {
|
||||||
|
controller.isClaimEditable();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.isEditable).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,31 +5,28 @@
|
||||||
data="$ctrl.photos">
|
data="$ctrl.photos">
|
||||||
</vn-crud-model>
|
</vn-crud-model>
|
||||||
|
|
||||||
<section class="drop-zone" vn-droppable="$ctrl.onDrop($event)">
|
<vn-horizontal class="photo-list drop-zone" vn-droppable="$ctrl.onDrop($event)">
|
||||||
<section><vn-icon icon="add_circle"></vn-icon></section>
|
<section class="empty-rows" ng-if="!$ctrl.photos.length">
|
||||||
<section translate>Drag & Drop files here...</section>
|
<section><vn-icon icon="image"></vn-icon></section>
|
||||||
</section>
|
<section translate>Drag & Drop photos here...</section>
|
||||||
<vn-data-viewer
|
</section>
|
||||||
model="model"
|
<section class="photo" ng-repeat="photo in $ctrl.photos">
|
||||||
class="vn-w-xl">
|
<section class="image vn-shadow" on-error-src
|
||||||
<vn-horizontal class="photo-list">
|
ng-style="{'background': 'url(/api/dms/' + photo.dmsFk + '/downloadFile?access_token=' + $ctrl.accessToken + ')'}"
|
||||||
<section class="photo" ng-repeat="photo in $ctrl.photos">
|
zoom-image="/api/dms/{{::photo.dmsFk}}/downloadFile?access_token={{::$ctrl.accessToken}}">
|
||||||
<section class="image vn-shadow" on-error-src
|
|
||||||
ng-style="{'background': 'url(/api/dms/' + photo.dmsFk + '/downloadFile?access_token=' + $ctrl.accessToken + ')'}"
|
|
||||||
zoom-image="/api/dms/{{::photo.dmsFk}}/downloadFile?access_token={{::$ctrl.accessToken}}">
|
|
||||||
</section>
|
|
||||||
<section class="actions">
|
|
||||||
<vn-button
|
|
||||||
class="round"
|
|
||||||
ng-click="$ctrl.showDeleteConfirm($index)"
|
|
||||||
title="{{'Remove file' | translate}}"
|
|
||||||
tabindex="-1"
|
|
||||||
icon="delete">
|
|
||||||
</vn-button>
|
|
||||||
</section>
|
|
||||||
</section>
|
</section>
|
||||||
</vn-horizontal>
|
<section class="actions">
|
||||||
</vn-data-viewer>
|
<vn-button
|
||||||
|
class="round"
|
||||||
|
ng-click="$ctrl.showDeleteConfirm($index)"
|
||||||
|
title="{{'Remove file' | translate}}"
|
||||||
|
tabindex="-1"
|
||||||
|
icon="delete">
|
||||||
|
</vn-button>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
</vn-horizontal>
|
||||||
|
|
||||||
<vn-worker-descriptor-popover
|
<vn-worker-descriptor-popover
|
||||||
vn-id="workerDescriptor">
|
vn-id="workerDescriptor">
|
||||||
</vn-worker-descriptor-popover>
|
</vn-worker-descriptor-popover>
|
||||||
|
@ -38,4 +35,10 @@
|
||||||
message="This file will be deleted"
|
message="This file will be deleted"
|
||||||
question="Are you sure you want to continue?"
|
question="Are you sure you want to continue?"
|
||||||
on-response="$ctrl.deleteDms($response)">
|
on-response="$ctrl.deleteDms($response)">
|
||||||
</vn-confirm>
|
</vn-confirm>
|
||||||
|
<vn-float-button fixed-bottom-right
|
||||||
|
icon="add"
|
||||||
|
vn-tooltip="Select photo"
|
||||||
|
vn-bind="+"
|
||||||
|
ng-click="$ctrl.openUploadDialog()">
|
||||||
|
</vn-float-button>
|
||||||
|
|
|
@ -68,6 +68,19 @@ class Controller {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
openUploadDialog() {
|
||||||
|
const element = document.createElement('input');
|
||||||
|
element.setAttribute('type', 'file');
|
||||||
|
element.setAttribute('multiple', true);
|
||||||
|
element.click();
|
||||||
|
|
||||||
|
element.addEventListener('change', () =>
|
||||||
|
this.setDefaultParams().then(() => {
|
||||||
|
this.dms.files = element.files;
|
||||||
|
this.create();
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
create() {
|
create() {
|
||||||
const query = `claims/${this.claim.id}/uploadFile`;
|
const query = `claims/${this.claim.id}/uploadFile`;
|
||||||
|
|
|
@ -2,13 +2,16 @@
|
||||||
|
|
||||||
vn-claim-dms-index {
|
vn-claim-dms-index {
|
||||||
.drop-zone {
|
.drop-zone {
|
||||||
border: 2px dashed $color-font-secondary;
|
|
||||||
color: $color-font-secondary;
|
color: $color-font-secondary;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: 2em $spacing-md;
|
|
||||||
border-radius: 0.5em;
|
border-radius: 0.5em;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 1.4em;
|
min-height: 100%;
|
||||||
|
|
||||||
|
.empty-rows {
|
||||||
|
padding: 5em $spacing-md;
|
||||||
|
font-size: 1.4em
|
||||||
|
}
|
||||||
|
|
||||||
vn-icon {
|
vn-icon {
|
||||||
font-size: 3em
|
font-size: 3em
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
FileDescription: Ticket id {{ticketId}} from client {{clientName}} id {{clientId}}
|
|
||||||
ContentTypesInfo: Allowed file types {{allowedContentTypes}}
|
|
|
@ -1,4 +1,5 @@
|
||||||
Are you sure you want to continue?: ¿Seguro que quieres continuar?
|
Are you sure you want to continue?: ¿Seguro que quieres continuar?
|
||||||
Drag & Drop files here...: Arrastra y suelta archivos aquí...
|
Drag & Drop photos here...: Arrastra y suelta fotos aquí...
|
||||||
Photo deleted: Foto eliminada
|
Photo deleted: Foto eliminada
|
||||||
Photo uploaded!: Foto subida!
|
Photo uploaded!: Foto subida!
|
||||||
|
Select photo: Seleccionar foto
|
|
@ -1,12 +1,10 @@
|
||||||
@import "./variables";
|
@import "./variables";
|
||||||
|
|
||||||
vn-claim-summary {
|
vn-claim-summary {
|
||||||
.photo {
|
section.photo {
|
||||||
height: 15.5em;
|
height: 15.5em
|
||||||
}
|
}
|
||||||
.photo .image {
|
.photo .image {
|
||||||
border: 2px solid $color-bg-dark;
|
border-radius: 0.2em
|
||||||
border-radius: 0.2em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -7,7 +7,7 @@ describe('Client activeWorkersWithRole', () => {
|
||||||
|
|
||||||
let isSalesPerson = await app.models.Account.hasRole(result[0].id, 'salesPerson');
|
let isSalesPerson = await app.models.Account.hasRole(result[0].id, 'salesPerson');
|
||||||
|
|
||||||
expect(result.length).toEqual(13);
|
expect(result.length).toEqual(14);
|
||||||
expect(isSalesPerson).toBeTruthy();
|
expect(isSalesPerson).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ describe('Client listWorkers', () => {
|
||||||
.then(result => {
|
.then(result => {
|
||||||
let amountOfEmployees = Object.keys(result).length;
|
let amountOfEmployees = Object.keys(result).length;
|
||||||
|
|
||||||
expect(amountOfEmployees).toEqual(48);
|
expect(amountOfEmployees).toEqual(49);
|
||||||
done();
|
done();
|
||||||
})
|
})
|
||||||
.catch(done.fail);
|
.catch(done.fail);
|
||||||
|
|
|
@ -11,10 +11,15 @@ module.exports = Self => {
|
||||||
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
|
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
|
||||||
http: {source: 'query'}
|
http: {source: 'query'}
|
||||||
}, {
|
}, {
|
||||||
arg: 'params',
|
arg: 'clientId',
|
||||||
type: 'Object',
|
type: 'Number',
|
||||||
description: 'clientFk',
|
description: 'The client id',
|
||||||
http: {source: 'query'}
|
required: true,
|
||||||
|
}, {
|
||||||
|
arg: 'companyId',
|
||||||
|
type: 'Number',
|
||||||
|
description: 'The company id',
|
||||||
|
required: true,
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
returns: {
|
returns: {
|
||||||
|
@ -27,7 +32,7 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.filter = async(filter, params) => {
|
Self.filter = async(filter, clientId, companyId) => {
|
||||||
let stmt = new ParameterizedSQL(
|
let stmt = new ParameterizedSQL(
|
||||||
`SELECT * FROM (
|
`SELECT * FROM (
|
||||||
SELECT
|
SELECT
|
||||||
|
@ -72,10 +77,10 @@ module.exports = Self => {
|
||||||
ORDER BY payed DESC, created DESC
|
ORDER BY payed DESC, created DESC
|
||||||
) t
|
) t
|
||||||
ORDER BY payed DESC, created DESC`, [
|
ORDER BY payed DESC, created DESC`, [
|
||||||
params.clientFk,
|
clientId,
|
||||||
params.companyFk,
|
companyId,
|
||||||
params.clientFk,
|
clientId,
|
||||||
params.companyFk,
|
companyId,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -2,12 +2,10 @@ const app = require('vn-loopback/server/server');
|
||||||
|
|
||||||
describe('receipt filter()', () => {
|
describe('receipt filter()', () => {
|
||||||
it('should return the receipts', async() => {
|
it('should return the receipts', async() => {
|
||||||
let filter = {limit: 20};
|
const filter = {limit: 20};
|
||||||
let params = {
|
const clientId = 101;
|
||||||
clientFk: 101,
|
const companyId = 442;
|
||||||
companyFk: 442
|
let result = await app.models.Receipt.filter(filter, clientId, companyId);
|
||||||
};
|
|
||||||
let result = await app.models.Receipt.filter(filter, params);
|
|
||||||
|
|
||||||
expect(result.length).toBeGreaterThan(0);
|
expect(result.length).toBeGreaterThan(0);
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,10 +2,12 @@ import ngModule from '../../module';
|
||||||
import './style.scss';
|
import './style.scss';
|
||||||
|
|
||||||
class Controller {
|
class Controller {
|
||||||
constructor($http, $scope, $stateParams) {
|
constructor($http, $scope, $stateParams, $translate, vnApp) {
|
||||||
this.$http = $http;
|
this.$http = $http;
|
||||||
this.$scope = $scope;
|
this.$scope = $scope;
|
||||||
this.$stateParams = $stateParams;
|
this.$stateParams = $stateParams;
|
||||||
|
this.$translate = $translate;
|
||||||
|
this.vnApp = vnApp;
|
||||||
this.filter = {
|
this.filter = {
|
||||||
fields: [
|
fields: [
|
||||||
'id',
|
'id',
|
||||||
|
@ -51,6 +53,7 @@ class Controller {
|
||||||
if (res.data) {
|
if (res.data) {
|
||||||
this.client.defaultAddressFk = res.data.defaultAddressFk;
|
this.client.defaultAddressFk = res.data.defaultAddressFk;
|
||||||
this.sortAddresses();
|
this.sortAddresses();
|
||||||
|
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -69,7 +72,7 @@ class Controller {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Controller.$inject = ['$http', '$scope', '$stateParams'];
|
Controller.$inject = ['$http', '$scope', '$stateParams', '$translate', 'vnApp'];
|
||||||
|
|
||||||
ngModule.component('vnClientAddressIndex', {
|
ngModule.component('vnClientAddressIndex', {
|
||||||
template: require('./index.html'),
|
template: require('./index.html'),
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
<vn-crud-model
|
<vn-crud-model
|
||||||
vn-id="model"
|
vn-id="model"
|
||||||
url="receipts/filter"
|
url="receipts/filter"
|
||||||
params="$ctrl.params"
|
|
||||||
limit="20"
|
limit="20"
|
||||||
data="$ctrl.balances"
|
data="$ctrl.balances">
|
||||||
auto-load="true">
|
|
||||||
</vn-crud-model>
|
</vn-crud-model>
|
||||||
<vn-crud-model
|
<vn-crud-model
|
||||||
vn-id="riskModel"
|
vn-id="riskModel"
|
||||||
|
@ -21,8 +19,7 @@
|
||||||
<vn-autocomplete
|
<vn-autocomplete
|
||||||
vn-id="company"
|
vn-id="company"
|
||||||
class="dense"
|
class="dense"
|
||||||
ng-model="$ctrl.companyFk"
|
ng-model="$ctrl.companyId"
|
||||||
on-change="$ctrl.setOrder(value)"
|
|
||||||
url="Companies"
|
url="Companies"
|
||||||
show-field="code"
|
show-field="code"
|
||||||
value-field="id"
|
value-field="id"
|
||||||
|
|
|
@ -16,75 +16,53 @@ class Controller {
|
||||||
scope: {
|
scope: {
|
||||||
fields: ['code'],
|
fields: ['code'],
|
||||||
},
|
},
|
||||||
},
|
|
||||||
where: {
|
|
||||||
clientFk: $stateParams.id,
|
|
||||||
companyFk: this.companyFk
|
|
||||||
},
|
|
||||||
};
|
|
||||||
this.params = {
|
|
||||||
params: {
|
|
||||||
clientFk: this.$stateParams.id,
|
|
||||||
companyFk: this.companyFk,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
get companyFk() {
|
|
||||||
if (!this._companyFk)
|
|
||||||
return this.vnConfig.companyFk;
|
|
||||||
|
|
||||||
return this._companyFk;
|
|
||||||
}
|
|
||||||
|
|
||||||
set companyFk(id) {
|
|
||||||
this._companyFk = id;
|
|
||||||
}
|
|
||||||
setOrder(value) {
|
|
||||||
this.params.params.companyFk = value;
|
|
||||||
this.filter.where.companyFk = value;
|
|
||||||
this.refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
refresh() {
|
|
||||||
this.$.model.refresh();
|
|
||||||
this.$.riskModel.refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
set balances(value) {
|
|
||||||
this._balances = value;
|
|
||||||
|
|
||||||
if (!value) return;
|
|
||||||
const params = {filter: this.filter};
|
|
||||||
this.$http.get(`ClientRisks`, {params}).then(response => {
|
|
||||||
if (response.data) {
|
|
||||||
this.clientRisks = response.data;
|
|
||||||
|
|
||||||
this.getBalances();
|
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
get balances() {
|
get companyId() {
|
||||||
return this._balances;
|
if (!this._companyId)
|
||||||
|
this.companyId = this.vnConfig.companyFk;
|
||||||
|
|
||||||
|
return this._companyId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set companyId(value) {
|
||||||
|
this._companyId = value;
|
||||||
|
|
||||||
|
if (value) this.getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
getData() {
|
||||||
|
return this.$.model.applyFilter(null, {
|
||||||
|
clientId: this.$stateParams.id,
|
||||||
|
companyId: this.companyId
|
||||||
|
}).then(() => this.$.riskModel.applyFilter({
|
||||||
|
where: {
|
||||||
|
clientFk: this.$stateParams.id,
|
||||||
|
companyFk: this.companyId
|
||||||
|
}
|
||||||
|
})).then(() => this.getBalances());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
getCurrentBalance() {
|
getCurrentBalance() {
|
||||||
const selectedCompany = this.$.company.selection;
|
const clientRisks = this.$.riskModel.data;
|
||||||
const currentBalance = this.clientRisks.find(balance => {
|
const selectedCompany = this.companyId;
|
||||||
return balance.companyFk === selectedCompany.id;
|
const currentBalance = clientRisks.find(balance => {
|
||||||
|
return balance.companyFk === selectedCompany;
|
||||||
});
|
});
|
||||||
|
|
||||||
return currentBalance.amount;
|
return currentBalance.amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
getBalances() {
|
getBalances() {
|
||||||
this.balances.forEach((balance, index) => {
|
const balances = this.$.model.data;
|
||||||
|
balances.forEach((balance, index) => {
|
||||||
if (index === 0)
|
if (index === 0)
|
||||||
balance.balance = this.getCurrentBalance();
|
balance.balance = this.getCurrentBalance();
|
||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
let previousBalance = this.balances[index - 1];
|
let previousBalance = balances[index - 1];
|
||||||
|
|
||||||
balance.balance = previousBalance.balance - (previousBalance.debit - previousBalance.credit);
|
balance.balance = previousBalance.balance - (previousBalance.debit - previousBalance.credit);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -92,10 +70,8 @@ class Controller {
|
||||||
|
|
||||||
|
|
||||||
openCreateDialog() {
|
openCreateDialog() {
|
||||||
this.$.balanceCreateDialog.companyFk = this.companyFk;
|
this.$.balanceCreateDialog.companyFk = this.companyId;
|
||||||
this.$.balanceCreateDialog.onResponse = () => {
|
this.$.balanceCreateDialog.onResponse = () => this.getData();
|
||||||
this.refresh();
|
|
||||||
};
|
|
||||||
this.$.balanceCreateDialog.show();
|
this.$.balanceCreateDialog.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,41 +3,98 @@ import './index';
|
||||||
describe('Client', () => {
|
describe('Client', () => {
|
||||||
describe('Component vnClientBalanceIndex', () => {
|
describe('Component vnClientBalanceIndex', () => {
|
||||||
let $componentController;
|
let $componentController;
|
||||||
let $scope;
|
|
||||||
let $httpBackend;
|
|
||||||
let $httpParamSerializer;
|
|
||||||
let controller;
|
let controller;
|
||||||
|
|
||||||
beforeEach(ngModule('client'));
|
beforeEach(ngModule('client'));
|
||||||
|
|
||||||
beforeEach(angular.mock.inject((_$componentController_, $rootScope, _$httpBackend_, _$httpParamSerializer_) => {
|
beforeEach(angular.mock.inject((_$componentController_, $rootScope) => {
|
||||||
$componentController = _$componentController_;
|
$componentController = _$componentController_;
|
||||||
$httpBackend = _$httpBackend_;
|
let $scope = $rootScope.$new();
|
||||||
$httpParamSerializer = _$httpParamSerializer_;
|
|
||||||
$scope = $rootScope.$new();
|
|
||||||
controller = $componentController('vnClientBalanceIndex', {$scope});
|
controller = $componentController('vnClientBalanceIndex', {$scope});
|
||||||
|
controller.$.model = {applyFilter: () => {}};
|
||||||
|
controller.$.riskModel = {
|
||||||
|
applyFilter: () => {},
|
||||||
|
data:
|
||||||
|
[{
|
||||||
|
clientFk: 101,
|
||||||
|
companyFk: 442,
|
||||||
|
amount: 713.24,
|
||||||
|
company: {
|
||||||
|
id: 442,
|
||||||
|
code: 'VNL'
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
};
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe('balances() setter', () => {
|
describe('getData()', () => {
|
||||||
it('should calculate the balance for each line from the oldest date to the newest', () => {
|
it('should apply the filters on he models and get the client balance', () => {
|
||||||
controller.getCurrentBalance = jasmine.createSpy(controller, 'getCurrentBalance').and.returnValue(1000);
|
controller._companyId = 442;
|
||||||
let balances = [
|
controller.$stateParams.id = 101;
|
||||||
{credit: -100, debit: 0},
|
spyOn(controller, 'getBalances');
|
||||||
{credit: 0, debit: 300},
|
spyOn(controller.$.model, 'applyFilter').and.returnValue(Promise.resolve());
|
||||||
{credit: 100, debit: 0},
|
spyOn(controller.$.riskModel, 'applyFilter').and.returnValue(Promise.resolve());
|
||||||
{credit: 0, debit: -300}
|
|
||||||
];
|
|
||||||
const params = {filter: controller.filter};
|
|
||||||
let serializedParams = $httpParamSerializer(params);
|
|
||||||
$httpBackend.when('GET', `ClientRisks?${serializedParams}`).respond(balances);
|
|
||||||
$httpBackend.expect('GET', `ClientRisks?${serializedParams}`);
|
|
||||||
controller.balances = balances;
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.balances[0].balance).toEqual(1000);
|
controller.getData().then(() => {
|
||||||
expect(controller.balances[1].balance).toEqual(900);
|
expect(controller.$.model.applyFilter).toHaveBeenCalledWith(null, {'clientId': 101, 'companyId': 442});
|
||||||
expect(controller.balances[2].balance).toEqual(600);
|
expect(controller.$.riskModel.applyFilter).toHaveBeenCalledWith({'where': {'clientFk': 101, 'companyFk': 442}});
|
||||||
expect(controller.balances[3].balance).toEqual(700);
|
expect(controller.getBalances).toHaveBeenCalledWith();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('company setter/getter', () => {
|
||||||
|
it('should return the company', () => {
|
||||||
|
controller.companyId = null;
|
||||||
|
|
||||||
|
expect(controller._companyId).toEqual(jasmine.any(Object));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the company and then call getData()', () => {
|
||||||
|
spyOn(controller, 'getData');
|
||||||
|
controller.companyId = 442;
|
||||||
|
|
||||||
|
expect(controller._companyId).toEqual(442);
|
||||||
|
expect(controller.getData).toHaveBeenCalledWith();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getCurrentBalance()', () => {
|
||||||
|
it('should return the client balance amount', () => {
|
||||||
|
controller._companyId = 442;
|
||||||
|
let result = controller.getCurrentBalance();
|
||||||
|
|
||||||
|
expect(result).toEqual(713.24);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getBalances()', () => {
|
||||||
|
it('should return the total client balance amount', () => {
|
||||||
|
spyOn(controller, 'getCurrentBalance').and.callThrough();
|
||||||
|
controller._companyId = 442;
|
||||||
|
controller.$.model = {data:
|
||||||
|
[{
|
||||||
|
id: 1,
|
||||||
|
debit: 1000,
|
||||||
|
credit: null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
debit: null,
|
||||||
|
credit: 500
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
debit: null,
|
||||||
|
credit: 300
|
||||||
|
}
|
||||||
|
]};
|
||||||
|
controller.getBalances();
|
||||||
|
const expectedBalances = controller.$.model.data;
|
||||||
|
|
||||||
|
expect(expectedBalances[0].balance).toEqual(713.24);
|
||||||
|
expect(expectedBalances[1].balance).toEqual(-286.76);
|
||||||
|
expect(expectedBalances[2].balance).toEqual(213.24);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -29,13 +29,24 @@ describe('Component VnClientWebAccess', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('isCustomer()', () => {
|
describe('isCustomer()', () => {
|
||||||
it(`should perform a query if client is defined with an ID`, () => {
|
it('should return true if the password can be modified', () => {
|
||||||
controller.client = {id: '1234'};
|
controller.client = {id: '1234'};
|
||||||
controller.isCustomer();
|
|
||||||
|
|
||||||
$httpBackend.when('GET', `Clients/${controller.client.id}/hasCustomerRole`).respond('ok');
|
$httpBackend.expectGET(`Clients/${controller.client.id}/hasCustomerRole`).respond({isCustomer: true});
|
||||||
$httpBackend.expectGET(`Clients/${controller.client.id}/hasCustomerRole`);
|
controller.isCustomer();
|
||||||
$httpBackend.flush();
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.canChangePassword).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should return a false if the password can't be modified`, () => {
|
||||||
|
controller.client = {id: '1234'};
|
||||||
|
|
||||||
|
$httpBackend.expectGET(`Clients/${controller.client.id}/hasCustomerRole`).respond({isCustomer: false});
|
||||||
|
controller.isCustomer();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.canChangePassword).toBeFalsy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const app = require('vn-loopback/server/server');
|
||||||
|
|
||||||
describe('invoiceOut book()', () => {
|
describe('invoiceOut book()', () => {
|
||||||
const invoiceOutId = 1;
|
const invoiceOutId = 5;
|
||||||
let bookedDate;
|
let bookedDate;
|
||||||
let OriginalInvoiceOut;
|
let OriginalInvoiceOut;
|
||||||
let updatedInvoiceOut;
|
let updatedInvoiceOut;
|
||||||
|
|
|
@ -53,7 +53,7 @@ class Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
showInvoiceOutPdf() {
|
showInvoiceOutPdf() {
|
||||||
let url = `InvoiceOuts/${this.invoiceOut.id}/download?access_token=${this.accessToken}`;
|
let url = `api/InvoiceOuts/${this.invoiceOut.id}/download?access_token=${this.accessToken}`;
|
||||||
window.open(url, '_blank');
|
window.open(url, '_blank');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ export default class Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
openPdf(id, event) {
|
openPdf(id, event) {
|
||||||
let url = `InvoiceOuts/${id}/download?access_token=${this.accessToken}`;
|
let url = `api/InvoiceOuts/${id}/download?access_token=${this.accessToken}`;
|
||||||
window.open(url, '_blank');
|
window.open(url, '_blank');
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopImmediatePropagation();
|
event.stopImmediatePropagation();
|
||||||
|
|
|
@ -20,7 +20,7 @@ class Controller {
|
||||||
];
|
];
|
||||||
this.orderFields = [].concat(this.defaultOrderFields);
|
this.orderFields = [].concat(this.defaultOrderFields);
|
||||||
this._orderWay = this.orderWays[0].way;
|
this._orderWay = this.orderWays[0].way;
|
||||||
this._orderField = this.orderFields[0].field;
|
this.orderField = this.orderFields[0].field;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -76,15 +76,13 @@ class Controller {
|
||||||
if (value) this.applyOrder();
|
if (value) this.applyOrder();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
get orderSelection() {
|
||||||
* Get order fields
|
return this._orderSelection;
|
||||||
*/
|
|
||||||
get orderField() {
|
|
||||||
return this._orderField;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set orderField(value) {
|
set orderSelection(value) {
|
||||||
this._orderField = value;
|
this._orderSelection = value;
|
||||||
|
|
||||||
if (value) this.applyOrder();
|
if (value) this.applyOrder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,10 +92,11 @@ class Controller {
|
||||||
* @return {Object} - Order param
|
* @return {Object} - Order param
|
||||||
*/
|
*/
|
||||||
getOrderBy() {
|
getOrderBy() {
|
||||||
|
const isTag = !!(this.orderSelection && this.orderSelection.isTag);
|
||||||
return {
|
return {
|
||||||
field: this.orderField,
|
field: this.orderField,
|
||||||
way: this.orderWay,
|
way: this.orderWay,
|
||||||
isTag: !!(this.orderSelection && this.orderSelection.isTag)
|
isTag: isTag
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,27 +6,26 @@
|
||||||
</vn-crud-model>
|
</vn-crud-model>
|
||||||
<div>
|
<div>
|
||||||
<vn-horizontal class="item-category">
|
<vn-horizontal class="item-category">
|
||||||
|
<vn-autocomplete vn-id="category"
|
||||||
|
data="categories"
|
||||||
|
ng-model="$ctrl.categoryId"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id"
|
||||||
|
label="Category">
|
||||||
|
</vn-autocomplete>
|
||||||
<vn-one ng-repeat="category in categories">
|
<vn-one ng-repeat="category in categories">
|
||||||
<vn-icon
|
<vn-icon
|
||||||
ng-class="{'active': $ctrl.category.id == category.id}"
|
ng-class="{'active': $ctrl.categoryId == category.id}"
|
||||||
icon="{{::category.icon}}"
|
icon="{{::category.icon}}"
|
||||||
vn-tooltip="{{::category.name}}"
|
vn-tooltip="{{::category.name}}"
|
||||||
ng-click="$ctrl.category = {
|
ng-click="$ctrl.categoryId = category.id">
|
||||||
id: category.id,
|
|
||||||
value: category.name
|
|
||||||
}">
|
|
||||||
</vn-icon>
|
</vn-icon>
|
||||||
</vn-one>
|
</vn-one>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-vertical class="input">
|
<vn-vertical class="input">
|
||||||
<vn-autocomplete
|
<vn-autocomplete vn-id="type"
|
||||||
vn-id="type"
|
|
||||||
data="$ctrl.itemTypes"
|
data="$ctrl.itemTypes"
|
||||||
on-change="$ctrl.type = {
|
ng-model="$ctrl.typeId"
|
||||||
id: value,
|
|
||||||
value: type.selection.name
|
|
||||||
}"
|
|
||||||
ng-model="$ctrl.type.id"
|
|
||||||
show-field="name"
|
show-field="name"
|
||||||
value-field="id"
|
value-field="id"
|
||||||
label="Type"
|
label="Type"
|
||||||
|
@ -38,9 +37,6 @@
|
||||||
{{categoryName}}
|
{{categoryName}}
|
||||||
</div>
|
</div>
|
||||||
</tpl-item>
|
</tpl-item>
|
||||||
<prepend>
|
|
||||||
<vn-icon icon="search"></vn-icon>
|
|
||||||
</prepend>
|
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
</vn-vertical>
|
</vn-vertical>
|
||||||
<vn-vertical class="input vn-pt-md">
|
<vn-vertical class="input vn-pt-md">
|
||||||
|
@ -73,7 +69,7 @@
|
||||||
<vn-textfield
|
<vn-textfield
|
||||||
ng-keyUp="$ctrl.onSearchById($event)"
|
ng-keyUp="$ctrl.onSearchById($event)"
|
||||||
label="Item id"
|
label="Item id"
|
||||||
ng-model="$ctrl.itemFk">
|
ng-model="$ctrl.itemId">
|
||||||
<prepend>
|
<prepend>
|
||||||
<vn-icon icon="icon-item"></vn-icon>
|
<vn-icon icon="icon-item"></vn-icon>
|
||||||
</prepend>
|
</prepend>
|
||||||
|
@ -106,20 +102,20 @@
|
||||||
</vn-popover>
|
</vn-popover>
|
||||||
<div class="chips">
|
<div class="chips">
|
||||||
<vn-chip
|
<vn-chip
|
||||||
ng-if="$ctrl.category"
|
ng-if="category.selection"
|
||||||
removable="true"
|
removable="true"
|
||||||
translate-attr="{title: 'Category'}"
|
translate-attr="{title: 'Category'}"
|
||||||
on-remove="$ctrl.category = null"
|
on-remove="$ctrl.categoryId = null"
|
||||||
class="colored">
|
class="colored">
|
||||||
<span translate>{{$ctrl.category.value}}</span>
|
<span translate>{{category.selection.name}}</span>
|
||||||
</vn-chip>
|
</vn-chip>
|
||||||
<vn-chip
|
<vn-chip
|
||||||
ng-if="$ctrl.type"
|
ng-if="type.selection"
|
||||||
removable="true"
|
removable="true"
|
||||||
translate-attr="{title: 'Type'}"
|
translate-attr="{title: 'Type'}"
|
||||||
on-remove="$ctrl.type = null"
|
on-remove="$ctrl.typeId = null"
|
||||||
class="colored">
|
class="colored">
|
||||||
<span translate>{{$ctrl.type.value}}</span>
|
<span translate>{{type.selection.name}}</span>
|
||||||
</vn-chip>
|
</vn-chip>
|
||||||
<vn-chip
|
<vn-chip
|
||||||
ng-repeat="tag in $ctrl.tags"
|
ng-repeat="tag in $ctrl.tags"
|
||||||
|
|
|
@ -24,65 +24,50 @@ class Controller {
|
||||||
* @param {Object} value - Order data
|
* @param {Object} value - Order data
|
||||||
*/
|
*/
|
||||||
set order(value) {
|
set order(value) {
|
||||||
if (!value || !value.id || this._order) return;
|
|
||||||
this._order = value;
|
this._order = value;
|
||||||
|
|
||||||
|
if (!value) return;
|
||||||
|
|
||||||
this.$.$applyAsync(() => {
|
this.$.$applyAsync(() => {
|
||||||
let category;
|
if (this.$stateParams.categoryId)
|
||||||
let type;
|
this.categoryId = this.$stateParams.categoryId;
|
||||||
|
|
||||||
if (this.$stateParams.category)
|
if (this.$stateParams.typeId)
|
||||||
category = JSON.parse(this.$stateParams.category);
|
this.typeId = this.$stateParams.typeId;
|
||||||
|
|
||||||
if (this.$stateParams.type)
|
|
||||||
type = JSON.parse(this.$stateParams.type);
|
|
||||||
|
|
||||||
if (category && category.id)
|
|
||||||
this.category = category;
|
|
||||||
|
|
||||||
if (type && type.id)
|
|
||||||
this.type = type;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
get category() {
|
get categoryId() {
|
||||||
return this._category;
|
return this._categoryId;
|
||||||
}
|
}
|
||||||
|
|
||||||
set category(value) {
|
set categoryId(value) {
|
||||||
this.catalog.$scope.model.data = [];
|
if (!value || (this.categoryId == value))
|
||||||
this.itemTypes = [];
|
value = null;
|
||||||
this.type = null;
|
|
||||||
|
|
||||||
if (!value || (this.category && this.category.id == value.id))
|
this._categoryId = value;
|
||||||
this._category = null;
|
this.itemTypes = [];
|
||||||
else
|
this.typeId = null;
|
||||||
this._category = value;
|
|
||||||
|
|
||||||
this.updateStateParams();
|
this.updateStateParams();
|
||||||
|
|
||||||
if (this.tags.length > 0)
|
if (this.tags.length > 0)
|
||||||
this.applyFilters();
|
this.applyFilters();
|
||||||
|
|
||||||
if (this._category)
|
if (value)
|
||||||
this.updateItemTypes();
|
this.updateItemTypes();
|
||||||
}
|
}
|
||||||
|
|
||||||
get type() {
|
get typeId() {
|
||||||
return this._type;
|
return this._typeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
set type(value) {
|
set typeId(value) {
|
||||||
if (value && this.type && this.type.id == value.id) return;
|
this._typeId = value;
|
||||||
|
|
||||||
this._type = value;
|
|
||||||
|
|
||||||
if (!value || !value.id)
|
|
||||||
this._type = null;
|
|
||||||
|
|
||||||
this.updateStateParams();
|
this.updateStateParams();
|
||||||
|
|
||||||
if ((value && value.id) || this.tags.length > 0)
|
if ((value) || this.tags.length > 0)
|
||||||
this.applyFilters();
|
this.applyFilters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,17 +76,17 @@ class Controller {
|
||||||
*/
|
*/
|
||||||
updateItemTypes() {
|
updateItemTypes() {
|
||||||
let params = {
|
let params = {
|
||||||
itemCategoryId: this.category.id
|
itemCategoryId: this.categoryId
|
||||||
};
|
};
|
||||||
|
|
||||||
const query = `Orders/${this.order.id}/getItemTypeAvailable`;
|
const query = `Orders/${this.order.id}/getItemTypeAvailable`;
|
||||||
this.$http.get(query, {params}).then(res => {
|
this.$http.get(query, {params}).then(res =>
|
||||||
this.itemTypes = res.data;
|
this.itemTypes = res.data);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onSearchById(event) {
|
onSearchById(event) {
|
||||||
if (event.key === 'Enter' && (this.tags.length > 0 || this.itemFk || this.type))
|
const hasValue = this.tags.length > 0 || this.itemId || this.typeId;
|
||||||
|
if (event.key === 'Enter' && hasValue)
|
||||||
this.applyFilters();
|
this.applyFilters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +102,7 @@ class Controller {
|
||||||
remove(index) {
|
remove(index) {
|
||||||
this.tags.splice(index, 1);
|
this.tags.splice(index, 1);
|
||||||
|
|
||||||
if (this.tags.length >= 0 || this.itemFk || this.type)
|
if (this.tags.length >= 0 || this.itemId || this.typeId)
|
||||||
this.applyFilters();
|
this.applyFilters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,14 +111,14 @@ class Controller {
|
||||||
let newFilter = {};
|
let newFilter = {};
|
||||||
const model = this.catalog.$scope.model;
|
const model = this.catalog.$scope.model;
|
||||||
|
|
||||||
if (this.category)
|
if (this.categoryId)
|
||||||
newFilter.categoryFk = this.category.id;
|
newFilter.categoryFk = this.categoryId;
|
||||||
|
|
||||||
if (this.type)
|
if (this.typeId)
|
||||||
newFilter.typeFk = this.type.id;
|
newFilter.typeFk = this.typeId;
|
||||||
|
|
||||||
if (this.itemFk)
|
if (this.itemId)
|
||||||
newFilter = {'i.id': this.itemFk};
|
newFilter = {'i.id': this.itemId};
|
||||||
|
|
||||||
newParams = {
|
newParams = {
|
||||||
orderFk: this.order.id,
|
orderFk: this.order.id,
|
||||||
|
@ -164,13 +149,13 @@ class Controller {
|
||||||
updateStateParams() {
|
updateStateParams() {
|
||||||
const params = {};
|
const params = {};
|
||||||
|
|
||||||
if (this.category)
|
if (this.categoryId)
|
||||||
params.category = JSON.stringify(this.category);
|
params.categoryId = this.categoryId;
|
||||||
|
else params.categoryId = undefined;
|
||||||
|
|
||||||
if (this.type)
|
if (this.typeId)
|
||||||
params.type = JSON.stringify(this.type);
|
params.typeId = this.typeId;
|
||||||
else
|
else params.typeId = undefined;
|
||||||
params.type = undefined;
|
|
||||||
|
|
||||||
this.$state.go(this.$state.current.name, params);
|
this.$state.go(this.$state.current.name, params);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,8 @@ describe('Order', () => {
|
||||||
$scope.model = crudModel;
|
$scope.model = crudModel;
|
||||||
$scope.search = {};
|
$scope.search = {};
|
||||||
$state = _$state_;
|
$state = _$state_;
|
||||||
$state.params.category = '{"id": 1, "value": "My Category"}';
|
$state.params.categoryId = 1;
|
||||||
$state.params.type = '{"id": 1, "value": "My type"}';
|
$state.params.typeId = 2;
|
||||||
$state.current.name = 'my.current.state';
|
$state.current.name = 'my.current.state';
|
||||||
controller = $componentController('vnCatalogFilter', {$element: null, $scope, $state});
|
controller = $componentController('vnCatalogFilter', {$element: null, $scope, $state});
|
||||||
controller.catalog = {
|
controller.catalog = {
|
||||||
|
@ -35,15 +35,15 @@ describe('Order', () => {
|
||||||
|
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
|
|
||||||
expect(controller.category).toEqual({id: 1, value: 'My Category'});
|
expect(controller.categoryId).toEqual(1);
|
||||||
expect(controller.type).toEqual({id: 1, value: 'My type'});
|
expect(controller.typeId).toEqual(2);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('category() setter', () => {
|
describe('categoryId() setter', () => {
|
||||||
it(`should set category property to null, call updateStateParams() method and not call applyFilters()`, () => {
|
it(`should set category property to null, call updateStateParams() method and not call applyFilters()`, () => {
|
||||||
spyOn(controller, 'updateStateParams');
|
spyOn(controller, 'updateStateParams');
|
||||||
controller.category = null;
|
controller.categoryId = null;
|
||||||
|
|
||||||
expect(controller.updateStateParams).toHaveBeenCalledWith();
|
expect(controller.updateStateParams).toHaveBeenCalledWith();
|
||||||
});
|
});
|
||||||
|
@ -51,17 +51,17 @@ describe('Order', () => {
|
||||||
it(`should set category property and then call updateStateParams() and applyFilters() methods`, () => {
|
it(`should set category property and then call updateStateParams() and applyFilters() methods`, () => {
|
||||||
spyOn(controller, 'updateStateParams');
|
spyOn(controller, 'updateStateParams');
|
||||||
controller._order = {id: 4};
|
controller._order = {id: 4};
|
||||||
controller.category = {id: 2, value: 'My category'};
|
controller.categoryId = 2;
|
||||||
|
|
||||||
expect(controller.updateStateParams).toHaveBeenCalledWith();
|
expect(controller.updateStateParams).toHaveBeenCalledWith();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('type() setter', () => {
|
describe('typeId() setter', () => {
|
||||||
it(`should set type property to null, call updateStateParams() method and not call applyFilters()`, () => {
|
it(`should set type property to null, call updateStateParams() method and not call applyFilters()`, () => {
|
||||||
spyOn(controller, 'updateStateParams');
|
spyOn(controller, 'updateStateParams');
|
||||||
spyOn(controller, 'applyFilters');
|
spyOn(controller, 'applyFilters');
|
||||||
controller.type = null;
|
controller.typeId = null;
|
||||||
|
|
||||||
expect(controller.updateStateParams).toHaveBeenCalledWith();
|
expect(controller.updateStateParams).toHaveBeenCalledWith();
|
||||||
expect(controller.applyFilters).not.toHaveBeenCalledWith();
|
expect(controller.applyFilters).not.toHaveBeenCalledWith();
|
||||||
|
@ -70,7 +70,7 @@ describe('Order', () => {
|
||||||
it(`should set category property and then call updateStateParams() and applyFilters() methods`, () => {
|
it(`should set category property and then call updateStateParams() and applyFilters() methods`, () => {
|
||||||
spyOn(controller, 'updateStateParams');
|
spyOn(controller, 'updateStateParams');
|
||||||
spyOn(controller, 'applyFilters');
|
spyOn(controller, 'applyFilters');
|
||||||
controller.type = {id: 2, value: 'My type'};
|
controller.typeId = 2;
|
||||||
|
|
||||||
expect(controller.updateStateParams).toHaveBeenCalledWith();
|
expect(controller.updateStateParams).toHaveBeenCalledWith();
|
||||||
expect(controller.applyFilters).toHaveBeenCalledWith();
|
expect(controller.applyFilters).toHaveBeenCalledWith();
|
||||||
|
@ -101,7 +101,7 @@ describe('Order', () => {
|
||||||
describe('onSearchById()', () => {
|
describe('onSearchById()', () => {
|
||||||
it(`should not filter by id if the event key code doesn't equals to 'Enter'`, () => {
|
it(`should not filter by id if the event key code doesn't equals to 'Enter'`, () => {
|
||||||
spyOn(controller, 'applyFilters');
|
spyOn(controller, 'applyFilters');
|
||||||
controller.itemFk = 1;
|
controller.itemId = 1;
|
||||||
controller.onSearchById({key: 'Tab'});
|
controller.onSearchById({key: 'Tab'});
|
||||||
|
|
||||||
expect(controller.applyFilters).not.toHaveBeenCalledWith();
|
expect(controller.applyFilters).not.toHaveBeenCalledWith();
|
||||||
|
@ -109,7 +109,7 @@ describe('Order', () => {
|
||||||
|
|
||||||
it(`should filter by id if the event key code equals to 'Enter' an then call applyFilters()`, () => {
|
it(`should filter by id if the event key code equals to 'Enter' an then call applyFilters()`, () => {
|
||||||
spyOn(controller, 'applyFilters');
|
spyOn(controller, 'applyFilters');
|
||||||
controller.itemFk = 1;
|
controller.itemId = 1;
|
||||||
|
|
||||||
controller.onSearchById({key: 'Enter'});
|
controller.onSearchById({key: 'Enter'});
|
||||||
|
|
||||||
|
@ -121,14 +121,14 @@ describe('Order', () => {
|
||||||
it(`should call model applyFilter() method with a new filter`, () => {
|
it(`should call model applyFilter() method with a new filter`, () => {
|
||||||
let model = controller.catalog.$scope.model;
|
let model = controller.catalog.$scope.model;
|
||||||
spyOn(model, 'applyFilter');
|
spyOn(model, 'applyFilter');
|
||||||
controller._category = {id: 1, value: 'My Category'};
|
controller._categoryId = 2;
|
||||||
controller._type = {id: 1, value: 'My type'};
|
controller._typeId = 4;
|
||||||
controller._order = {id: 4};
|
controller._order = {id: 4};
|
||||||
|
|
||||||
controller.applyFilters();
|
controller.applyFilters();
|
||||||
|
|
||||||
expect(model.applyFilter).toHaveBeenCalledWith(
|
expect(model.applyFilter).toHaveBeenCalledWith(
|
||||||
{where: {categoryFk: 1, typeFk: 1}},
|
{where: {categoryFk: 2, typeFk: 4}},
|
||||||
{orderFk: 4, orderBy: controller.catalog.getOrderBy(), tags: []});
|
{orderFk: 4, orderBy: controller.catalog.getOrderBy(), tags: []});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -146,8 +146,8 @@ describe('Order', () => {
|
||||||
|
|
||||||
it(`should remove a tag from tags property and call applyFilters() if there's no more tags`, () => {
|
it(`should remove a tag from tags property and call applyFilters() if there's no more tags`, () => {
|
||||||
spyOn(controller, 'applyFilters');
|
spyOn(controller, 'applyFilters');
|
||||||
controller._category = {id: 1, value: 'My Category'};
|
controller._categoryId = 1;
|
||||||
controller._type = {id: 1, value: 'My type'};
|
controller._typeId = 1;
|
||||||
controller.tags = [{tagFk: 1, value: 'Blue'}];
|
controller.tags = [{tagFk: 1, value: 'Blue'}];
|
||||||
controller.remove(0);
|
controller.remove(0);
|
||||||
|
|
||||||
|
@ -159,9 +159,9 @@ describe('Order', () => {
|
||||||
describe('updateStateParams()', () => {
|
describe('updateStateParams()', () => {
|
||||||
it(`should call state go() method passing category and type state params`, () => {
|
it(`should call state go() method passing category and type state params`, () => {
|
||||||
spyOn(controller.$state, 'go');
|
spyOn(controller.$state, 'go');
|
||||||
controller._category = {id: 1, value: 'My Category'};
|
controller._categoryId = 2;
|
||||||
controller._type = {id: 1, value: 'My type'};
|
controller._typeId = 4;
|
||||||
let result = {category: '{"id":1,"value":"My Category"}', type: '{"id":1,"value":"My type"}'};
|
let result = {categoryId: 2, typeId: 4};
|
||||||
controller.updateStateParams();
|
controller.updateStateParams();
|
||||||
|
|
||||||
expect(controller.$state.go).toHaveBeenCalledWith('my.current.state', result);
|
expect(controller.$state.go).toHaveBeenCalledWith('my.current.state', result);
|
||||||
|
|
|
@ -14,6 +14,10 @@ vn-catalog-filter > div {
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
vn-autocomplete[vn-id="category"] {
|
||||||
|
display: none
|
||||||
|
}
|
||||||
|
|
||||||
& > vn-one {
|
& > vn-one {
|
||||||
padding: $spacing-sm;
|
padding: $spacing-sm;
|
||||||
min-width: 33.33%;
|
min-width: 33.33%;
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
"order": "$ctrl.order"
|
"order": "$ctrl.order"
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
"url": "/catalog?category&type",
|
"url": "/catalog?categoryId&typeId",
|
||||||
"state": "order.card.catalog",
|
"state": "order.card.catalog",
|
||||||
"component": "vn-order-catalog",
|
"component": "vn-order-catalog",
|
||||||
"description": "Catalog",
|
"description": "Catalog",
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<form name="form" ng-submit="$ctrl.onSubmit()" class="vn-w-md">
|
<form name="form" ng-submit="$ctrl.onSubmit()" class="vn-w-md">
|
||||||
<vn-card class="vn-pa-lg">
|
<vn-card class="vn-pa-lg">
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-autocomplete
|
<vn-autocomplete
|
||||||
vn-one
|
vn-one
|
||||||
ng-model="$ctrl.route.workerFk"
|
ng-model="$ctrl.route.workerFk"
|
||||||
url="Clients/activeWorkersWithRole"
|
url="Clients/activeWorkersWithRole"
|
||||||
|
@ -17,6 +17,9 @@
|
||||||
value-field="id"
|
value-field="id"
|
||||||
where="{role: 'employee'}"
|
where="{role: 'employee'}"
|
||||||
label="Worker">
|
label="Worker">
|
||||||
|
<tpl-item>
|
||||||
|
<div>{{name}} - {{nickname}}</div>
|
||||||
|
</tpl-item>
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
<vn-autocomplete
|
<vn-autocomplete
|
||||||
vn-one
|
vn-one
|
||||||
|
|
|
@ -7,5 +7,9 @@
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},"Currency": {
|
},"Currency": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
|
},"Thermograph": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},"TravelThermograph": {
|
||||||
|
"dataSource": "vn"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"name": "Thermograph",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "thermograph"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "String",
|
||||||
|
"id": true,
|
||||||
|
"description": "Identifier"
|
||||||
|
},
|
||||||
|
"model": {
|
||||||
|
"type": "String"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
{
|
||||||
|
"name": "TravelThermograph",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "travelThermograph"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"thermographFk": {
|
||||||
|
"type": "String",
|
||||||
|
"id": 1,
|
||||||
|
"description": "Identifier"
|
||||||
|
},
|
||||||
|
"created": {
|
||||||
|
"type": "Date",
|
||||||
|
"id": 2,
|
||||||
|
"description": "Identifier"
|
||||||
|
},
|
||||||
|
"temperature": {
|
||||||
|
"type": "String"
|
||||||
|
},
|
||||||
|
"result": {
|
||||||
|
"type": "String"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"relations": {
|
||||||
|
"travel": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "Travel",
|
||||||
|
"foreignKey": "travelFk"
|
||||||
|
},
|
||||||
|
"warehouse": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "Warehouse",
|
||||||
|
"foreignKey": "warehouseFk"
|
||||||
|
},
|
||||||
|
"dms": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "Dms",
|
||||||
|
"foreignKey": "dmsFk"
|
||||||
|
},
|
||||||
|
"thermograph": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "Thermograph",
|
||||||
|
"foreignKey": "thermographFk"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -43,7 +43,7 @@
|
||||||
</vn-one>
|
</vn-one>
|
||||||
<vn-auto>
|
<vn-auto>
|
||||||
<h4 translate>Entries</h4>
|
<h4 translate>Entries</h4>
|
||||||
<vn-table model="model">
|
<vn-table>
|
||||||
<vn-thead>
|
<vn-thead>
|
||||||
<vn-tr>
|
<vn-tr>
|
||||||
<vn-th shrink>Confirmed</vn-th>
|
<vn-th shrink>Confirmed</vn-th>
|
||||||
|
@ -51,8 +51,8 @@
|
||||||
<vn-th shrink>Supplier</vn-th>
|
<vn-th shrink>Supplier</vn-th>
|
||||||
<vn-th shrink>Reference</vn-th>
|
<vn-th shrink>Reference</vn-th>
|
||||||
<vn-th shrink title="Half box">HB</vn-th>
|
<vn-th shrink title="Half box">HB</vn-th>
|
||||||
<vn-th shrink>Freight cost</vn-th>
|
<vn-th shrink>Freight</vn-th>
|
||||||
<vn-th shrink>Package cost</vn-th>
|
<vn-th shrink>Package</vn-th>
|
||||||
<vn-th shrink>CC</vn-th>
|
<vn-th shrink>CC</vn-th>
|
||||||
<vn-th shrink>Pallet</vn-th>
|
<vn-th shrink>Pallet</vn-th>
|
||||||
<vn-th shrink>m3</vn-th>
|
<vn-th shrink>m3</vn-th>
|
||||||
|
@ -61,16 +61,18 @@
|
||||||
</vn-thead>
|
</vn-thead>
|
||||||
<vn-tbody>
|
<vn-tbody>
|
||||||
<vn-tr ng-repeat="entry in $ctrl.entries">
|
<vn-tr ng-repeat="entry in $ctrl.entries">
|
||||||
<vn-check
|
<vn-td shrink>
|
||||||
value="{{entry.isConfirmed}}"
|
<vn-check
|
||||||
disabled="true">
|
value="{{entry.isConfirmed}}"
|
||||||
</vn-check>
|
disabled="true">
|
||||||
|
</vn-check>
|
||||||
|
</vn-td>
|
||||||
<vn-td shrink>{{entry.id}} </vn-td>
|
<vn-td shrink>{{entry.id}} </vn-td>
|
||||||
<vn-td shrink>{{entry.supplierName}}</vn-td>
|
<vn-td shrink>{{entry.supplierName}}</vn-td>
|
||||||
<vn-td shrink>{{entry.ref}}</vn-td>
|
<vn-td shrink>{{entry.ref}}</vn-td>
|
||||||
<vn-td shrink>{{entry.hb}}</vn-td>
|
<vn-td shrink>{{entry.hb}}</vn-td>
|
||||||
<vn-td shrink>{{entry.freightValue}}</vn-td>
|
<vn-td shrink>{{entry.freightValue | currency: 'EUR': 2}}</vn-td>
|
||||||
<vn-td shrink>{{entry.packageValue}}</vn-td>
|
<vn-td shrink>{{entry.packageValue | currency: 'EUR': 2}}</vn-td>
|
||||||
<vn-td shrink>{{entry.cc}}</vn-td>
|
<vn-td shrink>{{entry.cc}}</vn-td>
|
||||||
<vn-td shrink>{{entry.pallet}}</vn-td>
|
<vn-td shrink>{{entry.pallet}}</vn-td>
|
||||||
<vn-td shrink>{{entry.m3}}</vn-td>
|
<vn-td shrink>{{entry.m3}}</vn-td>
|
||||||
|
@ -81,13 +83,28 @@
|
||||||
icon="insert_drive_file">
|
icon="insert_drive_file">
|
||||||
</vn-icon>
|
</vn-icon>
|
||||||
<vn-icon
|
<vn-icon
|
||||||
ng-if="entry.notes.length"
|
ng-if="entry.observation.length"
|
||||||
vn-tooltip="{{entry.observation}}"
|
vn-tooltip="{{entry.observation}}"
|
||||||
icon="insert_drive_file">
|
icon="insert_drive_file">
|
||||||
</vn-icon>
|
</vn-icon>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
</vn-tr>
|
</vn-tr>
|
||||||
</vn-tbody>
|
</vn-tbody>
|
||||||
|
<vn-tfoot>
|
||||||
|
<vn-tr>
|
||||||
|
<vn-td></vn-td>
|
||||||
|
<vn-td></vn-td>
|
||||||
|
<vn-td></vn-td>
|
||||||
|
<vn-td></vn-td>
|
||||||
|
<vn-td shrink><strong>{{$ctrl.total('hb')}}</strong></vn-td>
|
||||||
|
<vn-td shrink><strong>{{$ctrl.total('freightValue') | currency: 'EUR': 2}}</strong></vn-td>
|
||||||
|
<vn-td shrink><strong>{{$ctrl.total('packageValue') | currency: 'EUR': 2}}</strong></vn-td>
|
||||||
|
<vn-td shrink><strong>{{$ctrl.total('cc')}}</strong></vn-td>
|
||||||
|
<vn-td shrink><strong>{{$ctrl.total('pallet')}}</strong></vn-td>
|
||||||
|
<vn-td shrink><strong>{{$ctrl.total('m3')}}</strong></vn-td>
|
||||||
|
<vn-td></vn-td>
|
||||||
|
</vn-tr>
|
||||||
|
</vn-tfoot>
|
||||||
</vn-table>
|
</vn-table>
|
||||||
</vn-auto>
|
</vn-auto>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
|
|
|
@ -5,6 +5,7 @@ class Controller {
|
||||||
constructor($scope, $http) {
|
constructor($scope, $http) {
|
||||||
this.$ = $scope;
|
this.$ = $scope;
|
||||||
this.$http = $http;
|
this.$http = $http;
|
||||||
|
this.entries = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
get travel() {
|
get travel() {
|
||||||
|
@ -31,6 +32,15 @@ class Controller {
|
||||||
this.entries = response.data;
|
this.entries = response.data;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
total(field) {
|
||||||
|
let total = 0;
|
||||||
|
|
||||||
|
for (let entry of this.entries)
|
||||||
|
total += entry[field];
|
||||||
|
|
||||||
|
return total;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller.$inject = ['$scope', '$http'];
|
Controller.$inject = ['$scope', '$http'];
|
||||||
|
|
|
@ -58,4 +58,18 @@ describe('component vnTravelSummary', () => {
|
||||||
expect(controller.entries).toEqual('I am the entries');
|
expect(controller.entries).toEqual('I am the entries');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('total()', () => {
|
||||||
|
it('should calculate the total amount of a given property for every row', () => {
|
||||||
|
controller.entries = [
|
||||||
|
{id: 1, freightValue: 1, packageValue: 2, cc: 0.01},
|
||||||
|
{id: 2, freightValue: 1, packageValue: 2, cc: 0.01},
|
||||||
|
{id: 3, freightValue: 1, packageValue: 2, cc: 0.01}
|
||||||
|
];
|
||||||
|
|
||||||
|
expect(controller.total('freightValue')).toEqual(3);
|
||||||
|
expect(controller.total('packageValue')).toEqual(6);
|
||||||
|
expect(controller.total('cc')).toEqual(0.03);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,6 +12,6 @@ Confirmed: Confirmada
|
||||||
Entry Id: Entrada Id
|
Entry Id: Entrada Id
|
||||||
Supplier: Proveedor
|
Supplier: Proveedor
|
||||||
Pallet: Pallet
|
Pallet: Pallet
|
||||||
Freight cost: Coste porte
|
Freight: Porte
|
||||||
Package cost: Coste embalaje
|
Package: Embalaje
|
||||||
Half box: Media caja
|
Half box: Media caja
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const app = require('vn-loopback/server/server');
|
||||||
|
|
||||||
// #1924 - Fix hours
|
describe('Worker absences()', () => {
|
||||||
xdescribe('Worker absences()', () => {
|
|
||||||
it('should get the absence calendar for a full year contract', async() => {
|
it('should get the absence calendar for a full year contract', async() => {
|
||||||
let ctx = {req: {accessToken: {userId: 106}}};
|
let ctx = {req: {accessToken: {userId: 106}}};
|
||||||
let workerFk = 106;
|
let workerFk = 106;
|
||||||
|
@ -27,8 +26,8 @@ xdescribe('Worker absences()', () => {
|
||||||
let firstType = absences[0].absenceType().name;
|
let firstType = absences[0].absenceType().name;
|
||||||
let sixthType = absences[5].absenceType().name;
|
let sixthType = absences[5].absenceType().name;
|
||||||
|
|
||||||
expect(firstType).toEqual('Leave of absence');
|
expect(firstType).toMatch(/(Holidays|Leave of absence)/);
|
||||||
expect(sixthType).toEqual('Holidays');
|
expect(sixthType).toMatch(/(Holidays|Leave of absence)/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get the absence calendar for a permanent contract', async() => {
|
it('should get the absence calendar for a permanent contract', async() => {
|
||||||
|
@ -64,8 +63,8 @@ xdescribe('Worker absences()', () => {
|
||||||
let firstType = absences[0].absenceType().name;
|
let firstType = absences[0].absenceType().name;
|
||||||
let sixthType = absences[5].absenceType().name;
|
let sixthType = absences[5].absenceType().name;
|
||||||
|
|
||||||
expect(firstType).toEqual('Leave of absence');
|
expect(firstType).toMatch(/(Holidays|Leave of absence)/);
|
||||||
expect(sixthType).toEqual('Holidays');
|
expect(sixthType).toMatch(/(Holidays|Leave of absence)/);
|
||||||
|
|
||||||
// restores the contract end date
|
// restores the contract end date
|
||||||
await app.models.WorkerLabour.rawSql(
|
await app.models.WorkerLabour.rawSql(
|
||||||
|
@ -146,8 +145,8 @@ xdescribe('Worker absences()', () => {
|
||||||
let firstType = absences[0].absenceType().name;
|
let firstType = absences[0].absenceType().name;
|
||||||
let sixthType = absences[5].absenceType().name;
|
let sixthType = absences[5].absenceType().name;
|
||||||
|
|
||||||
expect(firstType).toEqual('Leave of absence');
|
expect(firstType).toMatch(/(Holidays|Leave of absence)/);
|
||||||
expect(sixthType).toEqual('Holidays');
|
expect(sixthType).toMatch(/(Holidays|Leave of absence)/);
|
||||||
|
|
||||||
// resets the holidays per year with originalHolidaysValue and the contract starting date
|
// resets the holidays per year with originalHolidaysValue and the contract starting date
|
||||||
await app.models.WorkCenterHoliday.updateAll(
|
await app.models.WorkCenterHoliday.updateAll(
|
||||||
|
|
|
@ -29,7 +29,7 @@ module.exports = Self => {
|
||||||
|
|
||||||
const mySubordinates = await Self.mySubordinates(ctx);
|
const mySubordinates = await Self.mySubordinates(ctx);
|
||||||
const isSubordinate = mySubordinates.find(subordinate => {
|
const isSubordinate = mySubordinates.find(subordinate => {
|
||||||
return subordinate.workerFk === id;
|
return subordinate.workerFk == id;
|
||||||
});
|
});
|
||||||
|
|
||||||
const isHr = await models.Account.hasRole(myUserId, 'hr');
|
const isHr = await models.Account.hasRole(myUserId, 'hr');
|
||||||
|
|
|
@ -19,7 +19,7 @@ vn-log {
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 1570px) {
|
@media screen and (max-width: 1570px) {
|
||||||
.expendable {
|
vn-table .expendable {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
.changes {
|
.changes {
|
||||||
|
|
|
@ -4,8 +4,10 @@ let env = process.env.NODE_ENV ? process.env.NODE_ENV : 'development';
|
||||||
let configPath = `/etc/salix`;
|
let configPath = `/etc/salix`;
|
||||||
let config = require('../config/print.json');
|
let config = require('../config/print.json');
|
||||||
let configFiles = [
|
let configFiles = [
|
||||||
|
`${appPath}/config/print.local.json`,
|
||||||
`${appPath}/config/print.${env}.json`,
|
`${appPath}/config/print.${env}.json`,
|
||||||
`${configPath}/print.json`,
|
`${configPath}/print.json`,
|
||||||
|
`${configPath}/print.local.json`,
|
||||||
`${configPath}/print.${env}.json`
|
`${configPath}/print.${env}.json`
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
const Stylesheet = require(`${appPath}/core/stylesheet`);
|
||||||
|
|
||||||
|
module.exports = new Stylesheet([
|
||||||
|
`${appPath}/common/css/spacing.css`,
|
||||||
|
`${appPath}/common/css/misc.css`,
|
||||||
|
`${appPath}/common/css/layout.css`,
|
||||||
|
`${appPath}/common/css/email.css`])
|
||||||
|
.mergeStyles();
|
|
@ -0,0 +1,69 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html v-bind:lang="locale">
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width">
|
||||||
|
<meta name="format-detection" content="telephone=no">
|
||||||
|
<title>{{ $t('subject') }}</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<table class="grid">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<!-- Empty block -->
|
||||||
|
<div class="grid-row">
|
||||||
|
<div class="grid-block empty"></div>
|
||||||
|
</div>
|
||||||
|
<!-- Header block -->
|
||||||
|
<div class="grid-row">
|
||||||
|
<div class="grid-block">
|
||||||
|
<email-header v-bind="$props"></email-header>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Block -->
|
||||||
|
<div class="grid-row">
|
||||||
|
<div class="grid-block vn-pa-lg">
|
||||||
|
<h1>{{ $t('title') }}</h1>
|
||||||
|
<p>{{$t('dear')}},</p>
|
||||||
|
<p v-html="$t('description', [dated])"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Block -->
|
||||||
|
<div class="grid-row">
|
||||||
|
<div class="grid-block vn-pa-lg">
|
||||||
|
<table class="column-oriented">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{{$t('buyer')}}</th>
|
||||||
|
<th class="number">{{$t('percentage')}}</th>
|
||||||
|
<th class="number">{{$t('dwindle')}}</th>
|
||||||
|
<th class="number">{{$t('total')}}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr v-for="waste in wastes" v-bind:key="waste.buyer">
|
||||||
|
<td class="font gray">{{waste.buyer}}</td>
|
||||||
|
<td class="number">{{(waste.percentage / 100) | percentage(4, 4, locale)}}</td>
|
||||||
|
<td class="number">{{waste.dwindle | currency('EUR', locale)}}</td>
|
||||||
|
<td class="number">{{waste.total | currency('EUR', locale)}}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Footer block -->
|
||||||
|
<div class="grid-row">
|
||||||
|
<div class="grid-block">
|
||||||
|
<email-footer v-bind="$props"></email-footer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Empty block -->
|
||||||
|
<div class="grid-row">
|
||||||
|
<div class="grid-block empty"></div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,31 @@
|
||||||
|
const Component = require(`${appPath}/core/component`);
|
||||||
|
const db = require(`${appPath}/core/database`);
|
||||||
|
const emailHeader = new Component('email-header');
|
||||||
|
const emailFooter = new Component('email-footer');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'buyer-week-waste',
|
||||||
|
async serverPrefetch() {
|
||||||
|
this.wastes = await this.fetchWastes();
|
||||||
|
|
||||||
|
if (!this.wastes)
|
||||||
|
throw new Error('Something went wrong');
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
dated: function() {
|
||||||
|
const filters = this.$options.filters;
|
||||||
|
|
||||||
|
return filters.date(new Date(), '%d-%m-%Y');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
fetchWastes() {
|
||||||
|
return db.findOne(`CALL bs.weekWaste()`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
'email-header': emailHeader.build(),
|
||||||
|
'email-footer': emailFooter.build()
|
||||||
|
},
|
||||||
|
props: {}
|
||||||
|
};
|
|
@ -0,0 +1,8 @@
|
||||||
|
subject: Merma semanal
|
||||||
|
title: Merma semanal
|
||||||
|
dear: Hola
|
||||||
|
description: A continuación se muestra la merma semanal a fecha de <strong>{0}</strong>.
|
||||||
|
buyer: Comprador
|
||||||
|
percentage: Porcentaje
|
||||||
|
weakening: Mermas
|
||||||
|
total: Total
|
|
@ -12,4 +12,4 @@ claim: Reclamación {0}
|
||||||
sections:
|
sections:
|
||||||
agency:
|
agency:
|
||||||
description: 'Para agilizar tu recogida, por favor, pónte en contacto con la oficina
|
description: 'Para agilizar tu recogida, por favor, pónte en contacto con la oficina
|
||||||
de integrados. <br/> Tlf: 96 166 77 88 - Ana Gómez (Ext. 2133) <em>(agomezf@integra2.es)</em>'
|
de integrados. <br/> Tlf: 96 166 77 88 - Ana Gómez (Ext. 2113) <em>(agomezf@integra2.es)</em>'
|
||||||
|
|
Loading…
Reference in New Issue