Merge branch 'dev' into 6321_negative_tickets
gitea/salix/pipeline/pr-dev There was a failure building this commit
Details
gitea/salix/pipeline/pr-dev There was a failure building this commit
Details
This commit is contained in:
commit
149aeac54e
|
@ -121,7 +121,7 @@ pipeline {
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
def packageJson = readJSON file: 'package.json'
|
def packageJson = readJSON file: 'package.json'
|
||||||
env.VERSION = packageJson.version
|
env.VERSION = "${packageJson.version}-vn${env.BUILD_ID}"
|
||||||
}
|
}
|
||||||
sh 'docker-compose build back'
|
sh 'docker-compose build back'
|
||||||
}
|
}
|
||||||
|
@ -159,7 +159,7 @@ pipeline {
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
def packageJson = readJSON file: 'package.json'
|
def packageJson = readJSON file: 'package.json'
|
||||||
env.VERSION = packageJson.version
|
env.VERSION = "${packageJson.version}-vn${env.BUILD_ID}"
|
||||||
}
|
}
|
||||||
sh 'gulp build'
|
sh 'gulp build'
|
||||||
sh 'docker-compose build front'
|
sh 'docker-compose build front'
|
||||||
|
@ -179,7 +179,7 @@ pipeline {
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
def packageJson = readJSON file: 'package.json'
|
def packageJson = readJSON file: 'package.json'
|
||||||
env.VERSION = packageJson.version
|
env.VERSION = "${packageJson.version}-vn${env.BUILD_ID}"
|
||||||
}
|
}
|
||||||
sh 'docker login --username $CREDENTIALS_USR --password $CREDENTIALS_PSW $REGISTRY'
|
sh 'docker login --username $CREDENTIALS_USR --password $CREDENTIALS_PSW $REGISTRY'
|
||||||
sh 'docker-compose push'
|
sh 'docker-compose push'
|
||||||
|
@ -210,7 +210,7 @@ pipeline {
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
def packageJson = readJSON file: 'package.json'
|
def packageJson = readJSON file: 'package.json'
|
||||||
env.VERSION = packageJson.version
|
env.VERSION = "${packageJson.version}-vn${env.BUILD_ID}"
|
||||||
}
|
}
|
||||||
withKubeConfig([
|
withKubeConfig([
|
||||||
serverUrl: "$KUBERNETES_API",
|
serverUrl: "$KUBERNETES_API",
|
||||||
|
|
|
@ -26,16 +26,24 @@
|
||||||
<mrw:Nif><%= expeditionData.fi %></mrw:Nif>
|
<mrw:Nif><%= expeditionData.fi %></mrw:Nif>
|
||||||
<mrw:Nombre><%= expeditionData.clientName %></mrw:Nombre>
|
<mrw:Nombre><%= expeditionData.clientName %></mrw:Nombre>
|
||||||
<mrw:Telefono><%= expeditionData.phone %></mrw:Telefono>
|
<mrw:Telefono><%= expeditionData.phone %></mrw:Telefono>
|
||||||
|
<mrw:Observaciones><%= expeditionData.deliveryObservation %></mrw:Observaciones>
|
||||||
</mrw:DatosEntrega>
|
</mrw:DatosEntrega>
|
||||||
<mrw:DatosServicio>
|
<mrw:DatosServicio>
|
||||||
<mrw:Fecha><%= expeditionData.created %></mrw:Fecha>
|
<mrw:Fecha><%= expeditionData.created %></mrw:Fecha>
|
||||||
<mrw:Referencia><%= expeditionData.expeditionDataId %></mrw:Referencia>
|
<mrw:Referencia><%= expeditionData.reference %></mrw:Referencia>
|
||||||
<mrw:CodigoServicio><%= expeditionData.serviceType %></mrw:CodigoServicio>
|
<mrw:CodigoServicio><%= expeditionData.serviceType %></mrw:CodigoServicio>
|
||||||
<mrw:NumeroBultos>1</mrw:NumeroBultos>
|
<mrw:NumeroBultos>1</mrw:NumeroBultos>
|
||||||
<mrw:EntregaSabado><%= expeditionData.weekDays %></mrw:EntregaSabado>
|
<mrw:EntregaSabado><%= expeditionData.weekDays %></mrw:EntregaSabado>
|
||||||
<mrw:Peso><%= expeditionData.kg %></mrw:Peso>
|
|
||||||
<mrw:Reembolso/>
|
<mrw:Reembolso/>
|
||||||
<mrw:ImporteReembolso/>
|
<mrw:ImporteReembolso/>
|
||||||
|
<mrw:Bultos>
|
||||||
|
<mrw:BultoRequest>
|
||||||
|
<mrw:Alto><%= mrw.defaultHeight %></mrw:Alto>
|
||||||
|
<mrw:Largo><%= mrw.defaultLength %></mrw:Largo>
|
||||||
|
<mrw:Ancho><%= mrw.defaultWidth %></mrw:Ancho>
|
||||||
|
<mrw:Peso><%= mrw.defaultWeight %></mrw:Peso>
|
||||||
|
</mrw:BultoRequest>
|
||||||
|
</mrw:Bultos>
|
||||||
</mrw:DatosServicio>
|
</mrw:DatosServicio>
|
||||||
</mrw:request>
|
</mrw:request>
|
||||||
</mrw:TransmEnvio>
|
</mrw:TransmEnvio>
|
||||||
|
|
|
@ -45,7 +45,7 @@ module.exports = Self => {
|
||||||
`SELECT
|
`SELECT
|
||||||
CASE co.code
|
CASE co.code
|
||||||
WHEN 'ES' THEN a.postalCode
|
WHEN 'ES' THEN a.postalCode
|
||||||
WHEN 'PT' THEN LEFT(a.postalCode, 4)
|
WHEN 'PT' THEN LEFT(a.postalCode, mc.portugalPostCodeTrim)
|
||||||
WHEN 'AD' THEN REPLACE(a.postalCode, 'AD', '00')
|
WHEN 'AD' THEN REPLACE(a.postalCode, 'AD', '00')
|
||||||
END postalCode,
|
END postalCode,
|
||||||
a.city,
|
a.city,
|
||||||
|
@ -56,9 +56,10 @@ module.exports = Self => {
|
||||||
c.phone,
|
c.phone,
|
||||||
DATE_FORMAT(t.shipped, '%d/%m/%Y') created,
|
DATE_FORMAT(t.shipped, '%d/%m/%Y') created,
|
||||||
t.shipped,
|
t.shipped,
|
||||||
e.id expeditionId,
|
CONCAT( e.ticketFk, LPAD(e.counter, mc.counterWidth, '0')) reference,
|
||||||
LPAD(IF(mw.params IS NULL, ms.serviceType, mw.serviceType), 4 ,'0') serviceType,
|
LPAD(IF(mw.params IS NULL, ms.serviceType, mw.serviceType), mc.serviceTypeWidth,'0') serviceType,
|
||||||
IF(mw.weekdays, 'S', 'N') weekDays
|
IF(mw.weekdays, 'S', 'N') weekDays,
|
||||||
|
oa.description deliveryObservation
|
||||||
FROM expedition e
|
FROM expedition e
|
||||||
JOIN ticket t ON e.ticketFk = t.id
|
JOIN ticket t ON e.ticketFk = t.id
|
||||||
JOIN agencyMode am ON am.id = t.agencyModeFk
|
JOIN agencyMode am ON am.id = t.agencyModeFk
|
||||||
|
@ -66,8 +67,12 @@ module.exports = Self => {
|
||||||
LEFT JOIN mrwServiceWeekday mw ON mw.weekdays = DATE_FORMAT(t.shipped, '%a')
|
LEFT JOIN mrwServiceWeekday mw ON mw.weekdays = DATE_FORMAT(t.shipped, '%a')
|
||||||
JOIN client c ON t.clientFk = c.id
|
JOIN client c ON t.clientFk = c.id
|
||||||
JOIN address a ON t.addressFk = a.id
|
JOIN address a ON t.addressFk = a.id
|
||||||
|
LEFT JOIN addressObservation oa ON oa.addressFk = a.id
|
||||||
|
LEFT JOIN observationType ot ON ot.id = oa.observationTypeFk
|
||||||
|
AND ot.code = 'delivery'
|
||||||
JOIN province p ON a.provinceFk = p.id
|
JOIN province p ON a.provinceFk = p.id
|
||||||
JOIN country co ON co.id = p.countryFk
|
JOIN country co ON co.id = p.countryFk
|
||||||
|
JOIN mrwConfig mc
|
||||||
WHERE e.id = ?
|
WHERE e.id = ?
|
||||||
LIMIT 1`;
|
LIMIT 1`;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,16 @@
|
||||||
{
|
{
|
||||||
"name": "Collection",
|
"name": "Collection",
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"id": true,
|
||||||
|
"type": "number",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"workerFk": {
|
||||||
|
"type": "number"
|
||||||
|
}
|
||||||
|
},
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "collection"
|
"table": "collection"
|
||||||
|
|
|
@ -27,6 +27,18 @@
|
||||||
},
|
},
|
||||||
"subscriberCode": {
|
"subscriberCode": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
},
|
||||||
|
"defaultHeight": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"defaultLength": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"defaultWidth": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"defaultWeight": {
|
||||||
|
"type": "number"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -762,7 +762,12 @@ INSERT INTO `vn`.`ticket`(`id`, `priority`, `agencyModeFk`,`warehouseFk`,`routeF
|
||||||
(30, 1, 8, 1, 1, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), 1103, 'Phone Box', 123, NULL, 0, 1, 5, 1, util.VN_CURDATE(), NULL, NULL),
|
(30, 1, 8, 1, 1, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), 1103, 'Phone Box', 123, NULL, 0, 1, 5, 1, util.VN_CURDATE(), NULL, NULL),
|
||||||
(31, 1, 8, 1, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), DATE_ADD(util.VN_CURDATE(), INTERVAL + 2 DAY), 1103, 'Phone Box', 123, NULL, 0, 1, 5, 1, util.VN_CURDATE(), NULL, NULL),
|
(31, 1, 8, 1, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), DATE_ADD(util.VN_CURDATE(), INTERVAL + 2 DAY), 1103, 'Phone Box', 123, NULL, 0, 1, 5, 1, util.VN_CURDATE(), NULL, NULL),
|
||||||
(32, 1, 8, 1, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), DATE_ADD(util.VN_CURDATE(), INTERVAL + 2 DAY), 1103, 'Phone Box', 123, NULL, 0, 1, 5, 1, util.VN_CURDATE(), NULL, NULL),
|
(32, 1, 8, 1, 1, DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), DATE_ADD(util.VN_CURDATE(), INTERVAL + 2 DAY), 1103, 'Phone Box', 123, NULL, 0, 1, 5, 1, util.VN_CURDATE(), NULL, NULL),
|
||||||
(33, 1, 7, 1, 6, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), 1102, 'NY roofs', 122, NULL, 0, 3, 5, 1, util.VN_CURDATE(), NULL, NULL);
|
(33, 1, 7, 1, 6, util.VN_CURDATE(), DATE_ADD(util.VN_CURDATE(), INTERVAL + 1 DAY), 1102, 'NY roofs', 122, NULL, 0, 3, 5, 1, util.VN_CURDATE(), NULL, NULL),
|
||||||
|
(34, 1, 1, 1, 3, util.VN_CURDATE(), util.VN_CURDATE(), 1103, 'BEJAR', 123, NULL, 0, 1, 16, 0, util.VN_CURDATE(), NULL, NULL),
|
||||||
|
(35, 1, 1, 1, 3, util.VN_CURDATE(), util.VN_CURDATE(), 1102, 'Somewhere in Philippines', 123, NULL, 0, 1, 16, 0, util.VN_CURDATE(), NULL, NULL),
|
||||||
|
(36, 1, 1, 1, 3, util.VN_CURDATE(), util.VN_CURDATE(), 1102, 'Ant-Man Adventure', 123, NULL, 0, 1, 16, 0, util.VN_CURDATE(), NULL, NULL),
|
||||||
|
(37, 1, 1, 1, 3, util.VN_CURDATE(), util.VN_CURDATE(), 1110, 'Deadpool swords', 123, NULL, 0, 1, 16, 0, util.VN_CURDATE(), NULL, NULL);
|
||||||
|
|
||||||
INSERT INTO `vn`.`ticketObservation`(`id`, `ticketFk`, `observationTypeFk`, `description`)
|
INSERT INTO `vn`.`ticketObservation`(`id`, `ticketFk`, `observationTypeFk`, `description`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 11, 1, 'ready'),
|
(1, 11, 1, 'ready'),
|
||||||
|
@ -808,7 +813,10 @@ INSERT INTO `vn`.`ticketTracking`(`ticketFk`, `stateFk`, `userFk`, `created`)
|
||||||
(21, 1, 19, DATE_ADD(util.VN_NOW(), INTERVAL +1 MONTH)),
|
(21, 1, 19, DATE_ADD(util.VN_NOW(), INTERVAL +1 MONTH)),
|
||||||
(22, 1, 19, DATE_ADD(util.VN_NOW(), INTERVAL +1 MONTH)),
|
(22, 1, 19, DATE_ADD(util.VN_NOW(), INTERVAL +1 MONTH)),
|
||||||
(23, 16, 21, util.VN_NOW()),
|
(23, 16, 21, util.VN_NOW()),
|
||||||
(24, 16, 21, util.VN_NOW());
|
(24, 16, 21, util.VN_NOW()),
|
||||||
|
(34, 14, 49, util.VN_NOW()),
|
||||||
|
(35, 14, 18, util.VN_NOW()),
|
||||||
|
(36, 14, 18, util.VN_NOW());
|
||||||
|
|
||||||
INSERT INTO `vn`.`deliveryPoint` (`id`, `name`, `ubication`)
|
INSERT INTO `vn`.`deliveryPoint` (`id`, `name`, `ubication`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -1068,7 +1076,10 @@ INSERT INTO `vn`.`sale`(`id`, `itemFk`, `ticketFk`, `concept`, `quantity`, `pric
|
||||||
(37, 4, 31, 'Melee weapon heavy shield 100cm', 20, 1.72, 0, 0, 0, util.VN_CURDATE()),
|
(37, 4, 31, 'Melee weapon heavy shield 100cm', 20, 1.72, 0, 0, 0, util.VN_CURDATE()),
|
||||||
(36, 4, 30, 'Melee weapon heavy shield 100cm', 20, 1.72, 0, 0, 0, util.VN_CURDATE()),
|
(36, 4, 30, 'Melee weapon heavy shield 100cm', 20, 1.72, 0, 0, 0, util.VN_CURDATE()),
|
||||||
(38, 2, 32, 'Melee weapon combat fist 15cm', 30, 7.07, 0, 0, 0, DATE_ADD(util.VN_CURDATE(), INTERVAL +1 MONTH)),
|
(38, 2, 32, 'Melee weapon combat fist 15cm', 30, 7.07, 0, 0, 0, DATE_ADD(util.VN_CURDATE(), INTERVAL +1 MONTH)),
|
||||||
(39, 1, 32, 'Ranged weapon longbow 200cm', 2, 103.49, 0, 0, 0, util.VN_CURDATE());
|
(39, 1, 32, 'Ranged weapon longbow 200cm', 2, 103.49, 0, 0, 0, util.VN_CURDATE()),
|
||||||
|
(40, 2, 34, 'Melee weapon combat fist 15cm', 10.00, 3.91, 0, 0, 0, util.VN_CURDATE()),
|
||||||
|
(41, 2, 35, 'Melee weapon combat fist 15cm', 8.00, 3.01, 0, 0, 0, util.VN_CURDATE()),
|
||||||
|
(42, 2, 36, 'Melee weapon combat fist 15cm', 6.00, 2.50, 0, 0, 0, util.VN_CURDATE());
|
||||||
|
|
||||||
INSERT INTO `vn`.`saleComponent`(`saleFk`, `componentFk`, `value`)
|
INSERT INTO `vn`.`saleComponent`(`saleFk`, `componentFk`, `value`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -1247,14 +1258,20 @@ INSERT INTO `vn`.`operator` (`workerFk`, `numberOfWagons`, `trainFk`, `itemPacki
|
||||||
INSERT INTO `vn`.`collection`(`id`, `workerFk`, `stateFk`, `created`, `trainFk`)
|
INSERT INTO `vn`.`collection`(`id`, `workerFk`, `stateFk`, `created`, `trainFk`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 1106, 5, DATE_ADD(util.VN_CURDATE(),INTERVAL +1 DAY), 1),
|
(1, 1106, 5, DATE_ADD(util.VN_CURDATE(),INTERVAL +1 DAY), 1),
|
||||||
(2, 1106, 14, util.VN_CURDATE(), 1);
|
(2, 1106, 14, util.VN_CURDATE(), 1),
|
||||||
|
(4, 49, 5, util.VN_CURDATE(), 1),
|
||||||
|
(5, 18, 5, util.VN_CURDATE(), 1),
|
||||||
|
(6, 18, 5, util.VN_CURDATE(), 1);
|
||||||
|
|
||||||
INSERT INTO `vn`.`ticketCollection`(`ticketFk`, `collectionFk`, `level`)
|
INSERT INTO `vn`.`ticketCollection`(`ticketFk`, `collectionFk`, `level`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 1, 1),
|
(1, 1, 1),
|
||||||
(2, 1, NULL),
|
(2, 1, NULL),
|
||||||
(3, 2, NULL),
|
(3, 2, NULL),
|
||||||
(23, 1, NULL);
|
(23, 1, NULL),
|
||||||
|
(34, 4, 1),
|
||||||
|
(35, 5, 1),
|
||||||
|
(8, 6, 1);
|
||||||
|
|
||||||
INSERT INTO `vn`.`genus`(`id`, `name`)
|
INSERT INTO `vn`.`genus`(`id`, `name`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -3714,7 +3731,8 @@ INSERT IGNORE INTO vn.saleGroup
|
||||||
SET id = 4,
|
SET id = 4,
|
||||||
userFk = 1,
|
userFk = 1,
|
||||||
parkingFk = 9,
|
parkingFk = 9,
|
||||||
sectorFk = 9992;
|
sectorFk = 9992,
|
||||||
|
ticketFk = 36;
|
||||||
|
|
||||||
INSERT IGNORE INTO vn.sectorCollectionSaleGroup
|
INSERT IGNORE INTO vn.sectorCollectionSaleGroup
|
||||||
SET id = 9999,
|
SET id = 9999,
|
||||||
|
@ -3816,3 +3834,27 @@ INSERT INTO `vn`.`ledgerCompany` SET
|
||||||
|
|
||||||
INSERT INTO `vn`.`ledgerConfig` SET
|
INSERT INTO `vn`.`ledgerConfig` SET
|
||||||
maxTolerance = 0.01;
|
maxTolerance = 0.01;
|
||||||
|
|
||||||
|
INSERT INTO vn.sectorCollection
|
||||||
|
SET id = 2,
|
||||||
|
userFk = 18,
|
||||||
|
sectorFk = 1;
|
||||||
|
|
||||||
|
INSERT INTO vn.sectorCollectionSaleGroup
|
||||||
|
SET id = 8,
|
||||||
|
sectorCollectionFk = 2,
|
||||||
|
saleGroupFk = 4;
|
||||||
|
|
||||||
|
INSERT INTO vn.saleGroup (userFk, parkingFk, sectorFk, ticketFk)
|
||||||
|
VALUES
|
||||||
|
(1, 1, 1, 37);
|
||||||
|
|
||||||
|
INSERT INTO vn.sectorCollection
|
||||||
|
SET id = 3,
|
||||||
|
userFk = 18,
|
||||||
|
sectorFk = 1;
|
||||||
|
|
||||||
|
INSERT INTO vn.sectorCollectionSaleGroup
|
||||||
|
SET id = 9,
|
||||||
|
sectorCollectionFk = 3,
|
||||||
|
saleGroupFk = 6;
|
|
@ -48,7 +48,7 @@ BEGIN
|
||||||
-- Marcamos para no repetir
|
-- Marcamos para no repetir
|
||||||
UPDATE vn.claimEnd ce
|
UPDATE vn.claimEnd ce
|
||||||
JOIN vn.claim c ON c.id = ce.claimFk
|
JOIN vn.claim c ON c.id = ce.claimFk
|
||||||
SET c.isChargedToMana = TRUE
|
SET ce.isGreuge = TRUE
|
||||||
WHERE ce.claimDestinationFk NOT IN (1,5)
|
WHERE ce.claimDestinationFk NOT IN (1,5)
|
||||||
AND NOT ce.isGreuge
|
AND NOT ce.isGreuge
|
||||||
AND c.claimStateFk = 3;
|
AND c.claimStateFk = 3;
|
||||||
|
|
|
@ -44,8 +44,8 @@ proc:BEGIN
|
||||||
addressFk
|
addressFk
|
||||||
)
|
)
|
||||||
SELECT CONCAT(i.name, ' by ',a.nickname),
|
SELECT CONCAT(i.name, ' by ',a.nickname),
|
||||||
i.minPrice + apc.deliveryCost,
|
r.price + apc.deliveryCost,
|
||||||
i.id,
|
r.itemFk,
|
||||||
vLanded,
|
vLanded,
|
||||||
vPostalCode,
|
vPostalCode,
|
||||||
it.name,
|
it.name,
|
||||||
|
@ -53,13 +53,15 @@ proc:BEGIN
|
||||||
i.description,
|
i.description,
|
||||||
apc.addressFk
|
apc.addressFk
|
||||||
FROM vn.item i
|
FROM vn.item i
|
||||||
|
JOIN (SELECT itemFk, SUM(quantity * cost) price
|
||||||
|
FROM recipe
|
||||||
|
GROUP BY itemFk) r ON r.itemFk = i.id
|
||||||
JOIN vn.itemType it ON it.id = i.typeFk
|
JOIN vn.itemType it ON it.id = i.typeFk
|
||||||
JOIN addressPostCode apc
|
JOIN addressPostCode apc
|
||||||
ON apc.dayOfWeek = dayOfWeek(vLanded)
|
ON apc.dayOfWeek = dayOfWeek(vLanded)
|
||||||
AND NOW() < vLanded - INTERVAL apc.hoursInAdvance HOUR
|
AND NOW() < vLanded - INTERVAL apc.hoursInAdvance HOUR
|
||||||
AND apc.postCode = vPostalCode
|
AND apc.postCode = vPostalCode
|
||||||
JOIN vn.address a ON a.id = apc.addressFk
|
JOIN vn.address a ON a.id = apc.addressFk;
|
||||||
WHERE it.code IN ('FNR','FNP');
|
|
||||||
|
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM catalogue
|
FROM catalogue
|
||||||
|
|
|
@ -18,10 +18,29 @@ proc:BEGIN
|
||||||
DECLARE vBodyEmail TEXT;
|
DECLARE vBodyEmail TEXT;
|
||||||
DECLARE vZoneFk INT;
|
DECLARE vZoneFk INT;
|
||||||
|
|
||||||
|
DECLARE exit handler FOR SQLEXCEPTION
|
||||||
|
BEGIN
|
||||||
|
ROLLBACK;
|
||||||
|
|
||||||
|
GET DIAGNOSTICS CONDITION 2 @errno = MYSQL_ERRNO, @text = MESSAGE_TEXT;
|
||||||
|
|
||||||
|
SELECT CONCAT('ERROR ', IFNULL(@errno,0), ': ', ifnull(@text,'texto')) AS `SQLEXCEPTION`;
|
||||||
|
|
||||||
|
CALL vn.mail_insert(
|
||||||
|
'floranet@verdnatura.es,pako@verdnatura.es',
|
||||||
|
'noreply@verdnatura.es',
|
||||||
|
'Floranet.order_confirm failure',
|
||||||
|
CONCAT('CatalogueFk: ', vCatalogueFk, '\n','ERROR ', IFNULL(@errno, 0), ': ', ifnull(@text, 'texto'))
|
||||||
|
);
|
||||||
|
END;
|
||||||
|
|
||||||
IF (SELECT isPaid FROM `order` WHERE catalogueFk = vCatalogueFk) THEN
|
IF (SELECT isPaid FROM `order` WHERE catalogueFk = vCatalogueFk) THEN
|
||||||
CALL util.throw('Esta orden ya está confirmada');
|
SELECT CONCAT('CatalogueFk: ', vCatalogueFk, ' Esta orden ya está confirmada') AS `ERROR`;
|
||||||
|
LEAVE proc;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
|
START TRANSACTION;
|
||||||
|
|
||||||
UPDATE `order`
|
UPDATE `order`
|
||||||
SET isPaid = TRUE,
|
SET isPaid = TRUE,
|
||||||
payed = NOW()
|
payed = NOW()
|
||||||
|
@ -90,6 +109,23 @@ proc:BEGIN
|
||||||
AND apc.dayOfWeek = dayOfWeek(c.dated)
|
AND apc.dayOfWeek = dayOfWeek(c.dated)
|
||||||
WHERE c.id = vCatalogueFk;
|
WHERE c.id = vCatalogueFk;
|
||||||
|
|
||||||
|
INSERT INTO vn.sale(
|
||||||
|
ticketFk,
|
||||||
|
itemFk,
|
||||||
|
concept,
|
||||||
|
price,
|
||||||
|
quantity)
|
||||||
|
SELECT
|
||||||
|
vNewTicketFk,
|
||||||
|
r.elementFk,
|
||||||
|
i.longName,
|
||||||
|
r.cost,
|
||||||
|
r.quantity
|
||||||
|
FROM catalogue c
|
||||||
|
JOIN recipe r ON r.itemFk = c.itemFk
|
||||||
|
JOIN vn.item i ON i.id = r.elementFk
|
||||||
|
WHERE c.id = vCatalogueFk;
|
||||||
|
|
||||||
SELECT cl.email,
|
SELECT cl.email,
|
||||||
cf.email,
|
cf.email,
|
||||||
CONCAT('Nuevo pedido FLORANET para entrega el ',c.dated),
|
CONCAT('Nuevo pedido FLORANET para entrega el ',c.dated),
|
||||||
|
@ -124,5 +160,8 @@ proc:BEGIN
|
||||||
SELECT isPaid, vNewTicketFk
|
SELECT isPaid, vNewTicketFk
|
||||||
FROM `order`
|
FROM `order`
|
||||||
WHERE catalogueFk = vCatalogueFk;
|
WHERE catalogueFk = vCatalogueFk;
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
END$$
|
END$$
|
||||||
DELIMITER ;
|
DELIMITER ;
|
|
@ -11,10 +11,7 @@ BEGIN
|
||||||
*/
|
*/
|
||||||
DECLARE vClient INT DEFAULT NULL;
|
DECLARE vClient INT DEFAULT NULL;
|
||||||
|
|
||||||
-- SET vPhone = vPhone COLLATE 'utf8_unicode_ci';
|
CREATE OR REPLACE TEMPORARY TABLE tClient
|
||||||
|
|
||||||
DROP TEMPORARY TABLE IF EXISTS tClient;
|
|
||||||
CREATE TEMPORARY TABLE tClient
|
|
||||||
ENGINE = MEMORY
|
ENGINE = MEMORY
|
||||||
SELECT id clientFk
|
SELECT id clientFk
|
||||||
FROM `client`
|
FROM `client`
|
||||||
|
@ -27,13 +24,14 @@ BEGIN
|
||||||
OR mobile = vPhone
|
OR mobile = vPhone
|
||||||
UNION
|
UNION
|
||||||
SELECT clientFk
|
SELECT clientFk
|
||||||
FROM vn.clientContact
|
FROM clientContact
|
||||||
WHERE phone = vPhone;
|
WHERE phone = vPhone;
|
||||||
|
|
||||||
SELECT t.clientFk INTO vClient
|
SELECT t.clientFk INTO vClient
|
||||||
FROM tClient t
|
FROM tClient t
|
||||||
JOIN `client` c ON c.id = t.clientFk
|
JOIN `client` c ON c.id = t.clientFk
|
||||||
WHERE c.isActive
|
WHERE c.isActive
|
||||||
|
AND c.salesPersonFk
|
||||||
LIMIT 1;
|
LIMIT 1;
|
||||||
|
|
||||||
DROP TEMPORARY TABLE tClient;
|
DROP TEMPORARY TABLE tClient;
|
||||||
|
|
|
@ -13,28 +13,12 @@ BEGIN
|
||||||
* @param vCollectionFk Id de colección
|
* @param vCollectionFk Id de colección
|
||||||
*/
|
*/
|
||||||
DECLARE vHasTooMuchCollections BOOL;
|
DECLARE vHasTooMuchCollections BOOL;
|
||||||
DECLARE vItemPackingTypeFk VARCHAR(1);
|
|
||||||
DECLARE vWarehouseFk INT;
|
|
||||||
DECLARE vLockName VARCHAR(215);
|
|
||||||
DECLARE vLockTime INT DEFAULT 30;
|
|
||||||
|
|
||||||
DECLARE EXIT HANDLER FOR SQLEXCEPTION
|
|
||||||
BEGIN
|
|
||||||
IF vLockName IS NOT NULL THEN
|
|
||||||
DO RELEASE_LOCK(vLockName);
|
|
||||||
CALL util.debugAdd('releaseLock', vLockName); -- Tmp
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
RESIGNAL;
|
|
||||||
END;
|
|
||||||
|
|
||||||
-- Si hay colecciones sin terminar, sale del proceso
|
-- Si hay colecciones sin terminar, sale del proceso
|
||||||
CALL collection_get(vUserFk);
|
CALL collection_get(vUserFk);
|
||||||
|
|
||||||
SELECT (pc.maxNotReadyCollections - COUNT(*)) <= 0,
|
SELECT (pc.maxNotReadyCollections - COUNT(*)) <= 0
|
||||||
collection_assign_lockname
|
INTO vHasTooMuchCollections
|
||||||
INTO vHasTooMuchCollections,
|
|
||||||
vLockName
|
|
||||||
FROM productionConfig pc
|
FROM productionConfig pc
|
||||||
LEFT JOIN tCollection ON TRUE;
|
LEFT JOIN tCollection ON TRUE;
|
||||||
|
|
||||||
|
@ -44,21 +28,6 @@ BEGIN
|
||||||
CALL util.throw('Hay colecciones pendientes');
|
CALL util.throw('Hay colecciones pendientes');
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
SELECT warehouseFk, itemPackingTypeFk
|
|
||||||
INTO vWarehouseFk, vItemPackingTypeFk
|
|
||||||
FROM operator
|
|
||||||
WHERE workerFk = vUserFk;
|
|
||||||
|
|
||||||
SET vLockName = CONCAT_WS('/',
|
|
||||||
vLockName,
|
|
||||||
vWarehouseFk,
|
|
||||||
vItemPackingTypeFk
|
|
||||||
);
|
|
||||||
|
|
||||||
IF NOT GET_LOCK(vLockName, vLockTime) THEN
|
|
||||||
CALL util.throw(CONCAT('Cannot get lock: ', vLockName));
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
-- Se eliminan las colecciones sin asignar que estan obsoletas
|
-- Se eliminan las colecciones sin asignar que estan obsoletas
|
||||||
INSERT INTO ticketTracking(stateFk, ticketFk)
|
INSERT INTO ticketTracking(stateFk, ticketFk)
|
||||||
SELECT s.id, tc.ticketFk
|
SELECT s.id, tc.ticketFk
|
||||||
|
@ -80,8 +49,7 @@ BEGIN
|
||||||
VALUES(vUserFk);
|
VALUES(vUserFk);
|
||||||
|
|
||||||
-- Comprueba si hay colecciones disponibles que se ajustan a su configuracion
|
-- Comprueba si hay colecciones disponibles que se ajustan a su configuracion
|
||||||
SELECT MIN(c.id)
|
SELECT MIN(c.id) INTO vCollectionFk
|
||||||
INTO vCollectionFk
|
|
||||||
FROM `collection` c
|
FROM `collection` c
|
||||||
JOIN operator o
|
JOIN operator o
|
||||||
ON (o.itemPackingTypeFk = c.itemPackingTypeFk OR c.itemPackingTypeFk IS NULL)
|
ON (o.itemPackingTypeFk = c.itemPackingTypeFk OR c.itemPackingTypeFk IS NULL)
|
||||||
|
@ -107,7 +75,5 @@ BEGIN
|
||||||
UPDATE `collection`
|
UPDATE `collection`
|
||||||
SET workerFk = vUserFk
|
SET workerFk = vUserFk
|
||||||
WHERE id = vCollectionFk;
|
WHERE id = vCollectionFk;
|
||||||
|
|
||||||
DO RELEASE_LOCK(vLockName);
|
|
||||||
END$$
|
END$$
|
||||||
DELIMITER ;
|
DELIMITER ;
|
||||||
|
|
|
@ -6,12 +6,12 @@ BEGIN
|
||||||
*
|
*
|
||||||
* @param vDuaFk Id del dua a recalcular
|
* @param vDuaFk Id del dua a recalcular
|
||||||
*/
|
*/
|
||||||
DECLARE done BOOL DEFAULT FALSE;
|
DECLARE vDone BOOL DEFAULT FALSE;
|
||||||
DECLARE vInvoiceFk INT;
|
DECLARE vInvoiceFk INT;
|
||||||
DECLARE vASIEN BIGINT DEFAULT 0;
|
DECLARE vBookEntry INT;
|
||||||
DECLARE vCounter INT DEFAULT 0;
|
DECLARE vFiscalYear INT;
|
||||||
|
|
||||||
DECLARE rs CURSOR FOR
|
DECLARE vInvoicesIn CURSOR FOR
|
||||||
SELECT DISTINCT e.invoiceInFk
|
SELECT DISTINCT e.invoiceInFk
|
||||||
FROM entry e
|
FROM entry e
|
||||||
JOIN duaEntry de ON de.entryFk = e.id
|
JOIN duaEntry de ON de.entryFk = e.id
|
||||||
|
@ -20,9 +20,7 @@ BEGIN
|
||||||
AND de.customsValue
|
AND de.customsValue
|
||||||
AND ii.isBooked = FALSE;
|
AND ii.isBooked = FALSE;
|
||||||
|
|
||||||
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
|
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
|
||||||
|
|
||||||
OPEN rs;
|
|
||||||
|
|
||||||
UPDATE invoiceIn ii
|
UPDATE invoiceIn ii
|
||||||
JOIN entry e ON e.invoiceInFk = ii.id
|
JOIN entry e ON e.invoiceInFk = ii.id
|
||||||
|
@ -36,38 +34,36 @@ BEGIN
|
||||||
e.isConfirmed = TRUE
|
e.isConfirmed = TRUE
|
||||||
WHERE d.id = vDuaFk;
|
WHERE d.id = vDuaFk;
|
||||||
|
|
||||||
SELECT IFNULL(ASIEN,0) INTO vASIEN
|
SELECT ASIEN INTO vBookEntry FROM dua WHERE id = vDuaFk;
|
||||||
FROM dua
|
|
||||||
WHERE id = vDuaFk;
|
|
||||||
|
|
||||||
FETCH rs INTO vInvoiceFk;
|
|
||||||
|
|
||||||
WHILE NOT done DO
|
|
||||||
|
|
||||||
CALL invoiceIn_booking(vInvoiceFk);
|
|
||||||
|
|
||||||
IF vCounter > 0 OR vASIEN > 0 THEN
|
|
||||||
|
|
||||||
UPDATE XDiario x
|
|
||||||
JOIN ledgerConfig lc ON lc.lastBookEntry = x.ASIEN
|
|
||||||
SET x.ASIEN = vASIEN;
|
|
||||||
|
|
||||||
ELSE
|
|
||||||
|
|
||||||
SELECT lastBookEntry INTO vASIEN FROM ledgerConfig;
|
|
||||||
|
|
||||||
|
IF vBookEntry IS NULL THEN
|
||||||
|
SELECT YEAR(IFNULL(ii.bookEntried, d.bookEntried)) INTO vFiscalYear
|
||||||
|
FROM invoiceIn ii
|
||||||
|
JOIN entry e ON e.invoiceInFk = ii.id
|
||||||
|
JOIN duaEntry de ON de.entryFk = e.id
|
||||||
|
JOIN dua d ON d.id = de.duaFk
|
||||||
|
WHERE d.id = vDuaFk
|
||||||
|
LIMIT 1;
|
||||||
|
CALL ledger_next(vFiscalYear, FALSE, vBookEntry);
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
SET vCounter = vCounter + 1;
|
OPEN vInvoicesIn;
|
||||||
|
|
||||||
FETCH rs INTO vInvoiceFk;
|
l: LOOP
|
||||||
|
SET vDone = FALSE;
|
||||||
|
FETCH vInvoicesIn INTO vInvoiceFk;
|
||||||
|
|
||||||
END WHILE;
|
IF vDone THEN
|
||||||
|
LEAVE l;
|
||||||
|
END IF;
|
||||||
|
|
||||||
CLOSE rs;
|
CALL invoiceIn_booking(vInvoiceFk, vBookEntry);
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
CLOSE vInvoicesIn;
|
||||||
|
|
||||||
UPDATE dua
|
UPDATE dua
|
||||||
SET ASIEN = vASIEN
|
SET ASIEN = vBookEntry
|
||||||
WHERE id = vDuaFk;
|
WHERE id = vDuaFk;
|
||||||
|
|
||||||
UPDATE invoiceIn ii
|
UPDATE invoiceIn ii
|
||||||
|
|
|
@ -12,7 +12,7 @@ BEGIN
|
||||||
WHERE id = vDuaFk;
|
WHERE id = vDuaFk;
|
||||||
|
|
||||||
IF vBookNumber IS NULL OR NOT vBookNumber THEN
|
IF vBookNumber IS NULL OR NOT vBookNumber THEN
|
||||||
CALL ledger_next(YEAR(vBookDated), vBookNumber);
|
CALL ledger_next(YEAR(vBookDated), FALSE, vBookNumber);
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- Apunte de la aduana
|
-- Apunte de la aduana
|
||||||
|
|
|
@ -1,7 +1,17 @@
|
||||||
DELIMITER $$
|
DELIMITER $$
|
||||||
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`invoiceIn_booking`(vSelf INT)
|
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`invoiceIn_booking`(
|
||||||
|
vSelf INT,
|
||||||
|
vBookNumber INT
|
||||||
|
)
|
||||||
BEGIN
|
BEGIN
|
||||||
DECLARE vBookNumber INT;
|
/**
|
||||||
|
* Genera la contabilidad para una factura y la marca como contabilizada
|
||||||
|
* Cuadra el asiento generado en si encuentra problemas derivados
|
||||||
|
* de los calculos con decimales
|
||||||
|
*
|
||||||
|
* @param vSelf Id invoiceIn
|
||||||
|
* @param vBookEntry Id de asiento, si es NULL se genera uno nuevo
|
||||||
|
*/
|
||||||
DECLARE vFiscalYear INT;
|
DECLARE vFiscalYear INT;
|
||||||
|
|
||||||
CREATE OR REPLACE TEMPORARY TABLE tInvoiceIn
|
CREATE OR REPLACE TEMPORARY TABLE tInvoiceIn
|
||||||
|
@ -58,7 +68,10 @@ BEGIN
|
||||||
WHERE ii.id = vSelf;
|
WHERE ii.id = vSelf;
|
||||||
|
|
||||||
SELECT YEAR(bookEntried) INTO vFiscalYear FROM tInvoiceIn LIMIT 1;
|
SELECT YEAR(bookEntried) INTO vFiscalYear FROM tInvoiceIn LIMIT 1;
|
||||||
CALL ledger_next(vFiscalYear, vBookNumber);
|
|
||||||
|
IF vBookNumber IS NULL THEN
|
||||||
|
CALL ledger_next(vFiscalYear, FALSE, vBookNumber);
|
||||||
|
END IF;
|
||||||
|
|
||||||
-- Apunte del proveedor
|
-- Apunte del proveedor
|
||||||
INSERT INTO XDiario(
|
INSERT INTO XDiario(
|
||||||
|
|
|
@ -61,7 +61,7 @@ BEGIN
|
||||||
WHERE io.id = vInvoice;
|
WHERE io.id = vInvoice;
|
||||||
|
|
||||||
SELECT YEAR(FECHA) INTO vFiscalYear FROM rs LIMIT 1;
|
SELECT YEAR(FECHA) INTO vFiscalYear FROM rs LIMIT 1;
|
||||||
CALL ledger_next(vFiscalYear, vBookNumber);
|
CALL ledger_next(vFiscalYear, FALSE, vBookNumber);
|
||||||
-- Linea del cliente
|
-- Linea del cliente
|
||||||
INSERT INTO XDiario(
|
INSERT INTO XDiario(
|
||||||
ASIEN,
|
ASIEN,
|
||||||
|
|
|
@ -28,7 +28,7 @@ BEGIN
|
||||||
DECLARE vIsOriginalAClient BOOL;
|
DECLARE vIsOriginalAClient BOOL;
|
||||||
DECLARE vPayMethodCompensation INT;
|
DECLARE vPayMethodCompensation INT;
|
||||||
|
|
||||||
CALL ledger_next(YEAR(vDated), vNewBookEntry);
|
CALL ledger_next(YEAR(vDated), FALSE, vNewBookEntry);
|
||||||
|
|
||||||
SELECT COUNT(id) INTO vIsOriginalAClient
|
SELECT COUNT(id) INTO vIsOriginalAClient
|
||||||
FROM client
|
FROM client
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
DELIMITER $$
|
DELIMITER $$
|
||||||
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ledger_next`(
|
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ledger_next`(
|
||||||
IN vFiscalYear INT,
|
IN vFiscalYear INT,
|
||||||
|
IN vIsManageTransaction BOOLEAN,
|
||||||
OUT vLastBookEntry INT
|
OUT vLastBookEntry INT
|
||||||
)
|
)
|
||||||
BEGIN
|
BEGIN
|
||||||
|
@ -22,6 +23,7 @@ BEGIN
|
||||||
CALL util.throw('Fiscal year is required');
|
CALL util.throw('Fiscal year is required');
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
|
IF NOT vIsManageTransaction THEN
|
||||||
SELECT @@in_transaction INTO vHasStartTransaction;
|
SELECT @@in_transaction INTO vHasStartTransaction;
|
||||||
|
|
||||||
IF NOT vHasStartTransaction THEN
|
IF NOT vHasStartTransaction THEN
|
||||||
|
@ -29,6 +31,7 @@ BEGIN
|
||||||
ELSE
|
ELSE
|
||||||
SAVEPOINT sp;
|
SAVEPOINT sp;
|
||||||
END IF;
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
SELECT bookEntry + 1 INTO vLastBookEntry
|
SELECT bookEntry + 1 INTO vLastBookEntry
|
||||||
FROM ledgerCompany
|
FROM ledgerCompany
|
||||||
|
@ -46,10 +49,12 @@ BEGIN
|
||||||
SET bookEntry = vLastBookEntry
|
SET bookEntry = vLastBookEntry
|
||||||
WHERE fiscalYear = vFiscalYear;
|
WHERE fiscalYear = vFiscalYear;
|
||||||
|
|
||||||
|
IF NOT vIsManageTransaction THEN
|
||||||
IF vHasStartTransaction THEN
|
IF vHasStartTransaction THEN
|
||||||
RELEASE SAVEPOINT sp;
|
RELEASE SAVEPOINT sp;
|
||||||
ELSE
|
ELSE
|
||||||
COMMIT;
|
COMMIT;
|
||||||
END IF;
|
END IF;
|
||||||
|
END IF;
|
||||||
END$$
|
END$$
|
||||||
DELIMITER ;
|
DELIMITER ;
|
|
@ -39,7 +39,7 @@ CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`xdiario_new`(
|
||||||
*/
|
*/
|
||||||
BEGIN
|
BEGIN
|
||||||
IF vBookNumber IS NULL THEN
|
IF vBookNumber IS NULL THEN
|
||||||
CALL ledger_next(YEAR(vDated), vBookNumber);
|
CALL ledger_next(YEAR(vDated), FALSE, vBookNumber);
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
INSERT INTO XDiario
|
INSERT INTO XDiario
|
||||||
|
|
|
@ -9,7 +9,6 @@ BEGIN
|
||||||
DECLARE vIsCash BOOLEAN;
|
DECLARE vIsCash BOOLEAN;
|
||||||
DECLARE vIsSupplierActive BOOLEAN;
|
DECLARE vIsSupplierActive BOOLEAN;
|
||||||
|
|
||||||
-- PAK 10/02/15 No se asientan los pagos directamente, salvo en el caso de las cajas de CASH
|
|
||||||
SELECT (at2.code = 'cash') INTO vIsCash
|
SELECT (at2.code = 'cash') INTO vIsCash
|
||||||
FROM accounting a
|
FROM accounting a
|
||||||
JOIN accountingType at2 ON at2.id = a.accountingTypeFk
|
JOIN accountingType at2 ON at2.id = a.accountingTypeFk
|
||||||
|
@ -24,7 +23,7 @@ BEGIN
|
||||||
FROM supplier
|
FROM supplier
|
||||||
WHERE id = NEW.supplierFk;
|
WHERE id = NEW.supplierFk;
|
||||||
|
|
||||||
CALL ledger_next(YEAR(NEW.received), NEW.companyFk, vNewBookEntry);
|
CALL ledger_next(YEAR(NEW.received), TRUE, vNewBookEntry);
|
||||||
|
|
||||||
INSERT INTO XDiario (
|
INSERT INTO XDiario (
|
||||||
ASIEN,
|
ASIEN,
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE vn.item ADD COLUMN photoMotivation VARCHAR(255);
|
|
@ -0,0 +1,46 @@
|
||||||
|
use account;
|
||||||
|
|
||||||
|
INSERT INTO role
|
||||||
|
SET name = 'reviewer',
|
||||||
|
description = 'Revisor de producción',
|
||||||
|
hasLogin = TRUE,
|
||||||
|
created = util.VN_CURDATE(),
|
||||||
|
modified = util.VN_CURDATE(),
|
||||||
|
editorFk = NULL;
|
||||||
|
|
||||||
|
INSERT INTO roleInherit(
|
||||||
|
role,
|
||||||
|
inheritsFrom
|
||||||
|
)
|
||||||
|
SELECT r1.id,
|
||||||
|
r2.id
|
||||||
|
FROM role r1
|
||||||
|
JOIN role r2
|
||||||
|
WHERE r1.name = 'reviewer'
|
||||||
|
AND r2.name = 'production'
|
||||||
|
UNION
|
||||||
|
SELECT ri.role,
|
||||||
|
r2.id
|
||||||
|
FROM roleInherit ri
|
||||||
|
JOIN role r1 ON r1.id = ri.role
|
||||||
|
JOIN role r2 ON r2.name = 'reviewer'
|
||||||
|
WHERE r1.name IN ('claimManager', 'productionBoss')
|
||||||
|
GROUP BY ri.role;
|
||||||
|
|
||||||
|
DELETE ri
|
||||||
|
FROM roleInherit ri
|
||||||
|
JOIN role r1 ON ri.role = r1.id
|
||||||
|
JOIN role r2 ON ri.inheritsFrom = r2.id
|
||||||
|
WHERE r1.name = 'replenisher'
|
||||||
|
AND r2.name = 'buyer';
|
||||||
|
|
||||||
|
UPDATE salix.ACL
|
||||||
|
SET principalId = 'reviewer'
|
||||||
|
WHERE property = 'isInPreparing';
|
||||||
|
|
||||||
|
UPDATE user u
|
||||||
|
JOIN vn.workerDepartment wd ON wd.workerFk = u.id
|
||||||
|
JOIN vn.department d ON wd.departmentFk = d.id
|
||||||
|
JOIN role r ON r.name = 'reviewer'
|
||||||
|
SET u.role = r.id
|
||||||
|
WHERE d.name IN ('REVISION', 'PREVIA');
|
|
@ -0,0 +1,24 @@
|
||||||
|
REVOKE UPDATE ON vn. invoiceIn FROM administrative, hrBoss, buyer, logistic;
|
||||||
|
GRANT UPDATE (id,
|
||||||
|
serialNumber,
|
||||||
|
serial,
|
||||||
|
supplierFk,
|
||||||
|
issued,
|
||||||
|
supplierRef,
|
||||||
|
currencyFk,
|
||||||
|
created,
|
||||||
|
companyFk,
|
||||||
|
docFk,
|
||||||
|
booked,
|
||||||
|
operated,
|
||||||
|
siiTypeInvoiceInFk,
|
||||||
|
cplusRectificationTypeFk,
|
||||||
|
cplusSubjectOpFk,
|
||||||
|
cplusTaxBreakFk,
|
||||||
|
siiTrascendencyInvoiceInFk,
|
||||||
|
bookEntried,
|
||||||
|
isVatDeductible,
|
||||||
|
withholdingSageFk,
|
||||||
|
expenseFkDeductible,
|
||||||
|
editorFk
|
||||||
|
) ON vn.invoiceIn TO administrative, hrBoss, buyer, logistic;
|
|
@ -0,0 +1,23 @@
|
||||||
|
UPDATE salix.ACL
|
||||||
|
SET accessType = 'READ'
|
||||||
|
WHERE principalId IN ('administrative','buyer')
|
||||||
|
AND model = 'invoiceIn'
|
||||||
|
AND property = '*';
|
||||||
|
|
||||||
|
INSERT INTO salix.ACL (model, property, accessType, permission, principalType, principalId)
|
||||||
|
VALUES
|
||||||
|
('InvoiceIn', 'updateInvoiceIn', 'WRITE', 'ALLOW', 'ROLE', 'administrative'),
|
||||||
|
('InvoiceIn', 'clone', 'WRITE', 'ALLOW', 'ROLE', 'administrative'),
|
||||||
|
('InvoiceIn', 'corrective', 'WRITE', 'ALLOW', 'ROLE', 'administrative'),
|
||||||
|
('InvoiceIn', 'exchangeRateUpdate', 'WRITE', 'ALLOW', 'ROLE', 'administrative'),
|
||||||
|
('InvoiceIn', 'invoiceInEmail', 'WRITE', 'ALLOW', 'ROLE', 'administrative'),
|
||||||
|
('InvoiceIn', 'toBook', 'WRITE', 'ALLOW', 'ROLE', 'administrative'),
|
||||||
|
('InvoiceIn', 'toUnbook', 'WRITE', 'ALLOW', 'ROLE', 'administrative'),
|
||||||
|
('InvoiceIn', 'deleteById', 'WRITE', 'ALLOW', 'ROLE', 'administrative'),
|
||||||
|
('InvoiceIn', 'updateInvoiceIn', 'WRITE', 'ALLOW', 'ROLE', 'buyer'),
|
||||||
|
('InvoiceIn', 'clone', 'WRITE', 'ALLOW', 'ROLE', 'buyer'),
|
||||||
|
('InvoiceIn', 'corrective', 'WRITE', 'ALLOW', 'ROLE', 'buyer'),
|
||||||
|
('InvoiceIn', 'exchangeRateUpdate', 'WRITE', 'ALLOW', 'ROLE', 'buyer'),
|
||||||
|
('InvoiceIn', 'invoiceInEmail', 'WRITE', 'ALLOW', 'ROLE', 'buyer'),
|
||||||
|
('InvoiceIn', 'toBook', 'WRITE', 'ALLOW', 'ROLE', 'buyer'),
|
||||||
|
('InvoiceIn', 'deleteById', 'WRITE', 'ALLOW', 'ROLE', 'buyer');
|
|
@ -0,0 +1,20 @@
|
||||||
|
-- Place your SQL code here
|
||||||
|
|
||||||
|
|
||||||
|
-- floranet.recipe definition
|
||||||
|
|
||||||
|
CREATE OR REPLACE TABLE floranet.`recipe`
|
||||||
|
(
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`itemFk` int(11) NOT NULL COMMENT 'Bouquet or plant name',
|
||||||
|
`elementFk` int(11) NOT NULL COMMENT 'Item detail for bouquet''s composition',
|
||||||
|
`quantity` int(10) unsigned NOT NULL DEFAULT 1,
|
||||||
|
`cost` decimal(10,2) NOT NULL DEFAULT 1.00,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
KEY `recipe_FK` (`itemFk`),
|
||||||
|
KEY `recipe_FK_1` (`elementFk`),
|
||||||
|
CONSTRAINT `recipe_FK` FOREIGN KEY (`itemFk`) REFERENCES `vn`.`item` (`id`) ON UPDATE CASCADE,
|
||||||
|
CONSTRAINT `recipe_item_FK` FOREIGN KEY (`elementFk`) REFERENCES `vn`.`item` (`id`) ON UPDATE CASCADE
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='Links handmade products with their elements';
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS floranet.`element`;
|
|
@ -0,0 +1,5 @@
|
||||||
|
-- Place your SQL code here
|
||||||
|
ALTER TABLE vn.mrwConfig ADD IF NOT EXISTS defaultHeight INT UNSIGNED NULL COMMENT 'default height in centimeters';
|
||||||
|
ALTER TABLE vn.mrwConfig ADD IF NOT EXISTS defaultLength INT UNSIGNED NULL COMMENT 'default length in centimeters';
|
||||||
|
ALTER TABLE vn.mrwConfig ADD IF NOT EXISTS defaultWidth INT UNSIGNED NULL COMMENT 'default width in centimeters';
|
||||||
|
ALTER TABLE vn.mrwConfig ADD IF NOT EXISTS defaultWeight INT UNSIGNED NULL COMMENT 'default weight in centimeters';
|
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE vn.productionConfig ADD scannablePreviusCodeType enum('qr','barcode')
|
||||||
|
CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci DEFAULT 'barcode' NOT NULL;
|
|
@ -0,0 +1,3 @@
|
||||||
|
-- Place your SQL code here
|
||||||
|
ALTER TABLE vn.mrwConfig ADD IF NOT EXISTS expeditionDeadLine TIME NULL
|
||||||
|
COMMENT 'This field stores the latest time by which expeditions can be generated to be sent today';
|
|
@ -0,0 +1,9 @@
|
||||||
|
-- Place your SQL code here
|
||||||
|
ALTER TABLE vn.mrwConfig ADD IF NOT EXISTS counterWidth INT UNSIGNED NULL
|
||||||
|
COMMENT 'If it does not reach the required value, it will be padded with zeros on the left to meet the specified length.';
|
||||||
|
|
||||||
|
ALTER TABLE vn.mrwConfig ADD IF NOT EXISTS serviceTypeWidth INT UNSIGNED NULL
|
||||||
|
COMMENT 'If it does not reach the required value, it will be padded with zeros on the left to meet the specified length.';
|
||||||
|
|
||||||
|
ALTER TABLE vn.mrwConfig ADD IF NOT EXISTS portugalPostCodeTrim INT UNSIGNED NULL
|
||||||
|
COMMENT 'It will trim the last characters of the postal code';
|
|
@ -0,0 +1,3 @@
|
||||||
|
|
||||||
|
INSERT INTO salix.ACL (model,property,accessType,permission,principalType,principalId)
|
||||||
|
VALUES ('Ticket','refund','WRITE','ALLOW','ROLE','logistic');
|
|
@ -225,7 +225,7 @@ describe('Ticket Edit sale path', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should show error trying to delete a ticket with a refund', async() => {
|
it('should show error trying to delete a ticket with a refund', async() => {
|
||||||
await page.loginAndModule('production', 'ticket');
|
await page.loginAndModule('salesPerson', 'ticket');
|
||||||
await page.accessToSearchResult('8');
|
await page.accessToSearchResult('8');
|
||||||
await page.waitToClick(selectors.ticketDescriptor.moreMenu);
|
await page.waitToClick(selectors.ticketDescriptor.moreMenu);
|
||||||
await page.waitToClick(selectors.ticketDescriptor.moreMenuDeleteTicket);
|
await page.waitToClick(selectors.ticketDescriptor.moreMenuDeleteTicket);
|
||||||
|
|
|
@ -164,6 +164,7 @@ export default class UploadPhoto extends Component {
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
type: 'blob',
|
type: 'blob',
|
||||||
|
size: 'original'
|
||||||
};
|
};
|
||||||
return this.editor.result(options)
|
return this.editor.result(options)
|
||||||
.then(blob => this.newPhoto.blob = blob)
|
.then(blob => this.newPhoto.blob = blob)
|
||||||
|
|
|
@ -61,7 +61,8 @@
|
||||||
"Changed sale discount": "I have changed the following lines discounts from the ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
"Changed sale discount": "I have changed the following lines discounts from the ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
||||||
"Created claim": "I have created the claim [{{claimId}}]({{{claimUrl}}}) for the following lines from the ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
"Created claim": "I have created the claim [{{claimId}}]({{{claimUrl}}}) for the following lines from the ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
||||||
"Changed sale price": "I have changed the price of [{{itemId}} {{concept}}]({{{itemUrl}}}) ({{quantity}}) from {{oldPrice}}€ ➔ *{{newPrice}}€* of the ticket [{{ticketId}}]({{{ticketUrl}}})",
|
"Changed sale price": "I have changed the price of [{{itemId}} {{concept}}]({{{itemUrl}}}) ({{quantity}}) from {{oldPrice}}€ ➔ *{{newPrice}}€* of the ticket [{{ticketId}}]({{{ticketUrl}}})",
|
||||||
"Changed sale quantity": "I have changed the quantity of [{{itemId}} {{concept}}]({{{itemUrl}}}) from {{oldQuantity}} ➔ *{{newQuantity}}* of the ticket [{{ticketId}}]({{{ticketUrl}}})",
|
"Changed sale quantity": "I have changed {{changes}} of the ticket [{{ticketId}}]({{{ticketUrl}}})",
|
||||||
|
"Changes in sales": "the quantity of [{{itemId}} {{concept}}]({{{itemUrl}}}) from {{oldQuantity}} ➔ *{{newQuantity}}*",
|
||||||
"Changed sale reserved state": "I have changed the following lines reserved state from the ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
"Changed sale reserved state": "I have changed the following lines reserved state from the ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
||||||
"Bought units from buy request": "Bought {{quantity}} units of [{{itemId}} {{concept}}]({{{urlItem}}}) for the ticket id [{{ticketId}}]({{{url}}})",
|
"Bought units from buy request": "Bought {{quantity}} units of [{{itemId}} {{concept}}]({{{urlItem}}}) for the ticket id [{{ticketId}}]({{{url}}})",
|
||||||
"MESSAGE_INSURANCE_CHANGE": "I have changed the insurence credit of client [{{clientName}} ({{clientId}})]({{{url}}}) to *{{credit}} €*",
|
"MESSAGE_INSURANCE_CHANGE": "I have changed the insurence credit of client [{{clientName}} ({{clientId}})]({{{url}}}) to *{{credit}} €*",
|
||||||
|
|
|
@ -124,7 +124,8 @@
|
||||||
"Changed sale discount": "He cambiado el descuento de las siguientes lineas al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
"Changed sale discount": "He cambiado el descuento de las siguientes lineas al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
||||||
"Created claim": "He creado la reclamación [{{claimId}}]({{{claimUrl}}}) de las siguientes lineas del ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
"Created claim": "He creado la reclamación [{{claimId}}]({{{claimUrl}}}) de las siguientes lineas del ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
||||||
"Changed sale price": "He cambiado el precio de [{{itemId}} {{concept}}]({{{itemUrl}}}) ({{quantity}}) de {{oldPrice}}€ ➔ *{{newPrice}}€* del ticket [{{ticketId}}]({{{ticketUrl}}})",
|
"Changed sale price": "He cambiado el precio de [{{itemId}} {{concept}}]({{{itemUrl}}}) ({{quantity}}) de {{oldPrice}}€ ➔ *{{newPrice}}€* del ticket [{{ticketId}}]({{{ticketUrl}}})",
|
||||||
"Changed sale quantity": "He cambiado la cantidad de [{{itemId}} {{concept}}]({{{itemUrl}}}) de {{oldQuantity}} ➔ *{{newQuantity}}* del ticket [{{ticketId}}]({{{ticketUrl}}})",
|
"Changed sale quantity": "He cambiado {{changes}} del ticket [{{ticketId}}]({{{ticketUrl}}})",
|
||||||
|
"Changes in sales": "la cantidad de [{{itemId}} {{concept}}]({{{itemUrl}}}) de {{oldQuantity}} ➔ *{{newQuantity}}*",
|
||||||
"State": "Estado",
|
"State": "Estado",
|
||||||
"regular": "normal",
|
"regular": "normal",
|
||||||
"reserved": "reservado",
|
"reserved": "reservado",
|
||||||
|
@ -358,8 +359,8 @@
|
||||||
"Select ticket or client": "Elija un ticket o un client",
|
"Select ticket or client": "Elija un ticket o un client",
|
||||||
"It was not able to create the invoice": "No se pudo crear la factura",
|
"It was not able to create the invoice": "No se pudo crear la factura",
|
||||||
"ticketCommercial": "El ticket {{ ticket }} para el vendedor {{ salesMan }} está en preparación. (mensaje generado automáticamente)",
|
"ticketCommercial": "El ticket {{ ticket }} para el vendedor {{ salesMan }} está en preparación. (mensaje generado automáticamente)",
|
||||||
"This PDA is already assigned to another user": "Este PDA ya está asignado a otro usuario",
|
"This PDA is already assigned to another user": "Esta PDA ya está asignado a otro usuario",
|
||||||
"You can only have one PDA": "Solo puedes tener un PDA",
|
"You can only have one PDA": "Solo puedes tener una PDA",
|
||||||
"Incoterms and Customs agent are required for a non UEE member": "Se requieren Incoterms y agente de aduanas para un no miembro de la UEE",
|
"Incoterms and Customs agent are required for a non UEE member": "Se requieren Incoterms y agente de aduanas para un no miembro de la UEE",
|
||||||
"You can not use the same password": "No puedes usar la misma contraseña"
|
"You can not use the same password": "No puedes usar la misma contraseña"
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,8 +123,9 @@
|
||||||
"Added sale to ticket": "J'ai ajouté la ligne suivante au ticket [{{ticketId}}]({{{ticketUrl}}}): {{{addition}}}",
|
"Added sale to ticket": "J'ai ajouté la ligne suivante au ticket [{{ticketId}}]({{{ticketUrl}}}): {{{addition}}}",
|
||||||
"Changed sale discount": "J'ai changé le rabais des lignes suivantes du ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
"Changed sale discount": "J'ai changé le rabais des lignes suivantes du ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
||||||
"Created claim": "J'ai créé la réclamation [{{claimId}}]({{{claimUrl}}}) des lignes suivantes du ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
"Created claim": "J'ai créé la réclamation [{{claimId}}]({{{claimUrl}}}) des lignes suivantes du ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
||||||
"Changed sale price": "J'ai changé le prix de [{{itemId}} {{concept}}]({{{itemUrl}}}) ({{quantity}}) de {{oldPrice}}€ ➔ *{{newPrice}}€* du ticket [{{ticketId}}]({{{ticketUrl}}})",
|
"Changed sale price": " le prix de [{{itemId}} {{concept}}]({{{itemUrl}}}) ({{quantity}}) de {{oldPrice}}€ ➔ *{{newPrice}}€* du ticket [{{ticketId}}]({{{ticketUrl}}})",,
|
||||||
"Changed sale quantity": "J'ai changé la quantité de {{itemId}} {{concept}} de {{oldQuantity}} ➔ {{newQuantity}} du ticket [{{ticketId}}]({{{ticketUrl}}})",
|
"Changed sale quantity": "J'ai changé {{changes}} du ticket [{{ticketId}}]({{{ticketUrl}}})",
|
||||||
|
"Changes in sales": "la quantité de {{itemId}} {{concept}} de {{oldQuantity}} ➔ {{newQuantity}}",
|
||||||
"State": "État",
|
"State": "État",
|
||||||
"regular": "normal",
|
"regular": "normal",
|
||||||
"reserved": "réservé",
|
"reserved": "réservé",
|
||||||
|
|
|
@ -124,7 +124,8 @@
|
||||||
"Changed sale discount": "Desconto da venda alterado no ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
"Changed sale discount": "Desconto da venda alterado no ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
||||||
"Created claim": "Reclamação criada [{{claimId}}]({{{claimUrl}}}) no ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
"Created claim": "Reclamação criada [{{claimId}}]({{{claimUrl}}}) no ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
|
||||||
"Changed sale price": "Preço da venda alterado para [{{itemId}} {{concept}}]({{{itemUrl}}}) ({{quantity}}) de {{oldPrice}}€ ➔ *{{newPrice}}€* no ticket [{{ticketId}}]({{{ticketUrl}}})",
|
"Changed sale price": "Preço da venda alterado para [{{itemId}} {{concept}}]({{{itemUrl}}}) ({{quantity}}) de {{oldPrice}}€ ➔ *{{newPrice}}€* no ticket [{{ticketId}}]({{{ticketUrl}}})",
|
||||||
"Changed sale quantity": "Quantidade da venda alterada para [{{itemId}} {{concept}}]({{{itemUrl}}}) de {{oldQuantity}} ➔ *{{newQuantity}}* no ticket [{{ticketId}}]({{{ticketUrl}}})",
|
"Changed sale quantity": "Quantidade da venda alterada para {{changes}} no ticket [{{ticketId}}]({{{ticketUrl}}})",
|
||||||
|
"Changes in sales": " [{{itemId}} {{concept}}]({{{itemUrl}}}) de {{oldQuantity}} ➔ *{{newQuantity}}* ",
|
||||||
"State": "Estado",
|
"State": "Estado",
|
||||||
"regular": "normal",
|
"regular": "normal",
|
||||||
"reserved": "reservado",
|
"reserved": "reservado",
|
||||||
|
|
|
@ -85,8 +85,12 @@ exports.translateValues = async(instance, changes, options = {}) => {
|
||||||
exports.getChanges = (original, changes) => {
|
exports.getChanges = (original, changes) => {
|
||||||
const oldChanges = {};
|
const oldChanges = {};
|
||||||
const newChanges = {};
|
const newChanges = {};
|
||||||
|
const dateRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/;
|
||||||
|
|
||||||
for (let property in changes) {
|
for (let property in changes) {
|
||||||
|
if (dateRegex.test(original[property]))
|
||||||
|
original[property] = new Date(Date.parse(original[property]));
|
||||||
|
|
||||||
const firstChar = property.substring(0, 1);
|
const firstChar = property.substring(0, 1);
|
||||||
const isPrivate = firstChar == '$';
|
const isPrivate = firstChar == '$';
|
||||||
if (isPrivate) return;
|
if (isPrivate) return;
|
||||||
|
|
|
@ -6,6 +6,7 @@ describe('claimBeginning', () => {
|
||||||
const claimManagerId = 72;
|
const claimManagerId = 72;
|
||||||
const activeCtx = {
|
const activeCtx = {
|
||||||
accessToken: {userId: claimManagerId},
|
accessToken: {userId: claimManagerId},
|
||||||
|
__: value => value
|
||||||
};
|
};
|
||||||
const ctx = {req: activeCtx};
|
const ctx = {req: activeCtx};
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,8 @@ module.exports = Self => {
|
||||||
const updatedClaim = await claim.updateAttributes(args, myOptions);
|
const updatedClaim = await claim.updateAttributes(args, myOptions);
|
||||||
|
|
||||||
// When pickup has been changed
|
// When pickup has been changed
|
||||||
if (salesPerson && changedPickup && updatedClaim.pickup)
|
if (salesPerson) {
|
||||||
|
if (changedPickup && updatedClaim.pickup)
|
||||||
await notifyPickUp(ctx, salesPerson.id, claim);
|
await notifyPickUp(ctx, salesPerson.id, claim);
|
||||||
|
|
||||||
// When claimState has been changed
|
// When claimState has been changed
|
||||||
|
@ -98,6 +99,7 @@ module.exports = Self => {
|
||||||
if (newState.code == 'canceled')
|
if (newState.code == 'canceled')
|
||||||
await notifyStateChange(ctx, claim.workerFk, claim, newState.description);
|
await notifyStateChange(ctx, claim.workerFk, claim, newState.description);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (tx) await tx.commit();
|
if (tx) await tx.commit();
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,15 @@
|
||||||
},
|
},
|
||||||
"enlazadoSage": {
|
"enlazadoSage": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"enlazado": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"key": {
|
||||||
|
"type": "number",
|
||||||
|
"mysql": {
|
||||||
|
"columnName": "CLAVE"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"relations": {
|
"relations": {
|
||||||
|
|
|
@ -22,5 +22,8 @@
|
||||||
},
|
},
|
||||||
"EntryObservation": {
|
"EntryObservation": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
|
"EntryType": {
|
||||||
|
"dataSource": "vn"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"name": "EntryType",
|
||||||
|
"base": "VnModel",
|
||||||
|
"mixins": {
|
||||||
|
"Loggable": true
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "entryType"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"code": {
|
||||||
|
"type": "string",
|
||||||
|
"id": true,
|
||||||
|
"description": "Identifier"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"isInformal": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -101,6 +101,11 @@
|
||||||
"type": "belongsTo",
|
"type": "belongsTo",
|
||||||
"model": "Account",
|
"model": "Account",
|
||||||
"foreignKey": "observationEditorFk"
|
"foreignKey": "observationEditorFk"
|
||||||
|
},
|
||||||
|
"entryType": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "EntryType",
|
||||||
|
"foreignKey": "typeFk"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -54,6 +54,20 @@ module.exports = Self => {
|
||||||
value: rate
|
value: rate
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
const monday = 1;
|
||||||
|
if (xmlDateWithoutTime.getDay() === monday) {
|
||||||
|
const saturday = new Date(xmlDateWithoutTime);
|
||||||
|
saturday.setDate(xmlDateWithoutTime.getDate() - 2);
|
||||||
|
const sunday = new Date(xmlDateWithoutTime);
|
||||||
|
sunday.setDate(xmlDateWithoutTime.getDate() - 1);
|
||||||
|
|
||||||
|
for (const date of [saturday, sunday]) {
|
||||||
|
await models.ReferenceRate.upsertWithWhere(
|
||||||
|
{currencyFk: currency.id, dated: date},
|
||||||
|
{currencyFk: currency.id, dated: date, value: rate}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
|
describe('invoiceIn toUnbook()', () => {
|
||||||
|
it('should check that invoiceIn is unbooked', async() => {
|
||||||
|
const userId = 1;
|
||||||
|
const ctx = {
|
||||||
|
req: {
|
||||||
|
|
||||||
|
accessToken: {userId: userId},
|
||||||
|
headers: {origin: 'http://localhost:5000'},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const invoiceInId = 1;
|
||||||
|
const tx = await models.InvoiceIn.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
try {
|
||||||
|
await models.InvoiceIn.toBook(ctx, invoiceInId, options);
|
||||||
|
const bookEntry = await models.InvoiceIn.toUnbook(ctx, invoiceInId, options);
|
||||||
|
const invoiceIn = await models.InvoiceIn.findById(invoiceInId, null, options);
|
||||||
|
|
||||||
|
expect(bookEntry.accountingEntries).toEqual(4);
|
||||||
|
expect(bookEntry.isLinked).toBeFalsy();
|
||||||
|
expect(invoiceIn.isBooked).toEqual(false);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
|
@ -32,7 +32,7 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await Self.rawSql(`CALL vn.invoiceIn_booking(?)`, [id], myOptions);
|
await Self.rawSql(`CALL vn.invoiceIn_booking(?, NULL)`, [id], myOptions);
|
||||||
if (tx) await tx.commit();
|
if (tx) await tx.commit();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (tx) await tx.rollback();
|
if (tx) await tx.rollback();
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethodCtx('toUnbook', {
|
||||||
|
description: 'To unbook the invoiceIn',
|
||||||
|
accessType: 'WRITE',
|
||||||
|
accepts: {
|
||||||
|
arg: 'id',
|
||||||
|
type: 'number',
|
||||||
|
required: true,
|
||||||
|
description: 'The invoiceIn id',
|
||||||
|
http: {source: 'path'}
|
||||||
|
},
|
||||||
|
returns: {
|
||||||
|
type: 'object',
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: '/:id/toUnbook',
|
||||||
|
verb: 'POST'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.toUnbook = async(ctx, invoiceInId, options) => {
|
||||||
|
let tx;
|
||||||
|
const models = Self.app.models;
|
||||||
|
const myOptions = {userId: ctx.req.accessToken.userId};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
if (!myOptions.transaction) {
|
||||||
|
tx = await Self.beginTransaction({});
|
||||||
|
myOptions.transaction = tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
let isLinked;
|
||||||
|
let accountingEntries;
|
||||||
|
|
||||||
|
let bookEntry = await models.Xdiario.findOne({
|
||||||
|
fields: ['ASIEN'],
|
||||||
|
where: {
|
||||||
|
and: [
|
||||||
|
{key: invoiceInId},
|
||||||
|
{enlazado: false},
|
||||||
|
{enlazadoSage: false}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}, myOptions);
|
||||||
|
|
||||||
|
let asien = bookEntry?.ASIEN;
|
||||||
|
if (asien) {
|
||||||
|
accountingEntries = await models.Xdiario.count({ASIEN: asien}, myOptions);
|
||||||
|
|
||||||
|
await models.Xdiario.destroyAll({ASIEN: asien}, myOptions);
|
||||||
|
await Self.updateAll({id: invoiceInId}, {isBooked: false}, myOptions);
|
||||||
|
} else {
|
||||||
|
const linkedBookEntry = await models.Xdiario.findOne({
|
||||||
|
fields: ['ASIEN'],
|
||||||
|
where: {
|
||||||
|
key: invoiceInId,
|
||||||
|
and: [{or: [{enlazado: true, enlazadoSage: true}]}]
|
||||||
|
}
|
||||||
|
}, myOptions);
|
||||||
|
|
||||||
|
asien = linkedBookEntry?.ASIEN;
|
||||||
|
isLinked = true;
|
||||||
|
}
|
||||||
|
if (tx) await tx.commit();
|
||||||
|
|
||||||
|
return {
|
||||||
|
isLinked,
|
||||||
|
bookEntry: asien,
|
||||||
|
accountingEntries
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
if (tx) await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,104 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethodCtx('updateInvoiceIn', {
|
||||||
|
description: 'To update the invoiceIn attributes',
|
||||||
|
accessType: 'WRITE',
|
||||||
|
accepts: [{
|
||||||
|
arg: 'id',
|
||||||
|
type: 'number',
|
||||||
|
required: true,
|
||||||
|
description: 'The invoiceIn id',
|
||||||
|
http: {source: 'path'}
|
||||||
|
}, {
|
||||||
|
arg: 'supplierFk',
|
||||||
|
type: 'number',
|
||||||
|
required: true
|
||||||
|
}, {
|
||||||
|
arg: 'supplierRef',
|
||||||
|
type: 'any',
|
||||||
|
}, {
|
||||||
|
arg: 'issued',
|
||||||
|
type: 'any',
|
||||||
|
}, {
|
||||||
|
arg: 'operated',
|
||||||
|
type: 'any',
|
||||||
|
}, {
|
||||||
|
arg: 'deductibleExpenseFk',
|
||||||
|
type: 'any',
|
||||||
|
}, {
|
||||||
|
arg: 'dmsFk',
|
||||||
|
type: 'any',
|
||||||
|
}, {
|
||||||
|
arg: 'bookEntried',
|
||||||
|
type: 'any',
|
||||||
|
}, {
|
||||||
|
arg: 'booked',
|
||||||
|
type: 'any',
|
||||||
|
}, {
|
||||||
|
arg: 'currencyFk',
|
||||||
|
type: 'number',
|
||||||
|
required: true
|
||||||
|
}, {
|
||||||
|
arg: 'companyFk',
|
||||||
|
type: 'any',
|
||||||
|
}, {
|
||||||
|
arg: 'withholdingSageFk',
|
||||||
|
type: 'any',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
returns: {
|
||||||
|
type: 'object',
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: '/:id/updateInvoiceIn',
|
||||||
|
verb: 'PATCH'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.updateInvoiceIn = async(ctx,
|
||||||
|
id,
|
||||||
|
supplierFk,
|
||||||
|
supplierRef,
|
||||||
|
issued,
|
||||||
|
operated,
|
||||||
|
deductibleExpenseFk,
|
||||||
|
dmsFk,
|
||||||
|
bookEntried,
|
||||||
|
booked,
|
||||||
|
currencyFk,
|
||||||
|
companyFk,
|
||||||
|
withholdingSageFk,
|
||||||
|
options
|
||||||
|
) => {
|
||||||
|
let tx;
|
||||||
|
const myOptions = {userId: ctx.req.accessToken.userId};
|
||||||
|
|
||||||
|
if (typeof options == 'object') Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
if (!myOptions.transaction) {
|
||||||
|
tx = await Self.beginTransaction({});
|
||||||
|
myOptions.transaction = tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const invoiceIn = await Self.findById(id, null, myOptions);
|
||||||
|
invoiceIn.updateAttributes({supplierFk,
|
||||||
|
supplierRef,
|
||||||
|
issued,
|
||||||
|
operated,
|
||||||
|
deductibleExpenseFk,
|
||||||
|
dmsFk,
|
||||||
|
bookEntried,
|
||||||
|
booked,
|
||||||
|
currencyFk,
|
||||||
|
companyFk,
|
||||||
|
withholdingSageFk
|
||||||
|
}, myOptions);
|
||||||
|
if (tx) await tx.commit();
|
||||||
|
return invoiceIn;
|
||||||
|
} catch (e) {
|
||||||
|
if (tx) await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
|
@ -11,6 +11,8 @@ module.exports = Self => {
|
||||||
require('../methods/invoice-in/getSerial')(Self);
|
require('../methods/invoice-in/getSerial')(Self);
|
||||||
require('../methods/invoice-in/corrective')(Self);
|
require('../methods/invoice-in/corrective')(Self);
|
||||||
require('../methods/invoice-in/exchangeRateUpdate')(Self);
|
require('../methods/invoice-in/exchangeRateUpdate')(Self);
|
||||||
|
require('../methods/invoice-in/toUnbook')(Self);
|
||||||
|
require('../methods/invoice-in/updateInvoiceIn')(Self);
|
||||||
|
|
||||||
Self.rewriteDbError(function(err) {
|
Self.rewriteDbError(function(err) {
|
||||||
if (err.code === 'ER_ROW_IS_REFERENCED_2' && err.sqlMessage.includes('vehicleInvoiceIn'))
|
if (err.code === 'ER_ROW_IS_REFERENCED_2' && err.sqlMessage.includes('vehicleInvoiceIn'))
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<mg-ajax path="InvoiceIns/{{patch.params.id}}" options="vnPatch"></mg-ajax>
|
<mg-ajax path="InvoiceIns/{{patch.params.id}}/updateInvoiceIn" options="vnPatch"></mg-ajax>
|
||||||
<vn-watcher
|
<vn-watcher
|
||||||
vn-id="watcher"
|
vn-id="watcher"
|
||||||
data="$ctrl.invoiceIn"
|
data="$ctrl.invoiceIn"
|
||||||
|
|
|
@ -4,7 +4,7 @@ module.exports = Self => {
|
||||||
accessType: 'READ',
|
accessType: 'READ',
|
||||||
accepts: [{
|
accepts: [{
|
||||||
arg: 'barcode',
|
arg: 'barcode',
|
||||||
type: 'number',
|
type: 'string',
|
||||||
required: true,
|
required: true,
|
||||||
description: 'barcode'
|
description: 'barcode'
|
||||||
}],
|
}],
|
||||||
|
@ -18,7 +18,7 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.toItem = async(barcode, options) => {
|
Self.toItem = async (barcode, options) => {
|
||||||
const myOptions = {};
|
const myOptions = {};
|
||||||
|
|
||||||
if (typeof options == 'object')
|
if (typeof options == 'object')
|
||||||
|
|
|
@ -64,7 +64,7 @@ describe('item getBalance()', () => {
|
||||||
const secondItemBalance = await models.Item.getBalance(ctx, secondFilter, options);
|
const secondItemBalance = await models.Item.getBalance(ctx, secondFilter, options);
|
||||||
|
|
||||||
expect(firstItemBalance[9].claimFk).toEqual(null);
|
expect(firstItemBalance[9].claimFk).toEqual(null);
|
||||||
expect(secondItemBalance[4].claimFk).toEqual(2);
|
expect(secondItemBalance[7].claimFk).toEqual(2);
|
||||||
|
|
||||||
await tx.rollback();
|
await tx.rollback();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
"id": true,
|
"id": true,
|
||||||
"type": "number",
|
"type": "string",
|
||||||
"description": "Identifier"
|
"description": "Identifier"
|
||||||
},
|
},
|
||||||
"name": {
|
"name": {
|
||||||
|
|
|
@ -155,6 +155,9 @@
|
||||||
"minQuantity": {
|
"minQuantity": {
|
||||||
"type": "number",
|
"type": "number",
|
||||||
"description": "Min quantity"
|
"description": "Min quantity"
|
||||||
|
},
|
||||||
|
"photoMotivation": {
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"relations": {
|
"relations": {
|
||||||
|
|
|
@ -151,7 +151,7 @@ describe('SalesMonitor salesFilter()', () => {
|
||||||
const result = await models.SalesMonitor.salesFilter(ctx, filter, options);
|
const result = await models.SalesMonitor.salesFilter(ctx, filter, options);
|
||||||
const firstRow = result[0];
|
const firstRow = result[0];
|
||||||
|
|
||||||
expect(result.length).toEqual(12);
|
expect(result.length).toEqual(15);
|
||||||
expect(firstRow.alertLevel).not.toEqual(0);
|
expect(firstRow.alertLevel).not.toEqual(0);
|
||||||
|
|
||||||
await tx.rollback();
|
await tx.rollback();
|
||||||
|
|
|
@ -11,6 +11,12 @@
|
||||||
"Sector": {
|
"Sector": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
"SectorCollection": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
|
"SectorCollectionSaleGroup": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
"Train": {
|
"Train": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"name": "SectorCollection",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "sectorCollection"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "number",
|
||||||
|
"id": true
|
||||||
|
},
|
||||||
|
"created": {
|
||||||
|
"type": "date"
|
||||||
|
},
|
||||||
|
"userFk": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"sectorFk": {
|
||||||
|
"type": "number"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
{
|
||||||
|
"name": "SectorCollectionSaleGroup",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "sectorCollectionSaleGroup"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "number",
|
||||||
|
"id": true
|
||||||
|
},
|
||||||
|
"created": {
|
||||||
|
"type": "date"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"relations": {
|
||||||
|
"sectorCollection": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "SectorCollection",
|
||||||
|
"foreignKey": "sectorCollectionFk"
|
||||||
|
},
|
||||||
|
"saleGroup": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "SaleGroup",
|
||||||
|
"foreignKey": "saleGroupFk"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -33,7 +33,7 @@ module.exports = Self => {
|
||||||
JOIN vn.item i ON i.id = b.itemFk
|
JOIN vn.item i ON i.id = b.itemFk
|
||||||
WHERE e.id = ? AND e.supplierFk = ?
|
WHERE e.id = ? AND e.supplierFk = ?
|
||||||
GROUP BY i.id
|
GROUP BY i.id
|
||||||
) SELECT i.id, i.name, et.quantity, SUM(b.quantity) quantityTotal, et.printedStickers
|
) SELECT i.id, i.name, et.quantity, SUM(b.quantity) quantityTotal, et.printedStickers, ic.url
|
||||||
FROM vn.buy b
|
FROM vn.buy b
|
||||||
JOIN vn.item i ON i.id = b.itemFk
|
JOIN vn.item i ON i.id = b.itemFk
|
||||||
JOIN vn.entry e ON e.id = b.entryFk
|
JOIN vn.entry e ON e.id = b.entryFk
|
||||||
|
@ -41,6 +41,7 @@ module.exports = Self => {
|
||||||
JOIN vn.buyConfig bc ON bc.monthsAgo
|
JOIN vn.buyConfig bc ON bc.monthsAgo
|
||||||
JOIN vn.travel t ON t.id = e.travelFk
|
JOIN vn.travel t ON t.id = e.travelFk
|
||||||
LEFT JOIN entryTmp et ON et.id = i.id
|
LEFT JOIN entryTmp et ON et.id = i.id
|
||||||
|
JOIN hedera.imageConfig ic
|
||||||
WHERE e.supplierFk = ?
|
WHERE e.supplierFk = ?
|
||||||
AND i.family IN ('EMB', 'CONT')
|
AND i.family IN ('EMB', 'CONT')
|
||||||
AND b.created > (util.VN_CURDATE() - INTERVAL bc.monthsAgo MONTH)
|
AND b.created > (util.VN_CURDATE() - INTERVAL bc.monthsAgo MONTH)
|
||||||
|
|
|
@ -2,10 +2,12 @@ const models = require('vn-loopback/server/server').models;
|
||||||
const LoopBackContext = require('loopback-context');
|
const LoopBackContext = require('loopback-context');
|
||||||
|
|
||||||
describe('ticket setDelivered()', () => {
|
describe('ticket setDelivered()', () => {
|
||||||
const userId = 50;
|
const userId = 49;
|
||||||
const activeCtx = {
|
const activeCtx = {
|
||||||
accessToken: {userId: userId},
|
accessToken: {userId: userId},
|
||||||
|
__: value => value
|
||||||
};
|
};
|
||||||
|
const ctx = {req: activeCtx};
|
||||||
|
|
||||||
beforeAll(async() => {
|
beforeAll(async() => {
|
||||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||||
|
@ -19,8 +21,6 @@ describe('ticket setDelivered()', () => {
|
||||||
try {
|
try {
|
||||||
const options = {transaction: tx};
|
const options = {transaction: tx};
|
||||||
|
|
||||||
const ctx = {req: {accessToken: {userId: 49}}};
|
|
||||||
|
|
||||||
const originalTicketOne = await models.Ticket.findById(8, null, options);
|
const originalTicketOne = await models.Ticket.findById(8, null, options);
|
||||||
const originalTicketTwo = await models.Ticket.findById(10, null, options);
|
const originalTicketTwo = await models.Ticket.findById(10, null, options);
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,8 @@ module.exports = Self => {
|
||||||
http: {source: 'path'}
|
http: {source: 'path'}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
arg: 'itemId',
|
arg: 'barcode',
|
||||||
type: 'number',
|
type: 'any',
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -29,7 +29,7 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.addSale = async(ctx, id, itemId, quantity, options) => {
|
Self.addSale = async(ctx, id, barcode, quantity, options) => {
|
||||||
const $t = ctx.req.__; // $translate
|
const $t = ctx.req.__; // $translate
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
const myOptions = {userId: ctx.req.accessToken.userId};
|
const myOptions = {userId: ctx.req.accessToken.userId};
|
||||||
|
@ -46,7 +46,9 @@ module.exports = Self => {
|
||||||
try {
|
try {
|
||||||
await models.Ticket.isEditableOrThrow(ctx, id, myOptions);
|
await models.Ticket.isEditableOrThrow(ctx, id, myOptions);
|
||||||
|
|
||||||
|
const itemId = await models.ItemBarcode.toItem(barcode, myOptions);
|
||||||
const item = await models.Item.findById(itemId, null, myOptions);
|
const item = await models.Item.findById(itemId, null, myOptions);
|
||||||
|
|
||||||
const ticket = await models.Ticket.findById(id, {
|
const ticket = await models.Ticket.findById(id, {
|
||||||
include: {
|
include: {
|
||||||
relation: 'client',
|
relation: 'client',
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
const UserError = require('vn-loopback/util/user-error');
|
|
||||||
module.exports = Self => {
|
|
||||||
Self.remoteMethodCtx('addSaleByCode', {
|
|
||||||
description: 'Add a collection',
|
|
||||||
accessType: 'WRITE',
|
|
||||||
accepts: [
|
|
||||||
{
|
|
||||||
arg: 'barcode',
|
|
||||||
type: 'string',
|
|
||||||
required: true
|
|
||||||
}, {
|
|
||||||
arg: 'quantity',
|
|
||||||
type: 'number',
|
|
||||||
required: true
|
|
||||||
}, {
|
|
||||||
arg: 'ticketFk',
|
|
||||||
type: 'number',
|
|
||||||
required: true
|
|
||||||
}, {
|
|
||||||
arg: 'warehouseFk',
|
|
||||||
type: 'number',
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
|
|
||||||
],
|
|
||||||
http: {
|
|
||||||
path: `/addSaleByCode`,
|
|
||||||
verb: 'POST'
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Self.addSaleByCode = async(ctx, barcode, quantity, ticketFk, warehouseFk, options) => {
|
|
||||||
const myOptions = {userId: ctx.req.accessToken.userId};
|
|
||||||
let tx;
|
|
||||||
|
|
||||||
if (typeof options == 'object')
|
|
||||||
Object.assign(myOptions, options);
|
|
||||||
|
|
||||||
if (!myOptions.transaction) {
|
|
||||||
tx = await Self.beginTransaction({});
|
|
||||||
myOptions.transaction = tx;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const [[item]] = await Self.rawSql('CALL vn.item_getInfo(?,?)', [barcode, warehouseFk], myOptions);
|
|
||||||
if (!item?.available) throw new UserError('We do not have availability for the selected item');
|
|
||||||
|
|
||||||
await Self.rawSql('CALL vn.collection_addItem(?, ?, ?)', [item.id, quantity, ticketFk], myOptions);
|
|
||||||
|
|
||||||
if (tx) await tx.commit();
|
|
||||||
} catch (e) {
|
|
||||||
if (tx) await tx.rollback();
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -8,18 +8,13 @@ module.exports = Self => {
|
||||||
if (typeof options == 'object')
|
if (typeof options == 'object')
|
||||||
Object.assign(myOptions, options);
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
const state = await models.TicketState.findOne({
|
const state = await models.TicketState.findOne({where: {ticketFk: id}}, myOptions);
|
||||||
where: {ticketFk: id}
|
|
||||||
}, myOptions);
|
|
||||||
|
|
||||||
const isRoleAdvanced = await models.ACL.checkAccessAcl(ctx, 'Ticket', 'isRoleAdvanced', '*');
|
const isRoleAdvanced = await models.ACL.checkAccessAcl(ctx, 'Ticket', 'isRoleAdvanced', '*');
|
||||||
|
const isProductionReviewer = await models.ACL.checkAccessAcl(ctx, 'Sale', 'isInPreparing', '*');
|
||||||
const canEditWeeklyTicket = await models.ACL.checkAccessAcl(ctx, 'Ticket', 'canEditWeekly', 'WRITE');
|
const canEditWeeklyTicket = await models.ACL.checkAccessAcl(ctx, 'Ticket', 'canEditWeekly', 'WRITE');
|
||||||
const alertLevel = state ? state.alertLevel : null;
|
const alertLevel = state ? state.alertLevel : null;
|
||||||
const ticket = await models.Ticket.findById(id, {
|
const ticket = await models.Ticket.findById(id, {
|
||||||
fields: ['clientFk'],
|
fields: ['clientFk'], include: {relation: 'client'}
|
||||||
include: {
|
|
||||||
relation: 'client'
|
|
||||||
}
|
|
||||||
}, myOptions);
|
}, myOptions);
|
||||||
|
|
||||||
const isLocked = await models.Ticket.isLocked(id, myOptions);
|
const isLocked = await models.Ticket.isLocked(id, myOptions);
|
||||||
|
@ -29,10 +24,24 @@ module.exports = Self => {
|
||||||
const isNormalClient = ticket && ticket.client().typeFk == 'normal';
|
const isNormalClient = ticket && ticket.client().typeFk == 'normal';
|
||||||
const isEditable = !(alertLevelGreaterThanZero && isNormalClient);
|
const isEditable = !(alertLevelGreaterThanZero && isNormalClient);
|
||||||
|
|
||||||
|
const ticketCollection = await models.TicketCollection.findOne({
|
||||||
|
include: {relation: 'collection'}, where: {ticketFk: id}
|
||||||
|
}, myOptions);
|
||||||
|
let isOwner = ticketCollection?.collection()?.workerFk === ctx.req.accessToken.userId;
|
||||||
|
|
||||||
|
if (!isOwner) {
|
||||||
|
const saleGroup = await models.SaleGroup.findOne({fields: ['id'], where: {ticketFk: id}}, myOptions);
|
||||||
|
const sectorCollectionSaleGroup = saleGroup && await models.SectorCollectionSaleGroup.findOne({
|
||||||
|
include: {relation: 'sectorCollection'}, where: {saleGroupFk: saleGroup.id}
|
||||||
|
}, myOptions);
|
||||||
|
|
||||||
|
isOwner = sectorCollectionSaleGroup?.sectorCollection()?.userFk === ctx.req.accessToken.userId;
|
||||||
|
}
|
||||||
|
|
||||||
if (!ticket)
|
if (!ticket)
|
||||||
throw new ForbiddenError(`The ticket doesn't exist.`);
|
throw new ForbiddenError(`The ticket doesn't exist.`);
|
||||||
|
|
||||||
if (!isEditable && !isRoleAdvanced)
|
if (!isEditable && !isRoleAdvanced && !isProductionReviewer && !isOwner)
|
||||||
throw new ForbiddenError(`This ticket is not editable.`);
|
throw new ForbiddenError(`This ticket is not editable.`);
|
||||||
|
|
||||||
if (isLocked && !isWeekly)
|
if (isLocked && !isWeekly)
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
const {models} = require('vn-loopback/server/server');
|
|
||||||
const LoopBackContext = require('loopback-context');
|
|
||||||
|
|
||||||
describe('Ticket addSaleByCode()', () => {
|
|
||||||
const quantity = 3;
|
|
||||||
const ticketFk = 13;
|
|
||||||
const warehouseFk = 1;
|
|
||||||
beforeAll(async() => {
|
|
||||||
activeCtx = {
|
|
||||||
req: {
|
|
||||||
accessToken: {userId: 9},
|
|
||||||
headers: {origin: 'http://localhost'},
|
|
||||||
__: value => value
|
|
||||||
}
|
|
||||||
};
|
|
||||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
|
||||||
active: activeCtx
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add a new sale', async() => {
|
|
||||||
const tx = await models.Ticket.beginTransaction({});
|
|
||||||
|
|
||||||
try {
|
|
||||||
const options = {transaction: tx};
|
|
||||||
const code = '1111111111';
|
|
||||||
|
|
||||||
const salesBefore = await models.Sale.find(null, options);
|
|
||||||
await models.Ticket.addSaleByCode(activeCtx, code, quantity, ticketFk, warehouseFk, options);
|
|
||||||
const salesAfter = await models.Sale.find(null, options);
|
|
||||||
|
|
||||||
expect(salesAfter.length).toEqual(salesBefore.length + 1);
|
|
||||||
await tx.rollback();
|
|
||||||
} catch (e) {
|
|
||||||
await tx.rollback();
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -68,7 +68,7 @@ describe('ticket filter()', () => {
|
||||||
const filter = {};
|
const filter = {};
|
||||||
const result = await models.Ticket.filter(ctx, filter, options);
|
const result = await models.Ticket.filter(ctx, filter, options);
|
||||||
|
|
||||||
expect(result.length).toEqual(7);
|
expect(result.length).toEqual(10);
|
||||||
|
|
||||||
await tx.rollback();
|
await tx.rollback();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
@ -42,7 +42,7 @@ describe('sale priceDifference()', () => {
|
||||||
try {
|
try {
|
||||||
const options = {transaction: tx};
|
const options = {transaction: tx};
|
||||||
|
|
||||||
const ctx = {req: {accessToken: {userId: 1106}}};
|
const ctx = {req: {accessToken: {userId: 1105}}};
|
||||||
ctx.args = {
|
ctx.args = {
|
||||||
id: 1,
|
id: 1,
|
||||||
landed: Date.vnNew(),
|
landed: Date.vnNew(),
|
||||||
|
@ -84,7 +84,7 @@ describe('sale priceDifference()', () => {
|
||||||
|
|
||||||
const {items} = await models.Ticket.priceDifference(ctx, options);
|
const {items} = await models.Ticket.priceDifference(ctx, options);
|
||||||
|
|
||||||
expect(items[0].movable).toEqual(410);
|
expect(items[0].movable).toEqual(386);
|
||||||
expect(items[1].movable).toEqual(1810);
|
expect(items[1].movable).toEqual(1810);
|
||||||
|
|
||||||
await tx.rollback();
|
await tx.rollback();
|
||||||
|
|
|
@ -7,6 +7,7 @@ describe('ticket state()', () => {
|
||||||
const productionId = 49;
|
const productionId = 49;
|
||||||
const activeCtx = {
|
const activeCtx = {
|
||||||
accessToken: {userId: 9},
|
accessToken: {userId: 9},
|
||||||
|
__: value => value
|
||||||
};
|
};
|
||||||
const ctx = {req: activeCtx};
|
const ctx = {req: activeCtx};
|
||||||
const now = Date.vnNew();
|
const now = Date.vnNew();
|
||||||
|
@ -88,7 +89,8 @@ describe('ticket state()', () => {
|
||||||
const ticket = await models.Ticket.create(sampleTicket, options);
|
const ticket = await models.Ticket.create(sampleTicket, options);
|
||||||
|
|
||||||
activeCtx.accessToken.userId = productionId;
|
activeCtx.accessToken.userId = productionId;
|
||||||
const params = {ticketFk: ticket.id, stateFk: 3};
|
const stateOk = await models.State.findOne({where: {code: 'OK'}}, options);
|
||||||
|
const params = {ticketFk: ticket.id, stateFk: stateOk.id};
|
||||||
|
|
||||||
const ticketTracking = await models.Ticket.state(ctx, params, options);
|
const ticketTracking = await models.Ticket.state(ctx, params, options);
|
||||||
|
|
||||||
|
@ -112,16 +114,68 @@ describe('ticket state()', () => {
|
||||||
const options = {transaction: tx};
|
const options = {transaction: tx};
|
||||||
|
|
||||||
const ticket = await models.Ticket.create(sampleTicket, options);
|
const ticket = await models.Ticket.create(sampleTicket, options);
|
||||||
const ctx = {req: {accessToken: {userId: 18}}};
|
activeCtx.accessToken.userId = salesPersonId;
|
||||||
const assignedState = await models.State.findOne({where: {code: 'PICKER_DESIGNED'}}, options);
|
const assignedState = await models.State.findOne({where: {code: 'PICKER_DESIGNED'}}, options);
|
||||||
const params = {ticketFk: ticket.id, stateFk: assignedState.id, userFk: 1};
|
const paramsAssigned = {ticketFk: ticket.id, stateFk: assignedState.id, userFk: 1};
|
||||||
const res = await models.Ticket.state(ctx, params, options);
|
const resAssigned = await models.Ticket.state(ctx, paramsAssigned, options);
|
||||||
|
|
||||||
expect(res.ticketFk).toBe(params.ticketFk);
|
expect(resAssigned.ticketFk).toBe(paramsAssigned.ticketFk);
|
||||||
expect(res.stateFk).toBe(params.stateFk);
|
expect(resAssigned.stateFk).toBe(paramsAssigned.stateFk);
|
||||||
expect(res.userFk).toBe(params.userFk);
|
expect(resAssigned.userFk).toBe(paramsAssigned.userFk);
|
||||||
expect(res.userFk).toBe(1);
|
expect(resAssigned.userFk).toBe(1);
|
||||||
expect(res.id).toBeDefined();
|
expect(resAssigned.id).toBeDefined();
|
||||||
|
|
||||||
|
activeCtx.accessToken.userId = productionId;
|
||||||
|
const packedState = await models.State.findOne({where: {code: 'PACKED'}}, options);
|
||||||
|
const paramsPacked = {ticketFk: ticket.id, stateFk: packedState.id, userFk: salesPersonId};
|
||||||
|
const resPacked = await models.Ticket.state(ctx, paramsPacked, options);
|
||||||
|
|
||||||
|
expect(resPacked.stateFk).toBe(paramsPacked.stateFk);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should equalize the quantities of quantity and originalQuantity' +
|
||||||
|
' if they are different', async() => {
|
||||||
|
const tx = await models.TicketTracking.beginTransaction({});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
const ticket = await models.Ticket.create(sampleTicket, options);
|
||||||
|
activeCtx.accessToken.userId = salesPersonId;
|
||||||
|
|
||||||
|
const sampleSale = {
|
||||||
|
ticketFk: ticket.id,
|
||||||
|
itemFk: 1,
|
||||||
|
concept: 'Test',
|
||||||
|
quantity: 10,
|
||||||
|
originalQuantity: 6
|
||||||
|
};
|
||||||
|
await models.Sale.create(sampleSale, options);
|
||||||
|
const assignedState = await models.State.findOne({where: {code: 'PICKER_DESIGNED'}}, options);
|
||||||
|
const paramsAssigned = {ticketFk: ticket.id, stateFk: assignedState.id, userFk: 1};
|
||||||
|
const resAssigned = await models.Ticket.state(ctx, paramsAssigned, options);
|
||||||
|
|
||||||
|
expect(resAssigned.ticketFk).toBe(paramsAssigned.ticketFk);
|
||||||
|
expect(resAssigned.stateFk).toBe(paramsAssigned.stateFk);
|
||||||
|
expect(resAssigned.userFk).toBe(paramsAssigned.userFk);
|
||||||
|
expect(resAssigned.userFk).toBe(1);
|
||||||
|
expect(resAssigned.id).toBeDefined();
|
||||||
|
|
||||||
|
activeCtx.accessToken.userId = productionId;
|
||||||
|
const packedState = await models.State.findOne({where: {code: 'PACKED'}}, options);
|
||||||
|
const paramsPacked = {ticketFk: ticket.id, stateFk: packedState.id, userFk: salesPersonId};
|
||||||
|
const resPacked = await models.Ticket.state(ctx, paramsPacked, options);
|
||||||
|
|
||||||
|
const sale = await models.Sale.findOne({where: {ticketFk: ticket.id}}, options);
|
||||||
|
|
||||||
|
expect(resPacked.stateFk).toBe(paramsPacked.stateFk);
|
||||||
|
expect(sale.quantity).toBe(sale.originalQuantity);
|
||||||
|
|
||||||
await tx.rollback();
|
await tx.rollback();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
@ -64,7 +64,63 @@ module.exports = Self => {
|
||||||
if ((ticketState && !oldStateAllowed) || !newStateAllowed)
|
if ((ticketState && !oldStateAllowed) || !newStateAllowed)
|
||||||
throw new UserError(`You don't have enough privileges`, 'ACCESS_DENIED');
|
throw new UserError(`You don't have enough privileges`, 'ACCESS_DENIED');
|
||||||
|
|
||||||
await Self.rawSql(`CALL vn.ticket_setState(?, ?)`, [params.ticketFk, params.code], myOptions);
|
const ticket = await models.Ticket.findById(params.ticketFk, {
|
||||||
|
include: [{
|
||||||
|
relation: 'client',
|
||||||
|
scope: {
|
||||||
|
fields: ['salesPersonFk']
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
fields: ['id', 'clientFk']
|
||||||
|
}, myOptions);
|
||||||
|
|
||||||
|
const salesPersonFk = ticket.client().salesPersonFk;
|
||||||
|
if (salesPersonFk) {
|
||||||
|
const sales = await Self.rawSql(`
|
||||||
|
SELECT DISTINCT s.id,
|
||||||
|
s.itemFk,
|
||||||
|
s.concept,
|
||||||
|
s.originalQuantity AS oldQuantity,
|
||||||
|
s.quantity AS newQuantity
|
||||||
|
FROM vn.sale s
|
||||||
|
JOIN vn.saleTracking st ON st.saleFk = s.id
|
||||||
|
JOIN vn.ticket t ON t.id = s.ticketFk
|
||||||
|
JOIN vn.client c ON c.id = t.clientFk
|
||||||
|
JOIN vn.ticketState ts ON ts.ticketFk = t.id
|
||||||
|
JOIN vn.state s2 ON s2.id = ts.stateFk
|
||||||
|
WHERE s.ticketFk = ?
|
||||||
|
AND st.isChecked
|
||||||
|
AND s.originalQuantity IS NOT NULL
|
||||||
|
AND s.originalQuantity <> s.quantity
|
||||||
|
AND s2.\`order\` < (SELECT \`order\` FROM vn.state WHERE code = 'CHECKED')
|
||||||
|
ORDER BY st.created DESC
|
||||||
|
`, [params.ticketFk], myOptions);
|
||||||
|
|
||||||
|
let changes = '';
|
||||||
|
const url = await models.Url.getUrl();
|
||||||
|
const $t = ctx.req.__;
|
||||||
|
for (let sale of sales) {
|
||||||
|
changes += `\r\n-` + $t('Changes in sales', {
|
||||||
|
itemId: sale.itemFk,
|
||||||
|
concept: sale.concept,
|
||||||
|
oldQuantity: sale.oldQuantity,
|
||||||
|
newQuantity: sale.newQuantity,
|
||||||
|
itemUrl: `${url}item/${sale.itemFk}/summary`
|
||||||
|
});
|
||||||
|
const currentSale = await models.Sale.findById(sale.id, null, myOptions);
|
||||||
|
await currentSale.updateAttributes({
|
||||||
|
originalQuantity: currentSale.quantity
|
||||||
|
}, myOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
const message = $t('Changed sale quantity', {
|
||||||
|
ticketId: ticket.id,
|
||||||
|
changes: changes,
|
||||||
|
ticketUrl: `${url}ticket/${ticket.id}/sale`
|
||||||
|
});
|
||||||
|
await models.Chat.sendCheckingPresence(ctx, salesPersonFk, message, myOptions);
|
||||||
|
}
|
||||||
|
await Self.rawSql(`CALL vn.ticket_setState(?, ?)`, [ticket.id, params.code], myOptions);
|
||||||
|
|
||||||
const ticketTracking = await models.TicketTracking.findOne({
|
const ticketTracking = await models.TicketTracking.findOne({
|
||||||
where: {ticketFk: params.ticketFk},
|
where: {ticketFk: params.ticketFk},
|
||||||
|
|
|
@ -14,6 +14,9 @@
|
||||||
},
|
},
|
||||||
"parkingFk": {
|
"parkingFk": {
|
||||||
"type": "number"
|
"type": "number"
|
||||||
|
},
|
||||||
|
"ticketFk": {
|
||||||
|
"type": "number"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"relations": {
|
"relations": {
|
||||||
|
|
|
@ -1,361 +1,318 @@
|
||||||
/* eslint max-len: ["error", { "code": 150 }]*/
|
/* eslint max-len: ["error", { "code": 150 }]*/
|
||||||
|
const {models} = require('vn-loopback/server/server');
|
||||||
const models = require('vn-loopback/server/server').models;
|
|
||||||
const LoopBackContext = require('loopback-context');
|
const LoopBackContext = require('loopback-context');
|
||||||
|
|
||||||
describe('sale model ', () => {
|
describe('sale model ', () => {
|
||||||
const ctx = {
|
const developerId = 9;
|
||||||
req: {
|
const buyerId = 35;
|
||||||
accessToken: {userId: 9},
|
const employeeId = 1;
|
||||||
headers: {origin: 'localhost:5000'},
|
const productionId = 49;
|
||||||
__: () => {}
|
const salesPersonId = 18;
|
||||||
}
|
const reviewerId = 130;
|
||||||
};
|
|
||||||
function getActiveCtx(userId) {
|
const barcode = '4444444444';
|
||||||
return {
|
const ticketCollectionProd = 34;
|
||||||
active: {
|
const ticketCollectionSalesPerson = 35;
|
||||||
accessToken: {userId},
|
const previaTicketSalesPerson = 36;
|
||||||
http: {
|
const previaTicketProd = 37;
|
||||||
req: {
|
const notEditableError = 'This ticket is not editable.';
|
||||||
headers: {origin: 'http://localhost'}
|
|
||||||
}
|
const ctx = getCtx(developerId);
|
||||||
}
|
let tx;
|
||||||
}
|
let opts;
|
||||||
};
|
|
||||||
|
function getCtx(userId, active = false) {
|
||||||
|
const accessToken = {userId};
|
||||||
|
const headers = {origin: 'localhost:5000'};
|
||||||
|
if (!active) return {req: {accessToken, headers, __: () => {}}};
|
||||||
|
return {active: {accessToken, http: {req: {headers}}}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
beforeEach(async() => {
|
||||||
|
tx = await models.Sale.beginTransaction({});
|
||||||
|
opts = {transaction: tx};
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async() => await tx.rollback());
|
||||||
|
|
||||||
describe('quantity field ', () => {
|
describe('quantity field ', () => {
|
||||||
it('should add quantity if the quantity is greater than it should be and is role advanced', async() => {
|
it('should add quantity if the quantity is greater than it should be and is role advanced', async() => {
|
||||||
const saleId = 17;
|
const saleId = 17;
|
||||||
const buyerId = 35;
|
const ctx = getCtx(buyerId);
|
||||||
const ctx = {
|
|
||||||
req: {
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getCtx(buyerId, true));
|
||||||
accessToken: {userId: buyerId},
|
spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, opts) => {
|
||||||
headers: {origin: 'localhost:5000'},
|
|
||||||
__: () => {}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const tx = await models.Sale.beginTransaction({});
|
|
||||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(buyerId));
|
|
||||||
spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => {
|
|
||||||
if (sqlStatement.includes('catalog_calcFromItem')) {
|
if (sqlStatement.includes('catalog_calcFromItem')) {
|
||||||
sqlStatement = `CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY
|
sqlStatement = `CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY
|
||||||
SELECT 100 as available;`;
|
SELECT 100 as available;`;
|
||||||
params = null;
|
params = null;
|
||||||
}
|
}
|
||||||
return models.Ticket.rawSql(sqlStatement, params, options);
|
return models.Ticket.rawSql(sqlStatement, params, opts);
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
|
||||||
const options = {transaction: tx};
|
|
||||||
|
|
||||||
const isRoleAdvanced = await models.ACL.checkAccessAcl(ctx, 'Ticket', 'isRoleAdvanced', '*');
|
const isRoleAdvanced = await models.ACL.checkAccessAcl(ctx, 'Ticket', 'isRoleAdvanced', '*');
|
||||||
|
|
||||||
expect(isRoleAdvanced).toEqual(true);
|
expect(isRoleAdvanced).toEqual(true);
|
||||||
|
|
||||||
const originalLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, options);
|
const originalLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, opts);
|
||||||
|
|
||||||
expect(originalLine.quantity).toEqual(30);
|
expect(originalLine.quantity).toEqual(30);
|
||||||
|
|
||||||
const newQuantity = originalLine.quantity + 1;
|
const newQuantity = originalLine.quantity + 1;
|
||||||
await models.Sale.updateQuantity(ctx, saleId, newQuantity, options);
|
await models.Sale.updateQuantity(ctx, saleId, newQuantity, opts);
|
||||||
|
|
||||||
const modifiedLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, options);
|
const modifiedLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, opts);
|
||||||
|
|
||||||
expect(modifiedLine.quantity).toEqual(newQuantity);
|
expect(modifiedLine.quantity).toEqual(newQuantity);
|
||||||
|
|
||||||
await tx.rollback();
|
|
||||||
} catch (e) {
|
|
||||||
await tx.rollback();
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update the quantity of a given sale current line', async() => {
|
it('should update the quantity of a given sale current line', async() => {
|
||||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(9));
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getCtx(developerId, true));
|
||||||
|
|
||||||
const tx = await models.Sale.beginTransaction({});
|
|
||||||
const saleId = 25;
|
const saleId = 25;
|
||||||
const newQuantity = 4;
|
const newQuantity = 4;
|
||||||
|
|
||||||
try {
|
const originalLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, opts);
|
||||||
const options = {transaction: tx};
|
|
||||||
|
|
||||||
const originalLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, options);
|
|
||||||
|
|
||||||
expect(originalLine.quantity).toEqual(20);
|
expect(originalLine.quantity).toEqual(20);
|
||||||
|
|
||||||
await models.Sale.updateQuantity(ctx, saleId, newQuantity, options);
|
await models.Sale.updateQuantity(ctx, saleId, newQuantity, opts);
|
||||||
|
|
||||||
const modifiedLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, options);
|
const modifiedLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, opts);
|
||||||
|
|
||||||
expect(modifiedLine.quantity).toEqual(newQuantity);
|
expect(modifiedLine.quantity).toEqual(newQuantity);
|
||||||
|
|
||||||
await tx.rollback();
|
|
||||||
} catch (e) {
|
|
||||||
await tx.rollback();
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error if the quantity is negative and it is not a refund ticket', async() => {
|
it('should throw an error if the quantity is negative and it is not a refund ticket', async() => {
|
||||||
const ctx = {
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getCtx(employeeId, true));
|
||||||
req: {
|
|
||||||
accessToken: {userId: 1},
|
|
||||||
headers: {origin: 'localhost:5000'},
|
|
||||||
__: () => {}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1));
|
|
||||||
|
|
||||||
const saleId = 17;
|
const saleId = 17;
|
||||||
const newQuantity = -10;
|
const newQuantity = -10;
|
||||||
|
|
||||||
const tx = await models.Sale.beginTransaction({});
|
|
||||||
|
|
||||||
let error;
|
|
||||||
try {
|
try {
|
||||||
const options = {transaction: tx};
|
await models.Sale.updateQuantity(ctx, saleId, newQuantity, opts);
|
||||||
|
|
||||||
await models.Sale.updateQuantity(ctx, saleId, newQuantity, options);
|
|
||||||
|
|
||||||
await tx.rollback();
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
await tx.rollback();
|
expect(e).toEqual(new Error('You can only add negative amounts in refund tickets'));
|
||||||
error = e;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(error).toEqual(new Error('You can only add negative amounts in refund tickets'));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update a negative quantity when is a ticket refund', async() => {
|
it('should update a negative quantity when is a ticket refund', async() => {
|
||||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(9));
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getCtx(developerId, true));
|
||||||
|
|
||||||
const tx = await models.Sale.beginTransaction({});
|
|
||||||
const saleId = 32;
|
const saleId = 32;
|
||||||
const newQuantity = -10;
|
const newQuantity = -10;
|
||||||
|
|
||||||
try {
|
await models.Sale.updateQuantity(ctx, saleId, newQuantity, opts);
|
||||||
const options = {transaction: tx};
|
|
||||||
|
|
||||||
await models.Sale.updateQuantity(ctx, saleId, newQuantity, options);
|
const modifiedLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, opts);
|
||||||
|
|
||||||
const modifiedLine = await models.Sale.findOne({where: {id: saleId}, fields: ['quantity']}, options);
|
|
||||||
|
|
||||||
expect(modifiedLine.quantity).toEqual(newQuantity);
|
expect(modifiedLine.quantity).toEqual(newQuantity);
|
||||||
|
|
||||||
await tx.rollback();
|
|
||||||
} catch (e) {
|
|
||||||
await tx.rollback();
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error if the quantity is less than the minimum quantity of the item', async() => {
|
it('should throw an error if the quantity is less than the minimum quantity of the item', async() => {
|
||||||
const ctx = {
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getCtx(employeeId, true));
|
||||||
req: {
|
|
||||||
accessToken: {userId: 1},
|
|
||||||
headers: {origin: 'localhost:5000'},
|
|
||||||
__: () => {}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1));
|
|
||||||
|
|
||||||
const tx = await models.Sale.beginTransaction({});
|
|
||||||
const itemId = 2;
|
const itemId = 2;
|
||||||
const saleId = 17;
|
const saleId = 17;
|
||||||
const minQuantity = 30;
|
const minQuantity = 30;
|
||||||
const newQuantity = minQuantity - 1;
|
const newQuantity = minQuantity - 1;
|
||||||
|
|
||||||
let error;
|
|
||||||
try {
|
try {
|
||||||
const options = {transaction: tx};
|
const item = await models.Item.findById(itemId, null, opts);
|
||||||
|
await item.updateAttribute('minQuantity', minQuantity, opts);
|
||||||
const item = await models.Item.findById(itemId, null, options);
|
spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, opts) => {
|
||||||
await item.updateAttribute('minQuantity', minQuantity, options);
|
|
||||||
spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => {
|
|
||||||
if (sqlStatement.includes('catalog_calcFromItem')) {
|
if (sqlStatement.includes('catalog_calcFromItem')) {
|
||||||
sqlStatement = `CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY
|
sqlStatement = `CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY
|
||||||
SELECT 100 as available;`;
|
SELECT 100 as available;`;
|
||||||
params = null;
|
params = null;
|
||||||
}
|
}
|
||||||
return models.Ticket.rawSql(sqlStatement, params, options);
|
return models.Ticket.rawSql(sqlStatement, params, opts);
|
||||||
});
|
});
|
||||||
|
|
||||||
await models.Sale.updateQuantity(ctx, saleId, newQuantity, options);
|
await models.Sale.updateQuantity(ctx, saleId, newQuantity, opts);
|
||||||
|
|
||||||
await tx.rollback();
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
await tx.rollback();
|
expect(e).toEqual(new Error('The amount cannot be less than the minimum'));
|
||||||
error = e;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(error).toEqual(new Error('The amount cannot be less than the minimum'));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should change quantity if has minimum quantity and new quantity is equal than item available', async() => {
|
it('should change quantity if has minimum quantity and new quantity is equal than item available', async() => {
|
||||||
const ctx = {
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getCtx(employeeId, true));
|
||||||
req: {
|
|
||||||
accessToken: {userId: 1},
|
|
||||||
headers: {origin: 'localhost:5000'},
|
|
||||||
__: () => {}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1));
|
|
||||||
|
|
||||||
const tx = await models.Sale.beginTransaction({});
|
|
||||||
const itemId = 2;
|
const itemId = 2;
|
||||||
const saleId = 17;
|
const saleId = 17;
|
||||||
const minQuantity = 30;
|
const minQuantity = 30;
|
||||||
const newQuantity = minQuantity - 1;
|
const newQuantity = minQuantity - 1;
|
||||||
|
|
||||||
try {
|
const item = await models.Item.findById(itemId, null, opts);
|
||||||
const options = {transaction: tx};
|
await item.updateAttribute('minQuantity', minQuantity, opts);
|
||||||
|
|
||||||
const item = await models.Item.findById(itemId, null, options);
|
spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, opts) => {
|
||||||
await item.updateAttribute('minQuantity', minQuantity, options);
|
|
||||||
|
|
||||||
spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => {
|
|
||||||
if (sqlStatement.includes('catalog_calcFromItem')) {
|
if (sqlStatement.includes('catalog_calcFromItem')) {
|
||||||
sqlStatement = `CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY
|
sqlStatement = `CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY
|
||||||
SELECT ${newQuantity} as available;`;
|
SELECT ${newQuantity} as available;`;
|
||||||
params = null;
|
params = null;
|
||||||
}
|
}
|
||||||
return models.Ticket.rawSql(sqlStatement, params, options);
|
return models.Ticket.rawSql(sqlStatement, params, opts);
|
||||||
});
|
});
|
||||||
|
|
||||||
await models.Sale.updateQuantity(ctx, saleId, newQuantity, options);
|
await models.Sale.updateQuantity(ctx, saleId, newQuantity, opts);
|
||||||
|
|
||||||
await tx.rollback();
|
|
||||||
} catch (e) {
|
|
||||||
await tx.rollback();
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('newPrice', () => {
|
describe('newPrice', () => {
|
||||||
it('should increase quantity if you have enough available and the new price is the same as the previous one', async() => {
|
it('should increase quantity if you have enough available and the new price is the same as the previous one', async() => {
|
||||||
const ctx = {
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getCtx(employeeId, true));
|
||||||
req: {
|
|
||||||
accessToken: {userId: 1},
|
|
||||||
headers: {origin: 'localhost:5000'},
|
|
||||||
__: () => {}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1));
|
|
||||||
|
|
||||||
const tx = await models.Sale.beginTransaction({});
|
|
||||||
const itemId = 2;
|
const itemId = 2;
|
||||||
const saleId = 17;
|
const saleId = 17;
|
||||||
const minQuantity = 30;
|
const minQuantity = 30;
|
||||||
const newQuantity = 31;
|
const newQuantity = 31;
|
||||||
|
|
||||||
try {
|
const item = await models.Item.findById(itemId, null, opts);
|
||||||
const options = {transaction: tx};
|
await item.updateAttribute('minQuantity', minQuantity, opts);
|
||||||
|
spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, opts) => {
|
||||||
const item = await models.Item.findById(itemId, null, options);
|
|
||||||
await item.updateAttribute('minQuantity', minQuantity, options);
|
|
||||||
spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => {
|
|
||||||
if (sqlStatement.includes('catalog_calcFromItem')) {
|
if (sqlStatement.includes('catalog_calcFromItem')) {
|
||||||
sqlStatement = `
|
sqlStatement = `
|
||||||
CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available;
|
CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available;
|
||||||
CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 7.07 as price;`;
|
CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 7.07 as price;`;
|
||||||
params = null;
|
params = null;
|
||||||
}
|
}
|
||||||
return models.Ticket.rawSql(sqlStatement, params, options);
|
return models.Ticket.rawSql(sqlStatement, params, opts);
|
||||||
});
|
});
|
||||||
|
|
||||||
await models.Sale.updateQuantity(ctx, saleId, newQuantity, options);
|
await models.Sale.updateQuantity(ctx, saleId, newQuantity, opts);
|
||||||
|
|
||||||
await tx.rollback();
|
|
||||||
} catch (e) {
|
|
||||||
await tx.rollback();
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should increase quantity when the new price is lower than the previous one', async() => {
|
it('should increase quantity when the new price is lower than the previous one', async() => {
|
||||||
const ctx = {
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getCtx(employeeId, true));
|
||||||
req: {
|
|
||||||
accessToken: {userId: 1},
|
|
||||||
headers: {origin: 'localhost:5000'},
|
|
||||||
__: () => {}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1));
|
|
||||||
|
|
||||||
const tx = await models.Sale.beginTransaction({});
|
|
||||||
const itemId = 2;
|
const itemId = 2;
|
||||||
const saleId = 17;
|
const saleId = 17;
|
||||||
const minQuantity = 30;
|
const minQuantity = 30;
|
||||||
const newQuantity = 31;
|
const newQuantity = 31;
|
||||||
|
|
||||||
try {
|
const item = await models.Item.findById(itemId, null, opts);
|
||||||
const options = {transaction: tx};
|
await item.updateAttribute('minQuantity', minQuantity, opts);
|
||||||
|
spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, opts) => {
|
||||||
const item = await models.Item.findById(itemId, null, options);
|
|
||||||
await item.updateAttribute('minQuantity', minQuantity, options);
|
|
||||||
spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => {
|
|
||||||
if (sqlStatement.includes('catalog_calcFromItem')) {
|
if (sqlStatement.includes('catalog_calcFromItem')) {
|
||||||
sqlStatement = `
|
sqlStatement = `
|
||||||
CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available;
|
CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available;
|
||||||
CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 1 as price;`;
|
CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 1 as price;`;
|
||||||
params = null;
|
params = null;
|
||||||
}
|
}
|
||||||
return models.Ticket.rawSql(sqlStatement, params, options);
|
return models.Ticket.rawSql(sqlStatement, params, opts);
|
||||||
});
|
});
|
||||||
|
|
||||||
await models.Sale.updateQuantity(ctx, saleId, newQuantity, options);
|
await models.Sale.updateQuantity(ctx, saleId, newQuantity, opts);
|
||||||
|
|
||||||
await tx.rollback();
|
|
||||||
} catch (e) {
|
|
||||||
await tx.rollback();
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw error when increase quantity and the new price is higher than the previous one', async() => {
|
it('should throw error when increase quantity and the new price is higher than the previous one', async() => {
|
||||||
const ctx = {
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getCtx(employeeId, true));
|
||||||
req: {
|
|
||||||
accessToken: {userId: 1},
|
|
||||||
headers: {origin: 'localhost:5000'},
|
|
||||||
__: () => {}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getActiveCtx(1));
|
|
||||||
|
|
||||||
const tx = await models.Sale.beginTransaction({});
|
|
||||||
const itemId = 2;
|
const itemId = 2;
|
||||||
const saleId = 17;
|
const saleId = 17;
|
||||||
const minQuantity = 30;
|
const minQuantity = 30;
|
||||||
const newQuantity = 31;
|
const newQuantity = 31;
|
||||||
|
|
||||||
let error;
|
|
||||||
try {
|
try {
|
||||||
const options = {transaction: tx};
|
const item = await models.Item.findById(itemId, null, opts);
|
||||||
|
await item.updateAttribute('minQuantity', minQuantity, opts);
|
||||||
const item = await models.Item.findById(itemId, null, options);
|
spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, opts) => {
|
||||||
await item.updateAttribute('minQuantity', minQuantity, options);
|
|
||||||
spyOn(models.Sale, 'rawSql').and.callFake((sqlStatement, params, options) => {
|
|
||||||
if (sqlStatement.includes('catalog_calcFromItem')) {
|
if (sqlStatement.includes('catalog_calcFromItem')) {
|
||||||
sqlStatement = `
|
sqlStatement = `
|
||||||
CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available;
|
CREATE OR REPLACE TEMPORARY TABLE tmp.ticketCalculateItem ENGINE = MEMORY SELECT ${newQuantity} as available;
|
||||||
CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 100000 as price;`;
|
CREATE OR REPLACE TEMPORARY TABLE tmp.ticketComponentPrice ENGINE = MEMORY SELECT 1 as grouping, 100000 as price;`;
|
||||||
params = null;
|
params = null;
|
||||||
}
|
}
|
||||||
return models.Ticket.rawSql(sqlStatement, params, options);
|
return models.Ticket.rawSql(sqlStatement, params, opts);
|
||||||
});
|
});
|
||||||
|
|
||||||
await models.Sale.updateQuantity(ctx, saleId, newQuantity, options);
|
await models.Sale.updateQuantity(ctx, saleId, newQuantity, opts);
|
||||||
|
|
||||||
await tx.rollback();
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
await tx.rollback();
|
expect(e).toEqual(new Error('The price of the item changed'));
|
||||||
error = e;
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('add a sale from a collection or previa ticket', () => {
|
||||||
|
it('if is allocated to them and alert level higher than 0 as Production role', async() => {
|
||||||
|
const ctx = getCtx(productionId);
|
||||||
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getCtx(productionId, true));
|
||||||
|
|
||||||
|
const beforeSalesCollection = await models.Sale.count({ticketFk: ticketCollectionProd}, opts);
|
||||||
|
await models.Ticket.addSale(ctx, ticketCollectionProd, barcode, 20, opts);
|
||||||
|
const afterSalesCollection = await models.Sale.count({ticketFk: ticketCollectionProd}, opts);
|
||||||
|
|
||||||
|
expect(afterSalesCollection).toEqual(beforeSalesCollection + 1);
|
||||||
|
|
||||||
|
const beforeSalesPrevia = await models.Sale.count({ticketFk: previaTicketProd}, opts);
|
||||||
|
await models.Ticket.addSale(ctx, previaTicketProd, barcode, 20, opts);
|
||||||
|
const afterSalesPrevia = await models.Sale.count({ticketFk: previaTicketProd}, opts);
|
||||||
|
|
||||||
|
expect(afterSalesPrevia).toEqual(beforeSalesPrevia + 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw an error if is not allocated to them and alert level higher than 0 as Production role', async() => {
|
||||||
|
const ctx = getCtx(productionId);
|
||||||
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getCtx(productionId, true));
|
||||||
|
|
||||||
|
try {
|
||||||
|
await models.Ticket.addSale(ctx, ticketCollectionSalesPerson, barcode, 20, opts);
|
||||||
|
} catch ({message}) {
|
||||||
|
expect(message).toEqual(notEditableError);
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(error).toEqual(new Error('The price of the item changed'));
|
try {
|
||||||
|
await models.Ticket.addSale(ctx, previaTicketSalesPerson, barcode, 20, opts);
|
||||||
|
} catch ({message}) {
|
||||||
|
expect(message).toEqual(notEditableError);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('if is allocated to them and alert level higher than 0 as salesPerson role', async() => {
|
||||||
|
const ctx = getCtx(salesPersonId);
|
||||||
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getCtx(salesPersonId, true));
|
||||||
|
|
||||||
|
const beforeSalesCollection = await models.Sale.count({ticketFk: ticketCollectionSalesPerson}, opts);
|
||||||
|
await models.Ticket.addSale(ctx, ticketCollectionSalesPerson, barcode, 20, opts);
|
||||||
|
const afterSalesCollection = await models.Sale.count({ticketFk: ticketCollectionSalesPerson}, opts);
|
||||||
|
|
||||||
|
expect(afterSalesCollection).toEqual(beforeSalesCollection + 1);
|
||||||
|
|
||||||
|
const beforeSalesPrevia = await models.Sale.count({ticketFk: previaTicketSalesPerson}, opts);
|
||||||
|
await models.Ticket.addSale(ctx, previaTicketSalesPerson, barcode, 20, opts);
|
||||||
|
const afterSalesPrevia = await models.Sale.count({ticketFk: previaTicketSalesPerson}, opts);
|
||||||
|
|
||||||
|
expect(afterSalesPrevia).toEqual(beforeSalesPrevia + 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw an error if is not allocated to them and alert level higher than 0 as salesPerson role', async() => {
|
||||||
|
const ctx = getCtx(salesPersonId);
|
||||||
|
|
||||||
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getCtx(salesPersonId, true));
|
||||||
|
|
||||||
|
try {
|
||||||
|
await models.Ticket.addSale(ctx, ticketCollectionProd, barcode, 20, opts);
|
||||||
|
} catch ({message}) {
|
||||||
|
expect(message).toEqual(notEditableError);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('if is a reviewer', async() => {
|
||||||
|
const ctx = getCtx(reviewerId);
|
||||||
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue(getCtx(reviewerId, true));
|
||||||
|
|
||||||
|
const beforeSalesCollection = await models.Sale.count({ticketFk: ticketCollectionSalesPerson}, opts);
|
||||||
|
await models.Ticket.addSale(ctx, ticketCollectionSalesPerson, barcode, 20, opts);
|
||||||
|
const afterSalesCollection = await models.Sale.count({ticketFk: ticketCollectionSalesPerson}, opts);
|
||||||
|
|
||||||
|
expect(afterSalesCollection).toEqual(beforeSalesCollection + 1);
|
||||||
|
|
||||||
|
const beforeSalesPrevia = await models.Sale.count({ticketFk: previaTicketSalesPerson}, opts);
|
||||||
|
await models.Ticket.addSale(ctx, previaTicketSalesPerson, barcode, 20, opts);
|
||||||
|
const afterSalesPrevia = await models.Sale.count({ticketFk: previaTicketSalesPerson}, opts);
|
||||||
|
|
||||||
|
expect(afterSalesPrevia).toEqual(beforeSalesPrevia + 1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -46,7 +46,6 @@ module.exports = function(Self) {
|
||||||
require('../methods/ticket/invoiceTicketsAndPdf')(Self);
|
require('../methods/ticket/invoiceTicketsAndPdf')(Self);
|
||||||
require('../methods/ticket/docuwareDownload')(Self);
|
require('../methods/ticket/docuwareDownload')(Self);
|
||||||
require('../methods/ticket/myLastModified')(Self);
|
require('../methods/ticket/myLastModified')(Self);
|
||||||
require('../methods/ticket/addSaleByCode')(Self);
|
|
||||||
require('../methods/ticket/clone')(Self);
|
require('../methods/ticket/clone')(Self);
|
||||||
require('../methods/ticket/itemLack')(Self);
|
require('../methods/ticket/itemLack')(Self);
|
||||||
require('../methods/ticket/itemLackDetail')(Self);
|
require('../methods/ticket/itemLackDetail')(Self);
|
||||||
|
|
|
@ -152,7 +152,7 @@
|
||||||
</vn-item>
|
</vn-item>
|
||||||
<vn-item class="dropdown"
|
<vn-item class="dropdown"
|
||||||
vn-click-stop="refundMenu.show($event, 'left')"
|
vn-click-stop="refundMenu.show($event, 'left')"
|
||||||
vn-acl="invoicing, claimManager, salesAssistant"
|
vn-acl="invoicing, claimManager, salesAssistant, logistic"
|
||||||
vn-acl-action="remove"
|
vn-acl-action="remove"
|
||||||
vn-tooltip="Create a single ticket with all the content of the current ticket"
|
vn-tooltip="Create a single ticket with all the content of the current ticket"
|
||||||
translate>
|
translate>
|
||||||
|
|
|
@ -476,7 +476,7 @@ class Controller extends Section {
|
||||||
*/
|
*/
|
||||||
addSale(sale) {
|
addSale(sale) {
|
||||||
const data = {
|
const data = {
|
||||||
itemId: sale.itemFk,
|
barcode: sale.itemFk,
|
||||||
quantity: sale.quantity
|
quantity: sale.quantity
|
||||||
};
|
};
|
||||||
const query = `tickets/${this.ticket.id}/addSale`;
|
const query = `tickets/${this.ticket.id}/addSale`;
|
||||||
|
|
|
@ -659,7 +659,7 @@ describe('Ticket', () => {
|
||||||
jest.spyOn(controller, 'resetChanges').mockReturnThis();
|
jest.spyOn(controller, 'resetChanges').mockReturnThis();
|
||||||
|
|
||||||
const newSale = {itemFk: 4, quantity: 10};
|
const newSale = {itemFk: 4, quantity: 10};
|
||||||
const expectedParams = {itemId: 4, quantity: 10};
|
const expectedParams = {barcode: 4, quantity: 10};
|
||||||
const expectedResult = {
|
const expectedResult = {
|
||||||
id: 30,
|
id: 30,
|
||||||
quantity: 10,
|
quantity: 10,
|
||||||
|
|
|
@ -20,7 +20,7 @@ module.exports = Self => {
|
||||||
const notifications = await models.NotificationQueue.find(
|
const notifications = await models.NotificationQueue.find(
|
||||||
{where: {created: {gte: new Date(Date.vnNow() - (backupPrinterNotificationDelay * 1000))},
|
{where: {created: {gte: new Date(Date.vnNow() - (backupPrinterNotificationDelay * 1000))},
|
||||||
notificationFk: notificationName,
|
notificationFk: notificationName,
|
||||||
status: 'sent'
|
status: {neq: 'error'}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -54,8 +54,8 @@
|
||||||
<vn-autocomplete
|
<vn-autocomplete
|
||||||
ng-model="$ctrl.worker.originCountryFk"
|
ng-model="$ctrl.worker.originCountryFk"
|
||||||
url="Countries"
|
url="Countries"
|
||||||
fields="['id', 'country', 'code']"
|
fields="['id', 'name', 'code']"
|
||||||
show-field="country"
|
show-field="name"
|
||||||
value-field="id"
|
value-field="id"
|
||||||
label="Origin country">
|
label="Origin country">
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
|
|
|
@ -5,6 +5,7 @@ describe('zone deletezone()', () => {
|
||||||
const userId = 9;
|
const userId = 9;
|
||||||
const activeCtx = {
|
const activeCtx = {
|
||||||
accessToken: {userId: userId},
|
accessToken: {userId: userId},
|
||||||
|
__: value => value
|
||||||
};
|
};
|
||||||
const ctx = {req: activeCtx};
|
const ctx = {req: activeCtx};
|
||||||
const zoneId = 9;
|
const zoneId = 9;
|
||||||
|
@ -15,7 +16,6 @@ describe('zone deletezone()', () => {
|
||||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||||
active: activeCtx
|
active: activeCtx
|
||||||
});
|
});
|
||||||
try {
|
|
||||||
const originalTickets = await models.Ticket.find({
|
const originalTickets = await models.Ticket.find({
|
||||||
where: {
|
where: {
|
||||||
zoneFk: zoneId
|
zoneFk: zoneId
|
||||||
|
@ -25,9 +25,6 @@ describe('zone deletezone()', () => {
|
||||||
originalTicketStates = await models.TicketState.find({where: {
|
originalTicketStates = await models.TicketState.find({where: {
|
||||||
ticketFk: {inq: ticketIDs},
|
ticketFk: {inq: ticketIDs},
|
||||||
code: 'FIXING'}});
|
code: 'FIXING'}});
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should delete a zone and update their tickets', async() => {
|
it('should delete a zone and update their tickets', async() => {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "salix-back",
|
"name": "salix-back",
|
||||||
"version": "24.24.1",
|
"version": "24.24.3",
|
||||||
"author": "Verdnatura Levante SL",
|
"author": "Verdnatura Levante SL",
|
||||||
"description": "Salix backend",
|
"description": "Salix backend",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
|
|
Loading…
Reference in New Issue