Merge branch '1368-ticket_sale_refactor' of https://gitea.verdnatura.es/verdnatura/salix into 1368-ticket_sale_refactor
gitea/salix/pipeline/head There was a failure building this commit
Details
gitea/salix/pipeline/head There was a failure building this commit
Details
This commit is contained in:
commit
c801d8a969
|
@ -35,5 +35,5 @@ ENTRYPOINT ["docker-start.sh"]
|
||||||
|
|
||||||
CMD ["mysqld"]
|
CMD ["mysqld"]
|
||||||
|
|
||||||
#HEALTHCHECK --interval=5s --timeout=10s --retries=200 \
|
HEALTHCHECK --interval=5s --timeout=10s --retries=200 \
|
||||||
# CMD mysqladmin ping -h 127.0.0.1 -u root || exit 1
|
CMD mysqladmin ping -h 127.0.0.1 -u root || exit 1
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
|
|
||||||
VALUES
|
|
||||||
('WorkerDms', 'filter', 'READ', 'ALLOW', 'ROLE', 'employee'),
|
|
||||||
('WorkerDms', 'downloadFile', 'READ', 'ALLOW', 'ROLE', 'employee');
|
|
||||||
DELETE FROM `salix`.`ACL` WHERE (`id` = '205');
|
|
|
@ -1,119 +0,0 @@
|
||||||
USE `vn`;
|
|
||||||
DROP procedure IF EXISTS `zone_getEvents`;
|
|
||||||
|
|
||||||
DELIMITER $$
|
|
||||||
USE `vn`$$
|
|
||||||
CREATE DEFINER=`root`@`%` PROCEDURE `zone_getEvents`(
|
|
||||||
vGeoFk INT,
|
|
||||||
vAgencyModeFk INT)
|
|
||||||
BEGIN
|
|
||||||
/**
|
|
||||||
* Returns available events for the passed province/postcode and agency.
|
|
||||||
*
|
|
||||||
* @param vGeoFk The geo id
|
|
||||||
* @param vAgencyModeFk The agency mode id
|
|
||||||
*/
|
|
||||||
DECLARE vDeliveryMethodFk VARCHAR(255);
|
|
||||||
|
|
||||||
DROP TEMPORARY TABLE IF EXISTS tZone;
|
|
||||||
CREATE TEMPORARY TABLE tZone
|
|
||||||
(id INT PRIMARY KEY)
|
|
||||||
ENGINE = MEMORY;
|
|
||||||
|
|
||||||
SELECT dm.`code` INTO vDeliveryMethodFk
|
|
||||||
FROM agencyMode am
|
|
||||||
JOIN deliveryMethod dm ON dm.id = am.deliveryMethodFk
|
|
||||||
WHERE am.id = vAgencyModeFk;
|
|
||||||
|
|
||||||
IF vDeliveryMethodFk = 'PICKUP' THEN
|
|
||||||
INSERT INTO tZone
|
|
||||||
SELECT id
|
|
||||||
FROM zone
|
|
||||||
WHERE agencyModeFk = vAgencyModeFk;
|
|
||||||
ELSE
|
|
||||||
CALL zone_getFromGeo(vGeoFk);
|
|
||||||
|
|
||||||
IF vAgencyModeFk IS NOT NULL THEN
|
|
||||||
INSERT INTO tZone
|
|
||||||
SELECT t.id
|
|
||||||
FROM tmp.zone t
|
|
||||||
JOIN zone z ON z.id = t.id
|
|
||||||
WHERE z.agencyModeFk = vAgencyModeFk;
|
|
||||||
ELSE
|
|
||||||
INSERT INTO tZone
|
|
||||||
SELECT t.id
|
|
||||||
FROM tmp.zone t
|
|
||||||
JOIN zone z ON z.id = t.id
|
|
||||||
JOIN agencyMode am ON am.id = z.agencyModeFk
|
|
||||||
JOIN deliveryMethod dm ON dm.id = am.deliveryMethodFk
|
|
||||||
WHERE dm.`code` IN ('AGENCY', 'DELIVERY');
|
|
||||||
END IF;
|
|
||||||
DROP TEMPORARY TABLE tmp.zone;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
SELECT e.zoneFk, e.`type`, e.dated, e.`started`, e.`ended`, e.weekDays
|
|
||||||
FROM tZone t
|
|
||||||
JOIN zoneEvent e ON e.zoneFk = t.id;
|
|
||||||
|
|
||||||
SELECT e.zoneFk, e.dated
|
|
||||||
FROM tZone t
|
|
||||||
JOIN zoneExclusion e ON e.zoneFk = t.id;
|
|
||||||
|
|
||||||
DROP TEMPORARY TABLE tZone;
|
|
||||||
END$$
|
|
||||||
|
|
||||||
DELIMITER ;
|
|
||||||
|
|
||||||
USE `vn`;
|
|
||||||
DROP procedure IF EXISTS `zone_getEvents__`;
|
|
||||||
|
|
||||||
DELIMITER $$
|
|
||||||
USE `vn`$$
|
|
||||||
CREATE DEFINER=`root`@`%` PROCEDURE `zone_getEvents__`(
|
|
||||||
vProvinceFk INT,
|
|
||||||
vPostCode VARCHAR(255),
|
|
||||||
vAgencyModeFk INT)
|
|
||||||
BEGIN
|
|
||||||
/**
|
|
||||||
* Returns available events for the passed province/postcode and agency.
|
|
||||||
*
|
|
||||||
* @param vAgencyModeFk The agency mode id
|
|
||||||
* @param vProvinceFk The province id
|
|
||||||
* @param vPostCode The postcode or %NULL to use the province
|
|
||||||
*/
|
|
||||||
|
|
||||||
DECLARE vGeoFk INT;
|
|
||||||
|
|
||||||
IF vPostCode IS NOT NULL THEN
|
|
||||||
SELECT p.geoFk INTO vGeoFk
|
|
||||||
FROM postCode p
|
|
||||||
JOIN town t ON t.id = p.townFk
|
|
||||||
WHERE p.`code` = vPostCode
|
|
||||||
AND t.provinceFk = vProvinceFk;
|
|
||||||
ELSE
|
|
||||||
SELECT geoFk INTO vGeoFk
|
|
||||||
FROM province
|
|
||||||
WHERE id = vProvinceFk;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
CALL zone_getFromGeo(vGeoFk);
|
|
||||||
|
|
||||||
IF vAgencyModeFk IS NOT NULL THEN
|
|
||||||
DELETE t FROM tmp.zone t
|
|
||||||
JOIN zone z ON z.id = t.id
|
|
||||||
WHERE z.agencyModeFk != vAgencyModeFk;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
SELECT e.zoneFk, e.`type`, e.dated, e.`started`, e.`ended`, e.weekDays
|
|
||||||
FROM tmp.zone t
|
|
||||||
JOIN zoneEvent e ON e.zoneFk = t.id;
|
|
||||||
|
|
||||||
SELECT e.zoneFk, e.dated
|
|
||||||
FROM tmp.zone t
|
|
||||||
JOIN zoneExclusion e ON e.zoneFk = t.id;
|
|
||||||
|
|
||||||
DROP TEMPORARY TABLE tmp.zone;
|
|
||||||
END$$
|
|
||||||
|
|
||||||
DELIMITER ;
|
|
||||||
|
|
|
@ -1,87 +0,0 @@
|
||||||
USE `vn`;
|
|
||||||
DROP procedure IF EXISTS `zone_getWarehouse`;
|
|
||||||
|
|
||||||
DELIMITER $$
|
|
||||||
USE `vn`$$
|
|
||||||
CREATE DEFINER=`root`@`%` PROCEDURE `zone_getWarehouse`(vAddress INT, vLanded DATE, vWarehouse INT)
|
|
||||||
BEGIN
|
|
||||||
/**
|
|
||||||
* Devuelve el listado de agencias disponibles para la fecha,
|
|
||||||
* dirección y almacén pasados.
|
|
||||||
*
|
|
||||||
* @param vAddress
|
|
||||||
* @param vWarehouse warehouse
|
|
||||||
* @param vLanded Fecha de recogida
|
|
||||||
* @select Listado de agencias disponibles
|
|
||||||
*/
|
|
||||||
|
|
||||||
CALL zone_getFromGeo(address_getGeo(vAddress));
|
|
||||||
CALL zone_getOptionsForLanding(vLanded, FALSE);
|
|
||||||
|
|
||||||
SELECT am.id agencyModeFk,
|
|
||||||
am.name agencyMode,
|
|
||||||
am.description,
|
|
||||||
am.deliveryMethodFk,
|
|
||||||
TIMESTAMPADD(DAY, -zo.travelingDays, vLanded) shipped,
|
|
||||||
zw.warehouseFk,
|
|
||||||
z.id zoneFk
|
|
||||||
FROM tmp.zoneOption zo
|
|
||||||
JOIN zone z ON z.id = zo.zoneFk
|
|
||||||
JOIN agencyMode am ON am.id = z.agencyModeFk
|
|
||||||
JOIN zoneWarehouse zw ON zw.zoneFk = zo.zoneFk
|
|
||||||
WHERE zw.warehouseFk = vWarehouse
|
|
||||||
GROUP BY z.agencyModeFk
|
|
||||||
ORDER BY agencyMode;
|
|
||||||
|
|
||||||
DROP TEMPORARY TABLE
|
|
||||||
tmp.zone,
|
|
||||||
tmp.zoneOption;
|
|
||||||
|
|
||||||
END$$
|
|
||||||
|
|
||||||
DELIMITER ;
|
|
||||||
|
|
||||||
USE `vn`;
|
|
||||||
DROP procedure IF EXISTS `zone_getWarehouse__`;
|
|
||||||
|
|
||||||
DELIMITER $$
|
|
||||||
USE `vn`$$
|
|
||||||
CREATE DEFINER=`root`@`%` PROCEDURE `zone_getWarehouse__`(vAddress INT, vLanded DATE, vWarehouse INT)
|
|
||||||
BEGIN
|
|
||||||
/**
|
|
||||||
* Devuelve el listado de agencias disponibles para la fecha,
|
|
||||||
* dirección y almacén pasados.
|
|
||||||
*
|
|
||||||
* @param vAddress
|
|
||||||
* @param vWarehouse warehouse
|
|
||||||
* @param vLanded Fecha de recogida
|
|
||||||
* @select Listado de agencias disponibles
|
|
||||||
*/
|
|
||||||
|
|
||||||
CALL zone_getFromGeo(address_getGeo(vAddress));
|
|
||||||
CALL zone_getOptionsForLanding(vLanded, FALSE);
|
|
||||||
|
|
||||||
SELECT am.id agencyModeFk,
|
|
||||||
am.name agencyMode,
|
|
||||||
am.description,
|
|
||||||
am.deliveryMethodFk,
|
|
||||||
TIMESTAMPADD(DAY, -zo.travelingDays, vLanded) shipped,
|
|
||||||
zw.warehouseFk,
|
|
||||||
z.id zoneFk
|
|
||||||
FROM tmp.zoneOption zo
|
|
||||||
JOIN zone z ON z.id = zo.zoneFk
|
|
||||||
JOIN agencyMode am ON am.id = z.agencyModeFk
|
|
||||||
JOIN zoneWarehouse zw ON zw.zoneFk = zo.zoneFk
|
|
||||||
WHERE zw.warehouseFk
|
|
||||||
GROUP BY z.agencyModeFk
|
|
||||||
ORDER BY agencyMode;
|
|
||||||
|
|
||||||
DROP TEMPORARY TABLE
|
|
||||||
tmp.zone,
|
|
||||||
tmp.zoneOption;
|
|
||||||
|
|
||||||
END$$
|
|
||||||
|
|
||||||
DELIMITER ;
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
UPDATE `salix`.`ACL` SET `accessType`='WRITE' WHERE `id`='213';
|
UPDATE `salix`.`ACL` SET `accessType`='WRITE' WHERE `id`='213';
|
||||||
|
UPDATE `salix`.`ACL` SET `property` = 'deleteSales' WHERE (`id` = '80');
|
||||||
|
|
||||||
INSERT IGNORE INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('CustomsAgent', '*', '*', 'ALLOW', 'ROLE', 'employee');
|
INSERT IGNORE INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('CustomsAgent', '*', '*', 'ALLOW', 'ROLE', 'employee');
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
/*
|
||||||
|
Hay una versión en salix que machacará toda esta función/procedimiento
|
||||||
|
avisa a ___ de los cambios que quieres hacer
|
||||||
|
*/
|
|
@ -39,8 +39,7 @@ module.exports = class Docker {
|
||||||
|
|
||||||
let runChown = process.platform != 'linux';
|
let runChown = process.platform != 'linux';
|
||||||
|
|
||||||
const healthCheck = `--health-cmd='mysqladmin ping --silent'`;
|
const container = await this.execP(`docker run --env RUN_CHOWN=${runChown} -d ${dockerArgs} salix-db`);
|
||||||
const container = await this.execP(`docker run ${healthCheck} --env RUN_CHOWN=${runChown} -d ${dockerArgs} salix-db`);
|
|
||||||
this.id = container.stdout;
|
this.id = container.stdout;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -54,7 +53,7 @@ module.exports = class Docker {
|
||||||
this.dbConf.port = netSettings.Ports['3306/tcp'][0]['HostPort'];
|
this.dbConf.port = netSettings.Ports['3306/tcp'][0]['HostPort'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (runChown) await this.wait();
|
await this.waitForHealthy();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (this.isRandom)
|
if (this.isRandom)
|
||||||
await this.rm();
|
await this.rm();
|
||||||
|
|
|
@ -1455,6 +1455,9 @@ INSERT INTO `vn`.`clientContact`(`id`, `clientFk`, `name`, `phone`)
|
||||||
(3, 101, 'contact 3', 222333444),
|
(3, 101, 'contact 3', 222333444),
|
||||||
(4, 102, 'contact 1', 876543219);
|
(4, 102, 'contact 1', 876543219);
|
||||||
|
|
||||||
|
INSERT INTO `vn`.`workerManaExcluded`(`workerFk`)
|
||||||
|
VALUES
|
||||||
|
(9);
|
||||||
/*
|
/*
|
||||||
el mana de los trabajadores lo podemos poner a mano en la tabla si lo calculamos antes,
|
el mana de los trabajadores lo podemos poner a mano en la tabla si lo calculamos antes,
|
||||||
pero si hazemos alguna modificacion en alguna tabla que utiliza para calcularlo ya no seria correcto
|
pero si hazemos alguna modificacion en alguna tabla que utiliza para calcularlo ya no seria correcto
|
||||||
|
|
|
@ -83,8 +83,6 @@ async function backTestOnce(done) {
|
||||||
port: container.dbConf.port
|
port: container.dbConf.port
|
||||||
});
|
});
|
||||||
|
|
||||||
log('[Debug] dataSources', dataSources.vn);
|
|
||||||
|
|
||||||
let bootOptions = {dataSources};
|
let bootOptions = {dataSources};
|
||||||
|
|
||||||
let app = require(`./loopback/server/server`);
|
let app = require(`./loopback/server/server`);
|
||||||
|
@ -92,8 +90,6 @@ async function backTestOnce(done) {
|
||||||
try {
|
try {
|
||||||
app.boot(bootOptions);
|
app.boot(bootOptions);
|
||||||
|
|
||||||
log('[Debug] back started');
|
|
||||||
|
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
const jasmine = require('gulp-jasmine');
|
const jasmine = require('gulp-jasmine');
|
||||||
|
|
||||||
|
|
|
@ -67,5 +67,6 @@
|
||||||
"Customs agent is required for a non UEE member": "Customs agent is required for a non UEE member",
|
"Customs agent is required for a non UEE member": "Customs agent is required for a non UEE member",
|
||||||
"Incoterms is required for a non UEE member": "Incoterms is required for a non UEE member",
|
"Incoterms is required for a non UEE member": "Incoterms is required for a non UEE member",
|
||||||
"Client checked as validated despite of duplication": "Client checked as validated despite of duplication from client id {{clientId}}",
|
"Client checked as validated despite of duplication": "Client checked as validated despite of duplication from client id {{clientId}}",
|
||||||
"Landing cannot be lesser than shipment": "Landing cannot be lesser than shipment"
|
"Landing cannot be lesser than shipment": "Landing cannot be lesser than shipment",
|
||||||
|
"NOT_ZONE_WITH_THIS_PARAMETERS": "NOT_ZONE_WITH_THIS_PARAMETERS"
|
||||||
}
|
}
|
|
@ -4,17 +4,15 @@ module.exports = Self => {
|
||||||
Self.remoteMethodCtx('createFromSales', {
|
Self.remoteMethodCtx('createFromSales', {
|
||||||
description: 'Create a claim',
|
description: 'Create a claim',
|
||||||
accepts: [{
|
accepts: [{
|
||||||
arg: 'claim',
|
arg: 'ticketId',
|
||||||
type: 'object',
|
type: 'Number',
|
||||||
required: true,
|
required: true,
|
||||||
description: ' newTicketFk, clientFk, ticketCreated',
|
description: 'The origin ticket id'
|
||||||
http: {source: 'body'}
|
|
||||||
}, {
|
}, {
|
||||||
arg: 'sales',
|
arg: 'sales',
|
||||||
type: 'object',
|
type: ['Object'],
|
||||||
required: true,
|
required: true,
|
||||||
description: '[sales IDs]',
|
description: 'The claimed sales'
|
||||||
http: {source: 'body'}
|
|
||||||
}],
|
}],
|
||||||
returns: {
|
returns: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
@ -26,28 +24,27 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.createFromSales = async(ctx, params) => {
|
Self.createFromSales = async(ctx, ticketId, sales) => {
|
||||||
let models = Self.app.models;
|
const models = Self.app.models;
|
||||||
let userId = ctx.req.accessToken.userId;
|
const userId = ctx.req.accessToken.userId;
|
||||||
let tx = await Self.beginTransaction({});
|
const tx = await Self.beginTransaction({});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let options = {transaction: tx};
|
let options = {transaction: tx};
|
||||||
|
|
||||||
const ticketId = params.claim.ticketFk;
|
|
||||||
const ticket = await models.Ticket.findById(ticketId, null, options);
|
const ticket = await models.Ticket.findById(ticketId, null, options);
|
||||||
if (ticket.isDeleted)
|
if (ticket.isDeleted)
|
||||||
throw new UserError(`You can't create a claim for a removed ticket`);
|
throw new UserError(`You can't create a claim for a removed ticket`);
|
||||||
|
|
||||||
const worker = await models.Worker.findOne({
|
const newClaim = await Self.create({
|
||||||
where: {userFk: userId}
|
ticketFk: ticketId,
|
||||||
|
clientFk: ticket.clientFk,
|
||||||
|
ticketCreated: ticket.shipped,
|
||||||
|
workerFk: userId
|
||||||
}, options);
|
}, options);
|
||||||
|
const promises = [];
|
||||||
|
|
||||||
params.claim.workerFk = worker.id;
|
for (const sale of sales) {
|
||||||
let newClaim = await Self.create(params.claim, options);
|
|
||||||
let promises = [];
|
|
||||||
|
|
||||||
for (const sale of params.sales) {
|
|
||||||
const newClaimBeginning = models.ClaimBeginning.create({
|
const newClaimBeginning = models.ClaimBeginning.create({
|
||||||
saleFk: sale.id,
|
saleFk: sale.id,
|
||||||
claimFk: newClaim.id,
|
claimFk: newClaim.id,
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const app = require('vn-loopback/server/server');
|
||||||
|
|
||||||
describe('Claim Create', () => {
|
describe('Claim createFromSales()', () => {
|
||||||
let newDate = new Date();
|
|
||||||
let createdClaimFk;
|
let createdClaimFk;
|
||||||
|
|
||||||
afterAll(async done => {
|
afterAll(async done => {
|
||||||
|
@ -10,28 +9,18 @@ describe('Claim Create', () => {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
let newClaim = {
|
const ticketId = 2;
|
||||||
ticketFk: 2,
|
const newSale = [{
|
||||||
clientFk: 101,
|
|
||||||
ticketCreated: newDate
|
|
||||||
};
|
|
||||||
|
|
||||||
let newSale = [{
|
|
||||||
id: 3,
|
id: 3,
|
||||||
instance: 0,
|
instance: 0,
|
||||||
quantity: 10
|
quantity: 10
|
||||||
}];
|
}];
|
||||||
|
const ctx = {req: {accessToken: {userId: 1}}};
|
||||||
let params = {claim: newClaim, sales: newSale};
|
|
||||||
let ctx = {req: {accessToken: {userId: 1}}};
|
|
||||||
|
|
||||||
it('should create a new claim', async() => {
|
it('should create a new claim', async() => {
|
||||||
let claim = await app.models.Claim.createFromSales(ctx, params);
|
let claim = await app.models.Claim.createFromSales(ctx, ticketId, newSale);
|
||||||
|
|
||||||
expect(claim.ticketFk).toEqual(newClaim.ticketFk);
|
expect(claim.ticketFk).toEqual(ticketId);
|
||||||
expect(claim.clientFk).toEqual(newClaim.clientFk);
|
|
||||||
expect(claim.ticketCreated).toEqual(newClaim.ticketCreated);
|
|
||||||
expect(claim.workerFk).toEqual(newClaim.workerFk);
|
|
||||||
|
|
||||||
let claimBeginning = await app.models.ClaimBeginning.findOne({where: {claimFk: claim.id}});
|
let claimBeginning = await app.models.ClaimBeginning.findOne({where: {claimFk: claim.id}});
|
||||||
|
|
||||||
|
@ -44,7 +33,7 @@ describe('Claim Create', () => {
|
||||||
it('should not be able to create a claim if exists that sale', async() => {
|
it('should not be able to create a claim if exists that sale', async() => {
|
||||||
let error;
|
let error;
|
||||||
|
|
||||||
await app.models.Claim.createFromSales(ctx, params)
|
await app.models.Claim.createFromSales(ctx, ticketId, newSale)
|
||||||
|
|
||||||
.catch(e => {
|
.catch(e => {
|
||||||
error = e;
|
error = e;
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
let UserError = require('vn-loopback/util/user-error');
|
||||||
|
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethodCtx('deleteSales', {
|
||||||
|
description: 'Deletes the selected sales',
|
||||||
|
accessType: 'WRITE',
|
||||||
|
accepts: [{
|
||||||
|
arg: 'sales',
|
||||||
|
type: ['Object'],
|
||||||
|
required: true,
|
||||||
|
description: 'The sales to remove'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'ticketId',
|
||||||
|
type: 'Number',
|
||||||
|
required: true,
|
||||||
|
description: 'The ticket id'
|
||||||
|
}],
|
||||||
|
returns: {
|
||||||
|
type: ['Object'],
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/deleteSales`,
|
||||||
|
verb: 'POST'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.deleteSales = async(ctx, sales, ticketId) => {
|
||||||
|
const models = Self.app.models;
|
||||||
|
const isTicketEditable = await models.Ticket.isEditable(ctx, ticketId);
|
||||||
|
if (!isTicketEditable)
|
||||||
|
throw new UserError(`The sales of this ticket can't be modified`);
|
||||||
|
|
||||||
|
const promises = [];
|
||||||
|
for (let sale of sales) {
|
||||||
|
const deletedSale = models.Sale.destroyById(sale.id);
|
||||||
|
promises.push(deletedSale);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.all(promises);
|
||||||
|
};
|
||||||
|
};
|
|
@ -1,35 +0,0 @@
|
||||||
let UserError = require('vn-loopback/util/user-error');
|
|
||||||
|
|
||||||
module.exports = Self => {
|
|
||||||
Self.remoteMethodCtx('removes', {
|
|
||||||
description: 'Change the state of a ticket',
|
|
||||||
accessType: 'WRITE',
|
|
||||||
accepts: [{
|
|
||||||
arg: 'params',
|
|
||||||
type: 'object',
|
|
||||||
required: true,
|
|
||||||
description: '[sales IDs], actualTicketFk',
|
|
||||||
http: {source: 'body'}
|
|
||||||
}],
|
|
||||||
returns: {
|
|
||||||
type: 'string',
|
|
||||||
root: true
|
|
||||||
},
|
|
||||||
http: {
|
|
||||||
path: `/removes`,
|
|
||||||
verb: 'post'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Self.removes = async(ctx, params) => {
|
|
||||||
let thisTicketIsEditable = await Self.app.models.Ticket.isEditable(ctx, params.actualTicketFk);
|
|
||||||
if (!thisTicketIsEditable)
|
|
||||||
throw new UserError(`The sales of this ticket can't be modified`);
|
|
||||||
|
|
||||||
let promises = [];
|
|
||||||
for (let i = 0; i < params.sales.length; i++)
|
|
||||||
promises.push(Self.app.models.Sale.destroyById(params.sales[i].id));
|
|
||||||
|
|
||||||
return Promise.all(promises);
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -6,28 +6,43 @@ module.exports = Self => {
|
||||||
description: 'Change the state of a ticket',
|
description: 'Change the state of a ticket',
|
||||||
accessType: 'WRITE',
|
accessType: 'WRITE',
|
||||||
accepts: [{
|
accepts: [{
|
||||||
arg: 'params',
|
arg: 'ticketId',
|
||||||
type: 'object',
|
type: 'Number',
|
||||||
required: true,
|
required: true,
|
||||||
description: '[sales IDs], ticketFk, reserved',
|
description: 'The ticket id'
|
||||||
http: {source: 'body'}
|
}, {
|
||||||
|
arg: 'sales',
|
||||||
|
type: ['Object'],
|
||||||
|
required: true,
|
||||||
|
description: 'The sale to reserve'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'reserved',
|
||||||
|
type: 'Boolean',
|
||||||
|
required: true
|
||||||
}],
|
}],
|
||||||
returns: {
|
returns: {
|
||||||
type: 'string',
|
type: ['Object'],
|
||||||
root: true
|
root: true
|
||||||
},
|
},
|
||||||
http: {
|
http: {
|
||||||
path: `/reserve`,
|
path: `/reserve`,
|
||||||
verb: 'post'
|
verb: 'POST'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.reserve = async(ctx, params) => {
|
Self.reserve = async(ctx, ticketId, sales, reserved) => {
|
||||||
let thisTicketIsEditable = await Self.app.models.Ticket.isEditable(ctx, params.ticketFk);
|
const models = Self.app.models;
|
||||||
if (!thisTicketIsEditable)
|
const isTicketEditable = await models.Ticket.isEditable(ctx, ticketId);
|
||||||
|
if (!isTicketEditable)
|
||||||
throw new UserError(`The sales of this ticket can't be modified`);
|
throw new UserError(`The sales of this ticket can't be modified`);
|
||||||
|
|
||||||
for (let i = 0; i < params.sales.length; i++)
|
const promises = [];
|
||||||
await Self.app.models.Sale.update({id: params.sales[i].id}, {reserved: params.reserved});
|
for (let sale of sales) {
|
||||||
|
const reservedSale = models.Sale.update({id: sale.id}, {reserved: reserved});
|
||||||
|
promises.push(reservedSale);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.all(promises);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const app = require('vn-loopback/server/server');
|
||||||
|
|
||||||
describe('sale removes()', () => {
|
describe('sale deleteSales()', () => {
|
||||||
let sale;
|
let sale;
|
||||||
let newsale;
|
let newsale;
|
||||||
|
|
||||||
|
@ -16,13 +16,11 @@ describe('sale removes()', () => {
|
||||||
let ctx = {req: {accessToken: {userId: 9}}};
|
let ctx = {req: {accessToken: {userId: 9}}};
|
||||||
let error;
|
let error;
|
||||||
|
|
||||||
let params = {
|
const sales = [{id: 1, instance: 0}, {id: 2, instance: 1}];
|
||||||
sales: [{id: 1, instance: 0}, {id: 2, instance: 1}],
|
const ticketId = 2;
|
||||||
actualTicketFk: 2
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await app.models.Sale.removes(ctx, params);
|
await app.models.Sale.deleteSales(ctx, sales, ticketId);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
error = e;
|
error = e;
|
||||||
}
|
}
|
||||||
|
@ -32,12 +30,11 @@ describe('sale removes()', () => {
|
||||||
|
|
||||||
it('should delete the sales', async() => {
|
it('should delete the sales', async() => {
|
||||||
let ctx = {req: {accessToken: {userId: 9}}};
|
let ctx = {req: {accessToken: {userId: 9}}};
|
||||||
let params = {
|
|
||||||
sales: [{id: newsale.id, instance: 0}],
|
|
||||||
actualTicketFk: 16
|
|
||||||
};
|
|
||||||
|
|
||||||
let res = await app.models.Sale.removes(ctx, params);
|
const sales = [{id: newsale.id, instance: 0}];
|
||||||
|
const ticketId = 16;
|
||||||
|
|
||||||
|
let res = await app.models.Sale.deleteSales(ctx, sales, ticketId);
|
||||||
|
|
||||||
expect(res).toEqual([{count: 1}]);
|
expect(res).toEqual([{count: 1}]);
|
||||||
});
|
});
|
|
@ -1,6 +1,7 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const app = require('vn-loopback/server/server');
|
||||||
|
|
||||||
describe('sale reserve()', () => {
|
describe('sale reserve()', () => {
|
||||||
|
const ctx = {req: {accessToken: {userId: 9}}};
|
||||||
afterAll(async done => {
|
afterAll(async done => {
|
||||||
let ctx = {req: {accessToken: {userId: 9}}};
|
let ctx = {req: {accessToken: {userId: 9}}};
|
||||||
let params = {
|
let params = {
|
||||||
|
@ -17,13 +18,12 @@ describe('sale reserve()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error if the ticket can not be modified', async() => {
|
it('should throw an error if the ticket can not be modified', async() => {
|
||||||
let ctx = {req: {accessToken: {userId: 9}}};
|
|
||||||
let error;
|
let error;
|
||||||
let params = {ticketFk: 2,
|
const ticketId = 2;
|
||||||
sales: [{id: 5}],
|
const sales = [{id: 5}];
|
||||||
reserved: false};
|
const reserved = false;
|
||||||
|
|
||||||
await app.models.Sale.reserve(ctx, params)
|
await app.models.Sale.reserve(ctx, ticketId, sales, reserved)
|
||||||
.catch(response => {
|
.catch(response => {
|
||||||
expect(response).toEqual(new Error(`The sales of this ticket can't be modified`));
|
expect(response).toEqual(new Error(`The sales of this ticket can't be modified`));
|
||||||
error = response;
|
error = response;
|
||||||
|
@ -38,18 +38,13 @@ describe('sale reserve()', () => {
|
||||||
expect(originalTicketSales[0].reserved).toEqual(0);
|
expect(originalTicketSales[0].reserved).toEqual(0);
|
||||||
expect(originalTicketSales[1].reserved).toEqual(0);
|
expect(originalTicketSales[1].reserved).toEqual(0);
|
||||||
|
|
||||||
let ctx = {req: {accessToken: {userId: 9}}};
|
const ticketId = 11;
|
||||||
let params = {
|
const sales = [{id: 7}, {id: 8}];
|
||||||
sales: [
|
const reserved = true;
|
||||||
{id: 7},
|
|
||||||
{id: 8}],
|
|
||||||
ticketFk: 11,
|
|
||||||
reserved: true
|
|
||||||
};
|
|
||||||
|
|
||||||
await app.models.Sale.reserve(ctx, params);
|
await app.models.Sale.reserve(ctx, ticketId, sales, reserved);
|
||||||
|
|
||||||
let reservedTicketSales = await app.models.Ticket.getSales(11);
|
const reservedTicketSales = await app.models.Ticket.getSales(ticketId);
|
||||||
|
|
||||||
expect(reservedTicketSales[0].reserved).toEqual(1);
|
expect(reservedTicketSales[0].reserved).toEqual(1);
|
||||||
expect(reservedTicketSales[1].reserved).toEqual(1);
|
expect(reservedTicketSales[1].reserved).toEqual(1);
|
||||||
|
|
|
@ -56,7 +56,9 @@ module.exports = Self => {
|
||||||
throw new UserError(`The sales of this ticket can't be modified`);
|
throw new UserError(`The sales of this ticket can't be modified`);
|
||||||
|
|
||||||
const userId = ctx.req.accessToken.userId;
|
const userId = ctx.req.accessToken.userId;
|
||||||
|
|
||||||
let usesMana = await models.WorkerMana.findOne({where: {workerFk: userId}, fields: 'amount'}, options);
|
let usesMana = await models.WorkerMana.findOne({where: {workerFk: userId}, fields: 'amount'}, options);
|
||||||
|
|
||||||
let componentCode = usesMana ? 'mana' : 'buyerDiscount';
|
let componentCode = usesMana ? 'mana' : 'buyerDiscount';
|
||||||
|
|
||||||
let discount = await models.Component.findOne({where: {code: componentCode}}, options);
|
let discount = await models.Component.findOne({where: {code: componentCode}}, options);
|
||||||
|
@ -80,7 +82,6 @@ module.exports = Self => {
|
||||||
value: componentValue
|
value: componentValue
|
||||||
}, options);
|
}, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
await sale.updateAttributes({price: newPrice}, options);
|
await sale.updateAttributes({price: newPrice}, options);
|
||||||
|
|
||||||
query = `CALL vn.manaSpellersRequery(?)`;
|
query = `CALL vn.manaSpellersRequery(?)`;
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
Self.remoteMethod('getSalesPersonMana', {
|
Self.remoteMethod('getSalesPersonMana', {
|
||||||
description: 'Returns mana of a salesperson of a ticket',
|
description: 'Returns the mana amount of a salesperson for a ticket',
|
||||||
accessType: 'READ',
|
accessType: 'READ',
|
||||||
accepts: [{
|
accepts: [{
|
||||||
arg: 'id',
|
arg: 'id',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
required: true,
|
required: true,
|
||||||
description: 'ticket id',
|
description: 'The ticket id',
|
||||||
http: {source: 'path'}
|
http: {source: 'path'}
|
||||||
}],
|
}],
|
||||||
returns: {
|
returns: {
|
||||||
|
@ -18,8 +18,9 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.getSalesPersonMana = async ticketFk => {
|
Self.getSalesPersonMana = async ticketId => {
|
||||||
let ticket = await Self.app.models.Ticket.findById(ticketFk, {
|
const models = Self.app.models;
|
||||||
|
const ticket = await models.Ticket.findById(ticketId, {
|
||||||
include: [{
|
include: [{
|
||||||
relation: 'client',
|
relation: 'client',
|
||||||
scope: {
|
scope: {
|
||||||
|
@ -29,10 +30,12 @@ module.exports = Self => {
|
||||||
fields: ['id', 'clientFk']
|
fields: ['id', 'clientFk']
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!ticket)
|
if (!ticket) return 0;
|
||||||
return 0;
|
|
||||||
|
|
||||||
let mana = await Self.app.models.WorkerMana.findOne({where: {workerFk: ticket.client().salesPersonFk}, fields: 'amount'});
|
const mana = await models.WorkerMana.findOne({
|
||||||
|
where: {
|
||||||
|
workerFk: ticket.client().salesPersonFk
|
||||||
|
}, fields: 'amount'});
|
||||||
|
|
||||||
return mana ? mana.amount : 0;
|
return mana ? mana.amount : 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,7 +8,7 @@ describe('sale updateDiscount()', () => {
|
||||||
|
|
||||||
beforeAll(async done => {
|
beforeAll(async done => {
|
||||||
originalSale = await app.models.Sale.findById(originalSaleId);
|
originalSale = await app.models.Sale.findById(originalSaleId);
|
||||||
let manaDiscount = await app.models.Component.findOne({where: {code: 'mana'}});
|
let manaDiscount = await app.models.Component.findOne({where: {code: 'buyerDiscount'}});
|
||||||
componentId = manaDiscount.id;
|
componentId = manaDiscount.id;
|
||||||
|
|
||||||
let ticket = await app.models.Ticket.findById(originalSale.ticketFk);
|
let ticket = await app.models.Ticket.findById(originalSale.ticketFk);
|
||||||
|
@ -26,7 +26,6 @@ describe('sale updateDiscount()', () => {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it('should throw an error if no sales were selected', async() => {
|
it('should throw an error if no sales were selected', async() => {
|
||||||
let ctx = {req: {accessToken: {userId: 9}}};
|
let ctx = {req: {accessToken: {userId: 9}}};
|
||||||
let error;
|
let error;
|
||||||
|
@ -76,6 +75,28 @@ describe('sale updateDiscount()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update the discount if the salesPerson has mana', async() => {
|
it('should update the discount if the salesPerson has mana', async() => {
|
||||||
|
let ctx = {req: {accessToken: {userId: 18}}};
|
||||||
|
const ticketId = 11;
|
||||||
|
const sales = [originalSaleId];
|
||||||
|
const newDiscount = 100;
|
||||||
|
let manaDiscount = await app.models.Component.findOne({where: {code: 'mana'}});
|
||||||
|
componentId = manaDiscount.id;
|
||||||
|
|
||||||
|
await app.models.Ticket.updateDiscount(ctx, ticketId, sales, newDiscount);
|
||||||
|
|
||||||
|
let updatedSale = await app.models.Sale.findById(originalSaleId);
|
||||||
|
let createdSaleComponent = await app.models.SaleComponent.findOne({
|
||||||
|
where: {
|
||||||
|
componentFk: componentId,
|
||||||
|
saleFk: originalSaleId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(createdSaleComponent.componentFk).toEqual(componentId);
|
||||||
|
expect(updatedSale.discount).toEqual(100);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update the discount and add company discount component if the worker does not have mana', async() => {
|
||||||
let ctx = {req: {accessToken: {userId: 9}}};
|
let ctx = {req: {accessToken: {userId: 9}}};
|
||||||
const ticketId = 11;
|
const ticketId = 11;
|
||||||
const sales = [originalSaleId];
|
const sales = [originalSaleId];
|
||||||
|
|
|
@ -35,7 +35,6 @@ module.exports = Self => {
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.updateDiscount = async(ctx, id, salesIds, newDiscount) => {
|
Self.updateDiscount = async(ctx, id, salesIds, newDiscount) => {
|
||||||
const userId = ctx.req.accessToken.userId;
|
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
const tx = await Self.beginTransaction({});
|
const tx = await Self.beginTransaction({});
|
||||||
|
|
||||||
|
@ -69,6 +68,7 @@ module.exports = Self => {
|
||||||
if (!allFromSameTicket)
|
if (!allFromSameTicket)
|
||||||
throw new UserError('All sales must belong to the same ticket');
|
throw new UserError('All sales must belong to the same ticket');
|
||||||
|
|
||||||
|
const userId = ctx.req.accessToken.userId;
|
||||||
const isLocked = await models.Ticket.isLocked(id);
|
const isLocked = await models.Ticket.isLocked(id);
|
||||||
const isSalesPerson = await models.Account.hasRole(userId, 'salesPerson');
|
const isSalesPerson = await models.Account.hasRole(userId, 'salesPerson');
|
||||||
const state = await Self.app.models.TicketState.findOne({
|
const state = await Self.app.models.TicketState.findOne({
|
||||||
|
@ -79,18 +79,9 @@ module.exports = Self => {
|
||||||
if (isLocked || (!isSalesPerson && alertLevel > 0))
|
if (isLocked || (!isSalesPerson && alertLevel > 0))
|
||||||
throw new UserError(`The sales of this ticket can't be modified`);
|
throw new UserError(`The sales of this ticket can't be modified`);
|
||||||
|
|
||||||
const ticket = await models.Ticket.findById(id, {
|
|
||||||
include: {
|
|
||||||
relation: 'client',
|
|
||||||
scope: {
|
|
||||||
fields: ['salesPersonFk']
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}, options);
|
|
||||||
const salesPersonId = ticket.client().salesPersonFk;
|
|
||||||
const usesMana = await models.WorkerMana.findOne({
|
const usesMana = await models.WorkerMana.findOne({
|
||||||
where: {
|
where: {
|
||||||
workerFk: salesPersonId
|
workerFk: userId
|
||||||
},
|
},
|
||||||
fields: 'amount'}, options);
|
fields: 'amount'}, options);
|
||||||
|
|
||||||
|
@ -99,7 +90,6 @@ module.exports = Self => {
|
||||||
where: {code: componentCode}}, options);
|
where: {code: componentCode}}, options);
|
||||||
|
|
||||||
const componentId = discountComponent.id;
|
const componentId = discountComponent.id;
|
||||||
|
|
||||||
let promises = [];
|
let promises = [];
|
||||||
for (let sale of sales) {
|
for (let sale of sales) {
|
||||||
const value = ((-sale.price * newDiscount) / 100);
|
const value = ((-sale.price * newDiscount) / 100);
|
||||||
|
@ -115,10 +105,8 @@ module.exports = Self => {
|
||||||
|
|
||||||
await Promise.all(promises);
|
await Promise.all(promises);
|
||||||
|
|
||||||
if (salesPersonId) {
|
const query = `call vn.manaSpellersRequery(?)`;
|
||||||
const query = `call vn.manaSpellersRequery(?)`;
|
await Self.rawSql(query, [userId], options);
|
||||||
await Self.rawSql(query, [salesPersonId], options);
|
|
||||||
}
|
|
||||||
|
|
||||||
await tx.commit();
|
await tx.commit();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
require('../methods/sale/getClaimableFromTicket')(Self);
|
require('../methods/sale/getClaimableFromTicket')(Self);
|
||||||
require('../methods/sale/reserve')(Self);
|
require('../methods/sale/reserve')(Self);
|
||||||
require('../methods/sale/removes')(Self);
|
require('../methods/sale/deleteSales')(Self);
|
||||||
require('../methods/sale/updatePrice')(Self);
|
require('../methods/sale/updatePrice')(Self);
|
||||||
require('../methods/sale/updateQuantity')(Self);
|
require('../methods/sale/updateQuantity')(Self);
|
||||||
require('../methods/sale/updateConcept')(Self);
|
require('../methods/sale/updateConcept')(Self);
|
||||||
|
|
|
@ -18,7 +18,6 @@ import './expedition';
|
||||||
import './volume';
|
import './volume';
|
||||||
import './package/index';
|
import './package/index';
|
||||||
import './sale';
|
import './sale';
|
||||||
import './sale/editDiscount';
|
|
||||||
import './tracking/index';
|
import './tracking/index';
|
||||||
import './tracking/edit';
|
import './tracking/edit';
|
||||||
import './sale-checked';
|
import './sale-checked';
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
<section class="header vn-pa-md">
|
|
||||||
<h5>MANÁ: {{$ctrl.mana | currency: 'EUR':0}}</h5>
|
|
||||||
</section>
|
|
||||||
<div class="vn-pa-md">
|
|
||||||
<vn-input-number
|
|
||||||
vn-focus
|
|
||||||
label="Discount"
|
|
||||||
ng-model="$ctrl.newDiscount"
|
|
||||||
on-change="$ctrl.updateDiscount()"
|
|
||||||
suffix="%">
|
|
||||||
</vn-input-number>
|
|
||||||
<div class="simulator">
|
|
||||||
<p class="simulatorTitle" translate>New price</p>
|
|
||||||
<p>{{$ctrl.newPrice | currency: 'EUR':2}}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,88 +0,0 @@
|
||||||
import ngModule from '../module';
|
|
||||||
import Component from 'core/lib/component';
|
|
||||||
|
|
||||||
class Controller extends Component {
|
|
||||||
set edit(value) {
|
|
||||||
this._edit = value;
|
|
||||||
this.clearDiscount();
|
|
||||||
this.setNewDiscount();
|
|
||||||
}
|
|
||||||
|
|
||||||
get edit() {
|
|
||||||
return this._edit;
|
|
||||||
}
|
|
||||||
|
|
||||||
set bulk(value) {
|
|
||||||
this._bulk = value;
|
|
||||||
this.setNewDiscount();
|
|
||||||
}
|
|
||||||
|
|
||||||
get bulk() {
|
|
||||||
return this._bulk;
|
|
||||||
}
|
|
||||||
|
|
||||||
get newDiscount() {
|
|
||||||
return this._newDiscount;
|
|
||||||
}
|
|
||||||
|
|
||||||
set newDiscount(value) {
|
|
||||||
this._newDiscount = value;
|
|
||||||
this.updateNewPrice();
|
|
||||||
}
|
|
||||||
|
|
||||||
updateNewPrice() {
|
|
||||||
if (this.newDiscount && this.edit[0])
|
|
||||||
this.newPrice = (this.edit[0].quantity * this.edit[0].price) - ((this.newDiscount * (this.edit[0].quantity * this.edit[0].price)) / 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
setNewDiscount() {
|
|
||||||
if (!this.newDiscount && this.edit[0])
|
|
||||||
this.newDiscount = this.edit[0].discount;
|
|
||||||
}
|
|
||||||
|
|
||||||
updateDiscount() {
|
|
||||||
let salesIds = [];
|
|
||||||
let modified = false;
|
|
||||||
|
|
||||||
if (this.newDiscount == null) return;
|
|
||||||
|
|
||||||
for (let i = 0; i < this.edit.length; i++) {
|
|
||||||
if (this.newDiscount != this.edit[0].discount || this.bulk || !this.newDiscount) {
|
|
||||||
salesIds.push(this.edit[i].id);
|
|
||||||
modified = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (modified) {
|
|
||||||
const params = {salesIds: salesIds, newDiscount: this.newDiscount};
|
|
||||||
const query = `Tickets/${this.$params.id}/updateDiscount`;
|
|
||||||
this.$http.post(query, params).then(() => {
|
|
||||||
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
|
|
||||||
console.log(this.edit[0].sale);
|
|
||||||
this.edit[0].sale.price = 277;
|
|
||||||
this.clearDiscount();
|
|
||||||
modified = false;
|
|
||||||
}).catch(e => {
|
|
||||||
this.vnApp.showError(e.message);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.onHide();
|
|
||||||
} else
|
|
||||||
this.vnApp.showError(this.$translate.instant('There are no changes to save'));
|
|
||||||
}
|
|
||||||
|
|
||||||
clearDiscount() {
|
|
||||||
this.newDiscount = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngModule.component('vnTicketSaleEditDiscount', {
|
|
||||||
template: require('./editDiscount.html'),
|
|
||||||
controller: Controller,
|
|
||||||
bindings: {
|
|
||||||
edit: '<?',
|
|
||||||
mana: '<?',
|
|
||||||
bulk: '<?',
|
|
||||||
onHide: '&'
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -141,7 +141,7 @@
|
||||||
<vn-textfield class="dense" vn-focus
|
<vn-textfield class="dense" vn-focus
|
||||||
vn-id="concept"
|
vn-id="concept"
|
||||||
ng-model="sale.concept"
|
ng-model="sale.concept"
|
||||||
on-change="$ctrl.changeConcept(sale)">
|
on-change="$ctrl.updateConcept(sale)">
|
||||||
</vn-textfield>
|
</vn-textfield>
|
||||||
</field>
|
</field>
|
||||||
</vn-td-editable>
|
</vn-td-editable>
|
||||||
|
|
|
@ -130,23 +130,6 @@ class Controller extends Section {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an array of index
|
|
||||||
* from checked instances
|
|
||||||
*
|
|
||||||
* @return {Array} Index list of checked instances
|
|
||||||
*/
|
|
||||||
selectedSalesIndex() {
|
|
||||||
if (!this.sales) return;
|
|
||||||
|
|
||||||
const indexList = [];
|
|
||||||
this.sales.forEach((sale, index) => {
|
|
||||||
if (sale.checked) indexList.push(index);
|
|
||||||
});
|
|
||||||
|
|
||||||
return indexList;
|
|
||||||
}
|
|
||||||
|
|
||||||
resetChanges() {
|
resetChanges() {
|
||||||
if (this.newInstances().length === 0)
|
if (this.newInstances().length === 0)
|
||||||
this.$.watcher.updateOriginalData();
|
this.$.watcher.updateOriginalData();
|
||||||
|
@ -162,8 +145,8 @@ class Controller extends Section {
|
||||||
|
|
||||||
removeSales() {
|
removeSales() {
|
||||||
const sales = this.selectedValidSales();
|
const sales = this.selectedValidSales();
|
||||||
const params = {sales: sales, actualTicketFk: this.ticket.id};
|
const params = {sales: sales, ticketId: this.ticket.id};
|
||||||
this.$http.post(`Sales/removes`, params).then(() => {
|
this.$http.post(`Sales/deleteSales`, params).then(() => {
|
||||||
this.removeSelectedSales();
|
this.removeSelectedSales();
|
||||||
this.vnApp.showSuccess(this.$t('Data saved!'));
|
this.vnApp.showSuccess(this.$t('Data saved!'));
|
||||||
}).finally(() => this.resetChanges());
|
}).finally(() => this.resetChanges());
|
||||||
|
@ -181,15 +164,7 @@ class Controller extends Section {
|
||||||
|
|
||||||
createClaim() {
|
createClaim() {
|
||||||
const sales = this.selectedValidSales();
|
const sales = this.selectedValidSales();
|
||||||
const params = {
|
const params = {ticketId: this.ticket.id, sales: sales};
|
||||||
claim: {
|
|
||||||
ticketFk: this.ticket.id,
|
|
||||||
clientFk: this.ticket.clientFk,
|
|
||||||
ticketCreated: this.ticket.shipped
|
|
||||||
},
|
|
||||||
sales: sales
|
|
||||||
};
|
|
||||||
|
|
||||||
this.resetChanges();
|
this.resetChanges();
|
||||||
this.$http.post(`Claims/createFromSales`, params)
|
this.$http.post(`Claims/createFromSales`, params)
|
||||||
.then(res => this.$state.go('claim.card.basicData', {id: res.data.id}));
|
.then(res => this.$state.go('claim.card.basicData', {id: res.data.id}));
|
||||||
|
@ -197,8 +172,7 @@ class Controller extends Section {
|
||||||
|
|
||||||
showTransferPopover(event) {
|
showTransferPopover(event) {
|
||||||
this.setTransferParams();
|
this.setTransferParams();
|
||||||
this.$.transfer.parent = event.target;
|
this.$.transfer.show(event);
|
||||||
this.$.transfer.show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setTransferParams() {
|
setTransferParams() {
|
||||||
|
@ -357,21 +331,11 @@ class Controller extends Section {
|
||||||
}
|
}
|
||||||
|
|
||||||
setReserved(reserved) {
|
setReserved(reserved) {
|
||||||
let selectedSales = this.selectedValidSales();
|
const selectedSales = this.selectedValidSales();
|
||||||
let params = {sales: selectedSales, ticketFk: this.ticket.id, reserved: reserved};
|
const params = {ticketId: this.ticket.id, sales: selectedSales, reserved: reserved};
|
||||||
|
this.$http.post(`Sales/reserve`, params).then(() => {
|
||||||
let reservedSales = new Map();
|
selectedSales.forEach(sale => {
|
||||||
this.$http.post(`Sales/reserve`, params).then(res => {
|
sale.reserved = reserved;
|
||||||
let isReserved = res.config.data.reserved;
|
|
||||||
|
|
||||||
res.config.data.sales.forEach(sale => {
|
|
||||||
reservedSales.set(sale.id, {reserved: isReserved});
|
|
||||||
});
|
|
||||||
|
|
||||||
this.sales.forEach(sale => {
|
|
||||||
const reservedSale = reservedSales.get(sale.id);
|
|
||||||
if (reservedSale)
|
|
||||||
sale.reserved = reservedSale.reserved;
|
|
||||||
});
|
});
|
||||||
}).finally(() => this.resetChanges());
|
}).finally(() => this.resetChanges());
|
||||||
}
|
}
|
||||||
|
@ -444,7 +408,7 @@ class Controller extends Section {
|
||||||
/*
|
/*
|
||||||
* Changes a sale concept
|
* Changes a sale concept
|
||||||
*/
|
*/
|
||||||
changeConcept(sale) {
|
updateConcept(sale) {
|
||||||
const data = {newConcept: sale.concept};
|
const data = {newConcept: sale.concept};
|
||||||
this.$http.post(`Sales/${sale.id}/updateConcept`, data).then(() => {
|
this.$http.post(`Sales/${sale.id}/updateConcept`, data).then(() => {
|
||||||
this.vnApp.showSuccess(this.$t('Data saved!'));
|
this.vnApp.showSuccess(this.$t('Data saved!'));
|
||||||
|
@ -481,12 +445,12 @@ class Controller extends Section {
|
||||||
}
|
}
|
||||||
|
|
||||||
isTicketEditable() {
|
isTicketEditable() {
|
||||||
this.$http.get(`Tickets/${this.$state.params.id}/isEditable`)
|
this.$http.get(`Tickets/${this.$params.id}/isEditable`)
|
||||||
.then(res => this.isEditable = res.data);
|
.then(res => this.isEditable = res.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
isTicketLocked() {
|
isTicketLocked() {
|
||||||
this.$http.get(`Tickets/${this.$state.params.id}/isLocked`)
|
this.$http.get(`Tickets/${this.$params.id}/isLocked`)
|
||||||
.then(res => this.isLocked = res.data);
|
.then(res => this.isLocked = res.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,718 @@
|
||||||
|
import './index.js';
|
||||||
|
import watcher from 'core/mocks/watcher';
|
||||||
|
import crudModel from 'core/mocks/crud-model';
|
||||||
|
|
||||||
|
describe('Ticket', () => {
|
||||||
|
describe('Component vnTicketSale', () => {
|
||||||
|
let controller;
|
||||||
|
let $scope;
|
||||||
|
let $state;
|
||||||
|
let $httpBackend;
|
||||||
|
|
||||||
|
beforeEach(ngModule('ticket'));
|
||||||
|
|
||||||
|
beforeEach(angular.mock.inject(($componentController, $rootScope, _$state_, _$httpBackend_) => {
|
||||||
|
const ticket = {
|
||||||
|
id: 1,
|
||||||
|
clientFk: 101,
|
||||||
|
shipped: 1,
|
||||||
|
created: new Date(),
|
||||||
|
client: {salesPersonFk: 1},
|
||||||
|
address: {mobile: 111111111}
|
||||||
|
};
|
||||||
|
const sales = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
concept: 'Item 1',
|
||||||
|
quantity: 5,
|
||||||
|
price: 23.5,
|
||||||
|
discount: 0,
|
||||||
|
}, {
|
||||||
|
id: 4,
|
||||||
|
concept: 'Item 2',
|
||||||
|
quantity: 20,
|
||||||
|
price: 5.5,
|
||||||
|
discount: 0,
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
$state = _$state_;
|
||||||
|
$scope = $rootScope.$new();
|
||||||
|
$scope.watcher = watcher;
|
||||||
|
$scope.sms = {open: () => {}};
|
||||||
|
$scope.ticket = ticket;
|
||||||
|
$scope.model = crudModel;
|
||||||
|
$httpBackend = _$httpBackend_;
|
||||||
|
Object.defineProperties($state.params, {
|
||||||
|
id: {
|
||||||
|
value: ticket.id,
|
||||||
|
writable: true
|
||||||
|
},
|
||||||
|
go: {
|
||||||
|
value: () => {},
|
||||||
|
writable: false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const $element = angular.element('<vn-ticket-sale></vn-ticket-sale>');
|
||||||
|
controller = $componentController('vnTicketSale', {$element, $scope});
|
||||||
|
controller.card = {reload: () => {}};
|
||||||
|
controller._ticket = ticket;
|
||||||
|
controller._sales = sales;
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('ticket() setter', () => {
|
||||||
|
it('should set the ticket data an then call the isTicketEditable() and isTicketLocked() methods', () => {
|
||||||
|
jest.spyOn(controller, 'isTicketEditable').mockReturnThis();
|
||||||
|
jest.spyOn(controller, 'isTicketLocked').mockReturnThis();
|
||||||
|
|
||||||
|
controller.ticket = {id: 1};
|
||||||
|
|
||||||
|
expect(controller.isTicketEditable).toHaveBeenCalledWith();
|
||||||
|
expect(controller.isTicketLocked).toHaveBeenCalledWith();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('sales() setter', () => {
|
||||||
|
it('should set the sales data an then call the refreshTotal() method', () => {
|
||||||
|
jest.spyOn(controller, 'refreshTotal').mockReturnThis();
|
||||||
|
|
||||||
|
controller.sales = [{id: 1}];
|
||||||
|
|
||||||
|
expect(controller.refreshTotal).toHaveBeenCalledWith();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getSubTotal()', () => {
|
||||||
|
it('should make an HTTP GET query and then set the subtotal property', () => {
|
||||||
|
const expectedAmount = 128;
|
||||||
|
|
||||||
|
$httpBackend.expect('GET', 'Tickets/1/subtotal').respond(200, expectedAmount);
|
||||||
|
controller.getSubTotal();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.subtotal).toEqual(expectedAmount);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getSaleTotal()', () => {
|
||||||
|
it('should return the sale total amount', () => {
|
||||||
|
const sale = {
|
||||||
|
quantity: 10,
|
||||||
|
price: 2,
|
||||||
|
discount: 10
|
||||||
|
};
|
||||||
|
|
||||||
|
const expectedAmount = 18;
|
||||||
|
const result = controller.getSaleTotal(sale);
|
||||||
|
|
||||||
|
expect(result).toEqual(expectedAmount);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getMana()', () => {
|
||||||
|
it('should make an HTTP GET query and return the worker mana', () => {
|
||||||
|
controller.edit = {};
|
||||||
|
const expectedAmount = 250;
|
||||||
|
|
||||||
|
$httpBackend.expect('GET', 'Tickets/1/getSalesPersonMana').respond(200, expectedAmount);
|
||||||
|
controller.getMana();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.edit.mana).toEqual(expectedAmount);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getVat()', () => {
|
||||||
|
it('should make an HTTP GET query and return the ticket VAT', () => {
|
||||||
|
controller.edit = {};
|
||||||
|
const expectedAmount = 67;
|
||||||
|
|
||||||
|
$httpBackend.expect('GET', 'Tickets/1/getVAT').respond(200, expectedAmount);
|
||||||
|
controller.getVat();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.VAT).toEqual(expectedAmount);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('selectedSales()', () => {
|
||||||
|
it('should return a list of selected sales', () => {
|
||||||
|
controller.sales[1].checked = true;
|
||||||
|
|
||||||
|
const expectedSaleId = 4;
|
||||||
|
const result = controller.selectedSales();
|
||||||
|
const firstSelectedSale = result[0];
|
||||||
|
|
||||||
|
expect(result.length).toEqual(1);
|
||||||
|
expect(firstSelectedSale.id).toEqual(expectedSaleId);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('selectedValidSales()', () => {
|
||||||
|
it('should return a list of selected sales having a sale id', () => {
|
||||||
|
const newEmptySale = {quantity: 10, checked: true};
|
||||||
|
controller.sales.push(newEmptySale);
|
||||||
|
controller.sales[0].checked = true;
|
||||||
|
|
||||||
|
const expectedSaleId = 1;
|
||||||
|
const result = controller.selectedValidSales();
|
||||||
|
const firstSelectedSale = result[0];
|
||||||
|
|
||||||
|
expect(result.length).toEqual(1);
|
||||||
|
expect(firstSelectedSale.id).toEqual(expectedSaleId);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('selectedSalesCount()', () => {
|
||||||
|
it('should return the number of selected sales', () => {
|
||||||
|
controller.sales[0].checked = true;
|
||||||
|
|
||||||
|
const result = controller.selectedSalesCount();
|
||||||
|
|
||||||
|
expect(result).toEqual(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('hasSelectedSales()', () => {
|
||||||
|
it('should return truthy if atleast one sale is selected', () => {
|
||||||
|
controller.sales[0].checked = true;
|
||||||
|
|
||||||
|
const result = controller.hasSelectedSales();
|
||||||
|
|
||||||
|
expect(result).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('hasOneSaleSelected()', () => {
|
||||||
|
it('should return truthy if just one sale is selected', () => {
|
||||||
|
controller.sales[0].checked = true;
|
||||||
|
|
||||||
|
const result = controller.hasOneSaleSelected();
|
||||||
|
|
||||||
|
expect(result).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return falsy if more than one sale is selected', () => {
|
||||||
|
controller.sales[0].checked = true;
|
||||||
|
controller.sales[1].checked = true;
|
||||||
|
|
||||||
|
const result = controller.hasOneSaleSelected();
|
||||||
|
|
||||||
|
expect(result).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('newInstances()', () => {
|
||||||
|
it(`should return a list of sales that doesn't have an id`, () => {
|
||||||
|
const newEmptySale = {quantity: 10, checked: true};
|
||||||
|
controller.sales.push(newEmptySale);
|
||||||
|
|
||||||
|
const result = controller.newInstances();
|
||||||
|
const firstNewSale = result[0];
|
||||||
|
|
||||||
|
expect(result.length).toEqual(1);
|
||||||
|
expect(firstNewSale.id).toBeUndefined();
|
||||||
|
expect(firstNewSale.quantity).toEqual(10);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('resetChanges()', () => {
|
||||||
|
it(`should not call the watcher updateOriginalData() method`, () => {
|
||||||
|
jest.spyOn(controller.$.watcher, 'updateOriginalData').mockReturnThis();
|
||||||
|
|
||||||
|
const newEmptySale = {quantity: 10};
|
||||||
|
controller.sales.push(newEmptySale);
|
||||||
|
controller.resetChanges();
|
||||||
|
|
||||||
|
expect(controller.$.watcher.updateOriginalData).not.toHaveBeenCalledWith();
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should call the watcher updateOriginalData() method`, () => {
|
||||||
|
jest.spyOn(controller.$.watcher, 'updateOriginalData').mockReturnThis();
|
||||||
|
|
||||||
|
controller.resetChanges();
|
||||||
|
|
||||||
|
expect(controller.$.watcher.updateOriginalData).toHaveBeenCalledWith();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('changeState()', () => {
|
||||||
|
it('should make an HTTP post query, then call the showSuccess(), reload() and resetChanges() methods', () => {
|
||||||
|
jest.spyOn(controller.card, 'reload').mockReturnThis();
|
||||||
|
jest.spyOn(controller.vnApp, 'showSuccess').mockReturnThis();
|
||||||
|
jest.spyOn(controller, 'resetChanges').mockReturnThis();
|
||||||
|
|
||||||
|
const expectedParams = {ticketFk: 1, code: 'OK'};
|
||||||
|
$httpBackend.expect('POST', `TicketTrackings/changeState`, expectedParams).respond(200);
|
||||||
|
controller.changeState('OK');
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.card.reload).toHaveBeenCalledWith();
|
||||||
|
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
|
||||||
|
expect(controller.resetChanges).toHaveBeenCalledWith();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('removeSales()', () => {
|
||||||
|
it('should make an HTTP post query, then call the showSuccess(), removeSelectedSales() and resetChanges() methods', () => {
|
||||||
|
jest.spyOn(controller.vnApp, 'showSuccess').mockReturnThis();
|
||||||
|
jest.spyOn(controller, 'removeSelectedSales').mockReturnThis();
|
||||||
|
jest.spyOn(controller, 'resetChanges').mockReturnThis();
|
||||||
|
|
||||||
|
const firstSale = controller.sales[0];
|
||||||
|
firstSale.checked = true;
|
||||||
|
const expectedParams = {sales: [firstSale], ticketId: 1};
|
||||||
|
$httpBackend.expect('POST', `Sales/deleteSales`, expectedParams).respond(200);
|
||||||
|
controller.removeSales();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.removeSelectedSales).toHaveBeenCalledWith();
|
||||||
|
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
|
||||||
|
expect(controller.resetChanges).toHaveBeenCalledWith();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('removeSelectedSales()', () => {
|
||||||
|
it('should remove the selected sales from the controller sale property', () => {
|
||||||
|
jest.spyOn(controller, 'refreshTotal').mockReturnThis();
|
||||||
|
jest.spyOn(controller, 'resetChanges').mockReturnThis();
|
||||||
|
|
||||||
|
const firstSale = controller.sales[0];
|
||||||
|
firstSale.checked = true;
|
||||||
|
|
||||||
|
controller.removeSelectedSales();
|
||||||
|
|
||||||
|
const lastSale = controller.sales[0];
|
||||||
|
|
||||||
|
expect(controller.sales.length).toEqual(1);
|
||||||
|
expect(lastSale.id).toEqual(4);
|
||||||
|
expect(controller.refreshTotal).toHaveBeenCalledWith();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('createClaim()', () => {
|
||||||
|
it('should perform a query and call windows open', () => {
|
||||||
|
jest.spyOn(controller, 'resetChanges').mockReturnThis();
|
||||||
|
jest.spyOn(controller.$state, 'go').mockReturnThis();
|
||||||
|
|
||||||
|
const newEmptySale = {quantity: 10};
|
||||||
|
controller.sales.push(newEmptySale);
|
||||||
|
const firstSale = controller.sales[0];
|
||||||
|
firstSale.checked = true;
|
||||||
|
|
||||||
|
const expectedParams = {ticketId: 1, sales: [firstSale]};
|
||||||
|
$httpBackend.expect('POST', `Claims/createFromSales`, expectedParams).respond(200, {id: 1});
|
||||||
|
controller.createClaim();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.resetChanges).toHaveBeenCalledWith();
|
||||||
|
expect(controller.$state.go).toHaveBeenCalledWith('claim.card.basicData', {id: 1});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('setTransferParams()', () => {
|
||||||
|
it('should define the transfer object on the controller and its default properties', () => {
|
||||||
|
const firstSale = controller.sales[0];
|
||||||
|
firstSale.checked = true;
|
||||||
|
const expectedResponse = [firstSale];
|
||||||
|
|
||||||
|
$httpBackend.expect('GET', `clients/101/lastActiveTickets?ticketId=1`).respond(expectedResponse);
|
||||||
|
controller.setTransferParams();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
const lastActiveTickets = controller.transfer.lastActiveTickets;
|
||||||
|
|
||||||
|
expect(controller.transfer).toBeDefined();
|
||||||
|
expect(lastActiveTickets).toBeDefined();
|
||||||
|
expect(lastActiveTickets[0].id).toEqual(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('transferSales()', () => {
|
||||||
|
it('should transfer sales to a ticket and then call to the $state go() method', () => {
|
||||||
|
jest.spyOn(controller.$state, 'go').mockReturnThis();
|
||||||
|
|
||||||
|
controller.transfer = {
|
||||||
|
sales: [{id: 1, itemFk: 1}, {id: 2, itemFk: 4}]
|
||||||
|
};
|
||||||
|
|
||||||
|
const ticketIdToTransfer = 13;
|
||||||
|
const expectedResponse = {id: ticketIdToTransfer};
|
||||||
|
const params = {
|
||||||
|
ticketId: 13,
|
||||||
|
sales: controller.transfer.sales
|
||||||
|
};
|
||||||
|
|
||||||
|
$httpBackend.expect('POST', `tickets/1/transferSales`, params).respond(expectedResponse);
|
||||||
|
controller.transferSales(ticketIdToTransfer);
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.$state.go).toHaveBeenCalledWith('ticket.card.sale', {id: ticketIdToTransfer});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('updatePrice()', () => {
|
||||||
|
it('should make an HTTP POST query, update the sale price and then call to the resetChanges() method', () => {
|
||||||
|
jest.spyOn(controller.vnApp, 'showSuccess').mockReturnThis();
|
||||||
|
jest.spyOn(controller, 'resetChanges').mockReturnThis();
|
||||||
|
|
||||||
|
const selectedSale = controller.sales[0];
|
||||||
|
selectedSale.checked = true;
|
||||||
|
controller.$.editPricePopover = {hide: jest.fn()};
|
||||||
|
controller.edit = {
|
||||||
|
price: 2,
|
||||||
|
sale: selectedSale
|
||||||
|
};
|
||||||
|
const expectedParams = {newPrice: 2};
|
||||||
|
$httpBackend.expect('POST', `Sales/1/updatePrice`, expectedParams).respond(200, {price: 2});
|
||||||
|
controller.updatePrice();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(selectedSale.price).toEqual(2);
|
||||||
|
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
|
||||||
|
expect(controller.$.editPricePopover.hide).toHaveBeenCalledWith();
|
||||||
|
expect(controller.resetChanges).toHaveBeenCalledWith();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('changeDiscount()', () => {
|
||||||
|
it('should call to the updateDiscount() method and then to the editDiscount hide() method', () => {
|
||||||
|
jest.spyOn(controller, 'updateDiscount').mockReturnThis();
|
||||||
|
|
||||||
|
const selectedSale = controller.sales[0];
|
||||||
|
selectedSale.checked = true;
|
||||||
|
const expectedSale = selectedSale;
|
||||||
|
controller.$.editDiscount = {hide: jest.fn()};
|
||||||
|
controller.edit = {
|
||||||
|
discount: 10,
|
||||||
|
sale: selectedSale
|
||||||
|
};
|
||||||
|
|
||||||
|
controller.changeDiscount();
|
||||||
|
|
||||||
|
expect(controller.updateDiscount).toHaveBeenCalledWith([expectedSale]);
|
||||||
|
expect(controller.$.editDiscount.hide).toHaveBeenCalledWith();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('changeMultipleDiscount()', () => {
|
||||||
|
it('should call to the updateDiscount() method and then to the editDiscountDialog hide() method', () => {
|
||||||
|
jest.spyOn(controller, 'updateDiscount').mockReturnThis();
|
||||||
|
|
||||||
|
const firstSelectedSale = controller.sales[0];
|
||||||
|
firstSelectedSale.checked = true;
|
||||||
|
|
||||||
|
const secondSelectedSale = controller.sales[1];
|
||||||
|
secondSelectedSale.checked = true;
|
||||||
|
|
||||||
|
const expectedSales = [firstSelectedSale, secondSelectedSale];
|
||||||
|
controller.$.editDiscountDialog = {hide: jest.fn()};
|
||||||
|
controller.edit = {
|
||||||
|
discount: 10,
|
||||||
|
sales: expectedSales
|
||||||
|
};
|
||||||
|
|
||||||
|
controller.changeMultipleDiscount();
|
||||||
|
|
||||||
|
expect(controller.updateDiscount).toHaveBeenCalledWith(expectedSales);
|
||||||
|
expect(controller.$.editDiscountDialog.hide).toHaveBeenCalledWith();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not call to the updateDiscount() method and then to the editDiscountDialog hide() method', () => {
|
||||||
|
jest.spyOn(controller, 'updateDiscount').mockReturnThis();
|
||||||
|
|
||||||
|
const firstSelectedSale = controller.sales[0];
|
||||||
|
firstSelectedSale.checked = true;
|
||||||
|
firstSelectedSale.discount = 10;
|
||||||
|
|
||||||
|
const secondSelectedSale = controller.sales[1];
|
||||||
|
secondSelectedSale.checked = true;
|
||||||
|
secondSelectedSale.discount = 10;
|
||||||
|
|
||||||
|
const expectedSales = [firstSelectedSale, secondSelectedSale];
|
||||||
|
controller.$.editDiscountDialog = {hide: jest.fn()};
|
||||||
|
controller.edit = {
|
||||||
|
discount: 10,
|
||||||
|
sales: expectedSales
|
||||||
|
};
|
||||||
|
|
||||||
|
controller.changeMultipleDiscount();
|
||||||
|
|
||||||
|
expect(controller.updateDiscount).not.toHaveBeenCalledWith(expectedSales);
|
||||||
|
expect(controller.$.editDiscountDialog.hide).toHaveBeenCalledWith();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('updateDiscount()', () => {
|
||||||
|
it('should make an HTTP POST query, update the sales discount and then call to the resetChanges() method', () => {
|
||||||
|
jest.spyOn(controller, 'resetChanges').mockReturnThis();
|
||||||
|
jest.spyOn(controller.vnApp, 'showSuccess').mockReturnThis();
|
||||||
|
|
||||||
|
const expectedDiscount = 10;
|
||||||
|
const firstSelectedSale = controller.sales[0];
|
||||||
|
firstSelectedSale.checked = true;
|
||||||
|
|
||||||
|
const secondSelectedSale = controller.sales[1];
|
||||||
|
secondSelectedSale.checked = true;
|
||||||
|
|
||||||
|
controller.edit = {
|
||||||
|
discount: expectedDiscount
|
||||||
|
};
|
||||||
|
|
||||||
|
const expectedSales = [firstSelectedSale, secondSelectedSale];
|
||||||
|
const expectedSaleIds = [firstSelectedSale.id, secondSelectedSale.id];
|
||||||
|
const expectedParams = {salesIds: expectedSaleIds, newDiscount: expectedDiscount};
|
||||||
|
$httpBackend.expect('POST', `Tickets/1/updateDiscount`, expectedParams).respond(200, {discount: 10});
|
||||||
|
controller.updateDiscount(expectedSales);
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(firstSelectedSale.discount).toEqual(expectedDiscount);
|
||||||
|
expect(secondSelectedSale.discount).toEqual(expectedDiscount);
|
||||||
|
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
|
||||||
|
expect(controller.resetChanges).toHaveBeenCalledWith();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getNewPrice()', () => {
|
||||||
|
it('should return the total price simulation from a price change', () => {
|
||||||
|
const selectedSale = controller.sales[0];
|
||||||
|
selectedSale.checked = true;
|
||||||
|
controller.edit = {
|
||||||
|
price: 2,
|
||||||
|
sale: selectedSale
|
||||||
|
};
|
||||||
|
|
||||||
|
const expectedAmount = 10;
|
||||||
|
const result = controller.getNewPrice();
|
||||||
|
|
||||||
|
expect(result).toEqual(expectedAmount);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the total price simulation from a discount change', () => {
|
||||||
|
const selectedSale = controller.sales[0];
|
||||||
|
selectedSale.checked = true;
|
||||||
|
controller.edit = {
|
||||||
|
discount: 10,
|
||||||
|
sale: selectedSale
|
||||||
|
};
|
||||||
|
|
||||||
|
const expectedAmount = 105.75;
|
||||||
|
const result = controller.getNewPrice();
|
||||||
|
|
||||||
|
expect(result).toEqual(expectedAmount);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('hasReserves()', () => {
|
||||||
|
it('should return true for any sale marked as reserved', () => {
|
||||||
|
const selectedSale = controller.sales[0];
|
||||||
|
selectedSale.reserved = true;
|
||||||
|
|
||||||
|
const result = controller.hasReserves();
|
||||||
|
|
||||||
|
expect(result).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('unmarkAsReserved()', () => {
|
||||||
|
it('should call setReserved with false', () => {
|
||||||
|
jest.spyOn(controller, 'setReserved');
|
||||||
|
|
||||||
|
controller.unmarkAsReserved(false);
|
||||||
|
|
||||||
|
expect(controller.setReserved).toHaveBeenCalledWith(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('markAsReserved()', () => {
|
||||||
|
it('should call setReserved with true', () => {
|
||||||
|
jest.spyOn(controller, 'setReserved');
|
||||||
|
|
||||||
|
controller.markAsReserved(true);
|
||||||
|
|
||||||
|
expect(controller.setReserved).toHaveBeenCalledWith(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('setReserved()', () => {
|
||||||
|
it('should call getCheckedLines, $.index.accept and make a query ', () => {
|
||||||
|
const selectedSale = controller.sales[0];
|
||||||
|
selectedSale.checked = true;
|
||||||
|
const expectedParams = {
|
||||||
|
sales: [selectedSale],
|
||||||
|
ticketId: 1,
|
||||||
|
reserved: false
|
||||||
|
};
|
||||||
|
|
||||||
|
$httpBackend.expectPOST(`Sales/reserve`, expectedParams).respond();
|
||||||
|
controller.unmarkAsReserved(false);
|
||||||
|
$httpBackend.flush();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('newOrderFromTicket()', () => {
|
||||||
|
it('should make an HTTP post query and then open the new order on a new tab', () => {
|
||||||
|
const expectedParams = {ticketFk: 1};
|
||||||
|
const expectedResponse = {id: 123};
|
||||||
|
|
||||||
|
window.open = jasmine.createSpy('open');
|
||||||
|
controller.$state.href = jasmine.createSpy('href')
|
||||||
|
.and.returnValue('/somePath');
|
||||||
|
|
||||||
|
$httpBackend.expect('POST', `Orders/newFromTicket`, expectedParams).respond(expectedResponse);
|
||||||
|
controller.newOrderFromTicket();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(window.open).toHaveBeenCalledWith('/somePath', '_blank');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('showSMSDialog()', () => {
|
||||||
|
it('should open an SMS dialog with specified data', () => {
|
||||||
|
jest.spyOn(controller.$.sms, 'open');
|
||||||
|
|
||||||
|
const selectedSale = controller.sales[0];
|
||||||
|
selectedSale.checked = true;
|
||||||
|
controller.showSMSDialog();
|
||||||
|
|
||||||
|
expect(controller.$.sms.open).toHaveBeenCalledWith();
|
||||||
|
expect(controller.newSMS.destination).toEqual(111111111);
|
||||||
|
expect(controller.newSMS.message).not.toEqual('');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('changeQuantity()', () => {
|
||||||
|
it('should not call addSale() or updateQuantity() methods', () => {
|
||||||
|
jest.spyOn(controller, 'addSale');
|
||||||
|
jest.spyOn(controller, 'updateQuantity');
|
||||||
|
|
||||||
|
const sale = {itemFk: 4};
|
||||||
|
controller.changeQuantity(sale);
|
||||||
|
|
||||||
|
expect(controller.addSale).not.toHaveBeenCalled();
|
||||||
|
expect(controller.updateQuantity).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call addSale() method', () => {
|
||||||
|
jest.spyOn(controller, 'addSale');
|
||||||
|
|
||||||
|
const sale = {itemFk: 4, quantity: 5};
|
||||||
|
controller.changeQuantity(sale);
|
||||||
|
|
||||||
|
expect(controller.addSale).toHaveBeenCalledWith(sale);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call updateQuantity() method', () => {
|
||||||
|
jest.spyOn(controller, 'addSale');
|
||||||
|
jest.spyOn(controller, 'updateQuantity');
|
||||||
|
|
||||||
|
const sale = {id: 1, itemFk: 4, quantity: 5};
|
||||||
|
controller.changeQuantity(sale);
|
||||||
|
|
||||||
|
expect(controller.addSale).not.toHaveBeenCalled();
|
||||||
|
expect(controller.updateQuantity).toHaveBeenCalledWith(sale);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('updateQuantity()', () => {
|
||||||
|
it('should make a POST query saving sale quantity', () => {
|
||||||
|
jest.spyOn(controller, 'resetChanges').mockReturnThis();
|
||||||
|
|
||||||
|
const selectedSale = controller.sales[0];
|
||||||
|
selectedSale.checked = true;
|
||||||
|
selectedSale.quantity = 10;
|
||||||
|
|
||||||
|
const expectedParams = {quantity: 10};
|
||||||
|
$httpBackend.expect('POST', `Sales/1/updateQuantity`, expectedParams).respond();
|
||||||
|
controller.updateQuantity(selectedSale);
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.resetChanges).toHaveBeenCalledWith();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('updateConcept()', () => {
|
||||||
|
it('should make a POST query saving sale concept', () => {
|
||||||
|
jest.spyOn(controller, 'resetChanges').mockReturnThis();
|
||||||
|
|
||||||
|
const selectedSale = controller.sales[0];
|
||||||
|
selectedSale.checked = true;
|
||||||
|
selectedSale.concept = 'My new weapon';
|
||||||
|
|
||||||
|
const expectedParams = {newConcept: 'My new weapon'};
|
||||||
|
$httpBackend.expect('POST', `Sales/1/updateConcept`, expectedParams).respond();
|
||||||
|
controller.updateConcept(selectedSale);
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.resetChanges).toHaveBeenCalledWith();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('addSale()', () => {
|
||||||
|
it('should make a POST query adding a new sale', () => {
|
||||||
|
jest.spyOn(controller.vnApp, 'showSuccess').mockReturnThis();
|
||||||
|
jest.spyOn(controller, 'resetChanges').mockReturnThis();
|
||||||
|
|
||||||
|
const newSale = {itemFk: 4, quantity: 10};
|
||||||
|
const expectedParams = {itemId: 4, quantity: 10};
|
||||||
|
const expectedResult = {
|
||||||
|
id: 30,
|
||||||
|
quantity: 10,
|
||||||
|
discount: 0,
|
||||||
|
price: 0,
|
||||||
|
itemFk: 4,
|
||||||
|
item: {
|
||||||
|
subName: 'Item subName',
|
||||||
|
image: '30.png'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$httpBackend.expect('POST', `tickets/1/addSale`, expectedParams).respond(expectedResult);
|
||||||
|
controller.addSale(newSale);
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
|
||||||
|
expect(controller.resetChanges).toHaveBeenCalledWith();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isTicketEditable()', () => {
|
||||||
|
it('should make a HTTP GET query and set the isEditable property on the controller', () => {
|
||||||
|
$httpBackend.expect('GET', `Tickets/1/isEditable`).respond(200, true);
|
||||||
|
controller.isTicketEditable();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.isEditable).toBeDefined();
|
||||||
|
expect(controller.isEditable).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isTicketLocked()', () => {
|
||||||
|
it('should make a HTTP GET query and set the isLocked property on the controller', () => {
|
||||||
|
$httpBackend.expect('GET', `Tickets/1/isLocked`).respond(200, false);
|
||||||
|
controller.isTicketLocked();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.isLocked).toBeDefined();
|
||||||
|
expect(controller.isLocked).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('calculateSalePrice()', () => {
|
||||||
|
it('should make an HTTP post query ', () => {
|
||||||
|
jest.spyOn(controller.vnApp, 'showSuccess').mockReturnThis();
|
||||||
|
jest.spyOn(controller.$.model, 'refresh').mockReturnThis();
|
||||||
|
|
||||||
|
const selectedSale = controller.sales[0];
|
||||||
|
selectedSale.checked = true;
|
||||||
|
|
||||||
|
$httpBackend.expect('POST', `Sales/1/recalculatePrice`).respond(200);
|
||||||
|
controller.calculateSalePrice();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
|
||||||
|
expect(controller.$.model.refresh).toHaveBeenCalledWith();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,87 +0,0 @@
|
||||||
import '../editDiscount.js';
|
|
||||||
|
|
||||||
describe('Ticket', () => {
|
|
||||||
describe('Component vnTicketSaleEditDiscount', () => {
|
|
||||||
let controller;
|
|
||||||
let $httpBackend;
|
|
||||||
let $state;
|
|
||||||
let $scope;
|
|
||||||
|
|
||||||
beforeEach(ngModule('ticket'));
|
|
||||||
|
|
||||||
beforeEach(angular.mock.inject(($componentController, _$state_, _$httpBackend_, $rootScope) => {
|
|
||||||
$httpBackend = _$httpBackend_;
|
|
||||||
$scope = $rootScope.$new();
|
|
||||||
$scope.index = {model: {instances: [{id: 1}, {id: 2}]}, accept: () => {
|
|
||||||
return {
|
|
||||||
then: () => {}
|
|
||||||
};
|
|
||||||
}};
|
|
||||||
$state = _$state_;
|
|
||||||
$state.params.id = 11;
|
|
||||||
const $element = angular.element('<vn-ticket-sale-edit-discount></vn-ticket-sale-edit-discount>');
|
|
||||||
controller = $componentController('vnTicketSaleEditDiscount', {$element, $scope});
|
|
||||||
controller._edit = [{id: 3}];
|
|
||||||
controller.onHide = () => {};
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('edit() setter', () => {
|
|
||||||
it('should set _edit value and call setNewDiscount', () => {
|
|
||||||
jest.spyOn(controller, 'setNewDiscount');
|
|
||||||
controller.edit = {id: 1};
|
|
||||||
|
|
||||||
expect(controller.edit).toEqual({id: 1});
|
|
||||||
expect(controller.setNewDiscount).toHaveBeenCalledWith();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('bulk() setter', () => {
|
|
||||||
it('should set _bulk value and call setNewDiscount', () => {
|
|
||||||
jest.spyOn(controller, 'setNewDiscount');
|
|
||||||
controller.bulk = true;
|
|
||||||
|
|
||||||
expect(controller.bulk).toEqual(true);
|
|
||||||
expect(controller.setNewDiscount).toHaveBeenCalledWith();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('setNewDiscount()', () => {
|
|
||||||
it('should set NewDiscount to edit[0].discount value if it doesnt exists', () => {
|
|
||||||
controller.edit = [{discount: 1}];
|
|
||||||
controller.setNewDiscount();
|
|
||||||
|
|
||||||
expect(controller.newDiscount).toEqual(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('updateDiscount()', () => {
|
|
||||||
it('should make a query if the discount value has been modified or the bulk value is true', () => {
|
|
||||||
controller.bulk = true;
|
|
||||||
controller.newDiscount = 15;
|
|
||||||
|
|
||||||
$httpBackend.expectPOST(`Tickets/11/updateDiscount`).respond();
|
|
||||||
controller.updateDiscount();
|
|
||||||
|
|
||||||
$httpBackend.flush();
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should throw if there's no changes on discount and it isn't bulk`, () => {
|
|
||||||
controller.bulk = false;
|
|
||||||
controller.newDiscount = 15;
|
|
||||||
controller.edit = [{discount: 15}];
|
|
||||||
jest.spyOn(controller.vnApp, 'showError');
|
|
||||||
controller.updateDiscount();
|
|
||||||
|
|
||||||
expect(controller.vnApp.showError).toHaveBeenCalledWith('There are no changes to save');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('clearDiscount()', () => {
|
|
||||||
it('should set newDiscount to null', () => {
|
|
||||||
controller.clearDiscount();
|
|
||||||
|
|
||||||
expect(controller.newDiscount).toEqual(null);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,409 +0,0 @@
|
||||||
import '../index.js';
|
|
||||||
import watcher from 'core/mocks/watcher';
|
|
||||||
import crudModel from 'core/mocks/crud-model';
|
|
||||||
|
|
||||||
describe('Ticket', () => {
|
|
||||||
describe('Component vnTicketSale', () => {
|
|
||||||
let controller;
|
|
||||||
let $scope;
|
|
||||||
let $state;
|
|
||||||
let $httpBackend;
|
|
||||||
|
|
||||||
const ticket = {
|
|
||||||
id: 1,
|
|
||||||
clientFk: 101,
|
|
||||||
shipped: 1,
|
|
||||||
created: new Date(),
|
|
||||||
client: {salesPersonFk: 1},
|
|
||||||
address: {mobile: 111111111}
|
|
||||||
};
|
|
||||||
const sales = [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
concept: 'Item 1',
|
|
||||||
quantity: 5,
|
|
||||||
price: 23.5,
|
|
||||||
discount: 0,
|
|
||||||
}, {
|
|
||||||
id: 4,
|
|
||||||
concept: 'Item 2',
|
|
||||||
quantity: 20,
|
|
||||||
price: 5.5,
|
|
||||||
discount: 0,
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
beforeEach(ngModule('ticket'));
|
|
||||||
|
|
||||||
beforeEach(angular.mock.inject(($componentController, $rootScope, _$state_, _$httpBackend_) => {
|
|
||||||
$state = _$state_;
|
|
||||||
$scope = $rootScope.$new();
|
|
||||||
$scope.watcher = watcher;
|
|
||||||
$scope.sms = {open: () => {}};
|
|
||||||
$scope.ticket = ticket;
|
|
||||||
$scope.model = crudModel;
|
|
||||||
$httpBackend = _$httpBackend_;
|
|
||||||
Object.defineProperties($state.params, {
|
|
||||||
id: {
|
|
||||||
value: ticket.id,
|
|
||||||
writable: true
|
|
||||||
},
|
|
||||||
go: {
|
|
||||||
value: () => {},
|
|
||||||
writable: false
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const $element = angular.element('<vn-ticket-sale></vn-ticket-sale>');
|
|
||||||
controller = $componentController('vnTicketSale', {$element, $scope});
|
|
||||||
controller.card = {reload: () => {}};
|
|
||||||
controller.ticket = ticket;
|
|
||||||
controller.sales = sales;
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('createClaim()', () => {
|
|
||||||
it('should perform a query and call windows open', () => {
|
|
||||||
jest.spyOn(controller.$state, 'go');
|
|
||||||
|
|
||||||
const claim = {id: 1};
|
|
||||||
const sales = [{id: 1}, {id: 2}];
|
|
||||||
|
|
||||||
$httpBackend.whenGET(`Tickets/1/getVAT`).respond(200, 10.5);
|
|
||||||
$httpBackend.whenGET(`Tickets/1/subtotal`).respond(200, 227.5);
|
|
||||||
$httpBackend.whenGET(`Tickets/1/isEditable`).respond();
|
|
||||||
$httpBackend.whenGET(`Tickets/1/isLocked`).respond();
|
|
||||||
$httpBackend.when('POST', `Claims/createFromSales`, {claim: claim, sales: sales}).respond(claim);
|
|
||||||
$httpBackend.expect('POST', `Claims/createFromSales`).respond(claim);
|
|
||||||
controller.createClaim();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.subtotal).toEqual(227.5);
|
|
||||||
expect(controller.VAT).toEqual(10.5);
|
|
||||||
expect(controller.total).toEqual(238);
|
|
||||||
expect(controller.$state.go).toHaveBeenCalledWith('claim.card.basicData', {id: 1});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('isChecked() getter', () => {
|
|
||||||
it('should set isChecked value to true when one of the instances has the value checked to true', () => {
|
|
||||||
controller.sales[0].checked = true;
|
|
||||||
|
|
||||||
expect(controller.isChecked).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('checkedLines()', () => {
|
|
||||||
it('should make an array of the instances with the property checked true()', () => {
|
|
||||||
let sale = controller.sales[0];
|
|
||||||
sale.checked = true;
|
|
||||||
let expectedResult = [sale];
|
|
||||||
|
|
||||||
$httpBackend.whenGET(`Tickets/1/subtotal`).respond(200, 227.5);
|
|
||||||
$httpBackend.whenGET(`Tickets/1/getVAT`).respond(200, 10.5);
|
|
||||||
$httpBackend.whenGET(`Tickets/1/isEditable`).respond();
|
|
||||||
$httpBackend.whenGET(`Tickets/1/isLocked`).respond();
|
|
||||||
let result = controller.checkedLines();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(result).toEqual(expectedResult);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('onStateOkClick()', () => {
|
|
||||||
it('should perform a get and then call a function', () => {
|
|
||||||
let filter = {where: {code: 'OK'}, fields: ['id']};
|
|
||||||
filter = encodeURIComponent(JSON.stringify(filter));
|
|
||||||
let res = [{id: 3}];
|
|
||||||
jest.spyOn(controller, 'onStateChange').mockReturnThis();
|
|
||||||
|
|
||||||
$httpBackend.whenGET(`States?filter=${filter}`).respond(res);
|
|
||||||
$httpBackend.expectGET(`Tickets/1/subtotal`).respond(200, 227.5);
|
|
||||||
$httpBackend.expectGET(`Tickets/1/getVAT`).respond(200, 10.5);
|
|
||||||
$httpBackend.whenGET(`Tickets/1/isEditable`).respond();
|
|
||||||
$httpBackend.whenGET(`Tickets/1/isLocked`).respond();
|
|
||||||
controller.onStateOkClick();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.onStateChange).toHaveBeenCalledWith(3);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('onStateChange()', () => {
|
|
||||||
it('should perform a post and then call a function', () => {
|
|
||||||
$httpBackend.expectPOST(`TicketTrackings/changeState`).respond();
|
|
||||||
$httpBackend.whenGET(`Tickets/1/subtotal`).respond(200, 227.5);
|
|
||||||
$httpBackend.whenGET(`Tickets/1/getVAT`).respond(200, 10.5);
|
|
||||||
$httpBackend.whenGET(`Tickets/1/isEditable`).respond();
|
|
||||||
$httpBackend.whenGET(`Tickets/1/isLocked`).respond();
|
|
||||||
controller.onStateChange(3);
|
|
||||||
$httpBackend.flush();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('onRemoveLinesClick()', () => {
|
|
||||||
it('should call getCheckedLines, call removeInstances, and make a query', () => {
|
|
||||||
controller.sales[0].checked = true;
|
|
||||||
|
|
||||||
$httpBackend.whenPOST(`Sales/removes`).respond();
|
|
||||||
$httpBackend.whenGET(`Tickets/1/subtotal`).respond(200, 227.5);
|
|
||||||
$httpBackend.whenGET(`Tickets/1/getVAT`).respond(200, 10.5);
|
|
||||||
$httpBackend.whenGET(`Tickets/1/isEditable`).respond();
|
|
||||||
$httpBackend.whenGET(`Tickets/1/isLocked`).respond();
|
|
||||||
controller.onRemoveLinesClick('accept');
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.sales.length).toEqual(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('unmarkAsReserved()', () => {
|
|
||||||
it('should call setReserved with false', () => {
|
|
||||||
jest.spyOn(controller, 'setReserved');
|
|
||||||
|
|
||||||
controller.unmarkAsReserved(false);
|
|
||||||
|
|
||||||
expect(controller.setReserved).toHaveBeenCalledWith(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('markAsReserved()', () => {
|
|
||||||
it('should call setReserved with true', () => {
|
|
||||||
jest.spyOn(controller, 'setReserved');
|
|
||||||
|
|
||||||
controller.markAsReserved(true);
|
|
||||||
|
|
||||||
expect(controller.setReserved).toHaveBeenCalledWith(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('setReserved()', () => {
|
|
||||||
it('should call getCheckedLines, $.index.accept and make a query ', () => {
|
|
||||||
const sale = controller.sales[0];
|
|
||||||
sale.checked = true;
|
|
||||||
let expectedRequest = {
|
|
||||||
sales: [sale],
|
|
||||||
ticketFk: ticket.id,
|
|
||||||
reserved: false
|
|
||||||
};
|
|
||||||
|
|
||||||
$httpBackend.expectPOST(`Sales/reserve`, expectedRequest).respond();
|
|
||||||
$httpBackend.whenGET(`Tickets/1/subtotal`).respond(200, 227.5);
|
|
||||||
$httpBackend.whenGET(`Tickets/1/getVAT`).respond(200, 10.5);
|
|
||||||
$httpBackend.whenGET(`Tickets/1/isEditable`).respond();
|
|
||||||
$httpBackend.whenGET(`Tickets/1/isLocked`).respond();
|
|
||||||
controller.unmarkAsReserved(false);
|
|
||||||
$httpBackend.flush();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('showSMSDialog()', () => {
|
|
||||||
it('should open an SMS dialog with specified data', () => {
|
|
||||||
jest.spyOn(controller.$.sms, 'open');
|
|
||||||
|
|
||||||
controller.sales[0].checked = true;
|
|
||||||
controller.showSMSDialog();
|
|
||||||
|
|
||||||
expect(controller.$.sms.open).toHaveBeenCalledWith();
|
|
||||||
expect(controller.newSMS.destination).toEqual(111111111);
|
|
||||||
expect(controller.newSMS.message).not.toEqual('');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('onChangeQuantity()', () => {
|
|
||||||
it('should not call addSale() or updateQuantity() methods', () => {
|
|
||||||
jest.spyOn(controller, 'addSale');
|
|
||||||
jest.spyOn(controller, 'updateQuantity');
|
|
||||||
|
|
||||||
const sale = {itemFk: 4};
|
|
||||||
controller.onChangeQuantity(sale);
|
|
||||||
|
|
||||||
expect(controller.addSale).not.toHaveBeenCalled();
|
|
||||||
expect(controller.updateQuantity).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call addSale() method', () => {
|
|
||||||
jest.spyOn(controller, 'addSale');
|
|
||||||
|
|
||||||
const sale = {itemFk: 4, quantity: 5};
|
|
||||||
controller.onChangeQuantity(sale);
|
|
||||||
|
|
||||||
expect(controller.addSale).toHaveBeenCalledWith(sale);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call updateQuantity() method', () => {
|
|
||||||
jest.spyOn(controller, 'updateQuantity');
|
|
||||||
jest.spyOn(controller, 'addSale');
|
|
||||||
|
|
||||||
const sale = {id: 1, itemFk: 4, quantity: 5};
|
|
||||||
controller.onChangeQuantity(sale);
|
|
||||||
|
|
||||||
expect(controller.addSale).not.toHaveBeenCalled();
|
|
||||||
expect(controller.updateQuantity).toHaveBeenCalledWith(sale);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('updateQuantity()', () => {
|
|
||||||
it('should make a POST query saving sale quantity', () => {
|
|
||||||
jest.spyOn(controller.$.watcher, 'updateOriginalData');
|
|
||||||
const data = {quantity: 10};
|
|
||||||
const sale = sales[0];
|
|
||||||
sale.quantity = 10;
|
|
||||||
|
|
||||||
$httpBackend.when('POST', `Sales/4/updateQuantity`, data).respond();
|
|
||||||
$httpBackend.expect('POST', `Sales/4/updateQuantity`, data).respond();
|
|
||||||
$httpBackend.whenGET(`Tickets/1/subtotal`).respond(200, 227.5);
|
|
||||||
$httpBackend.whenGET(`Tickets/1/getVAT`).respond(200, 10.5);
|
|
||||||
$httpBackend.whenGET(`Tickets/1/isEditable`).respond();
|
|
||||||
$httpBackend.whenGET(`Tickets/1/isLocked`).respond();
|
|
||||||
controller.updateQuantity(sale);
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.$.watcher.updateOriginalData).toHaveBeenCalledWith();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('updateConcept()', () => {
|
|
||||||
it('should make a POST query saving sale concept', () => {
|
|
||||||
jest.spyOn(controller.$.watcher, 'updateOriginalData');
|
|
||||||
const data = {newConcept: 'My new weapon'};
|
|
||||||
const sale = sales[0];
|
|
||||||
sale.concept = 'My new weapon';
|
|
||||||
|
|
||||||
$httpBackend.when('POST', `Sales/4/updateConcept`, data).respond();
|
|
||||||
$httpBackend.expect('POST', `Sales/4/updateConcept`, data).respond();
|
|
||||||
$httpBackend.whenGET(`Tickets/1/subtotal`).respond(200, 227.5);
|
|
||||||
$httpBackend.whenGET(`Tickets/1/getVAT`).respond(200, 10.5);
|
|
||||||
$httpBackend.whenGET(`Tickets/1/isEditable`).respond();
|
|
||||||
$httpBackend.whenGET(`Tickets/1/isLocked`).respond();
|
|
||||||
controller.updateConcept(sale);
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.$.watcher.updateOriginalData).toHaveBeenCalledWith();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('addSale()', () => {
|
|
||||||
it('should make a POST query adding a new sale', () => {
|
|
||||||
jest.spyOn(controller.$.watcher, 'updateOriginalData');
|
|
||||||
const newSale = {itemFk: 4, quantity: 10};
|
|
||||||
const params = {itemId: 4, quantity: 10};
|
|
||||||
|
|
||||||
const expectedResult = {
|
|
||||||
id: 30,
|
|
||||||
quantity: 10,
|
|
||||||
discount: 0,
|
|
||||||
price: 0,
|
|
||||||
itemFk: 4,
|
|
||||||
item: {
|
|
||||||
subName: 'Item subName',
|
|
||||||
image: '30.png'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$httpBackend.when('POST', `tickets/1/addSale`, params).respond(expectedResult);
|
|
||||||
$httpBackend.expect('POST', `tickets/1/addSale`, params).respond(expectedResult);
|
|
||||||
$httpBackend.whenGET(`Tickets/1/subtotal`).respond(200, 227.5);
|
|
||||||
$httpBackend.whenGET(`Tickets/1/getVAT`).respond(200, 10.5);
|
|
||||||
$httpBackend.whenGET(`Tickets/1/isEditable`).respond();
|
|
||||||
$httpBackend.whenGET(`Tickets/1/isLocked`).respond();
|
|
||||||
controller.addSale(newSale);
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.$.watcher.updateOriginalData).toHaveBeenCalledWith();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('transferSales()', () => {
|
|
||||||
it('should transfer sales to a ticket', () => {
|
|
||||||
jest.spyOn(controller, 'goToTicket');
|
|
||||||
controller.transfer = {
|
|
||||||
sales: [{id: 1, itemFk: 1}, {id: 2, itemFk: 4}]
|
|
||||||
};
|
|
||||||
|
|
||||||
const expectedResponse = {id: 13};
|
|
||||||
const params = {
|
|
||||||
ticketId: 13,
|
|
||||||
sales: controller.transfer.sales
|
|
||||||
};
|
|
||||||
|
|
||||||
$httpBackend.when('POST', `tickets/1/transferSales`, params).respond(expectedResponse);
|
|
||||||
$httpBackend.expect('POST', `tickets/1/transferSales`, params).respond(expectedResponse);
|
|
||||||
$httpBackend.whenGET(`Tickets/1/subtotal`).respond(200, 227.5);
|
|
||||||
$httpBackend.whenGET(`Tickets/1/getVAT`).respond(200, 10.5);
|
|
||||||
$httpBackend.whenGET(`Tickets/1/isEditable`).respond();
|
|
||||||
$httpBackend.whenGET(`Tickets/1/isLocked`).respond();
|
|
||||||
controller.transferSales(13);
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.goToTicket).toHaveBeenCalledWith(13);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('setTransferParams()', () => {
|
|
||||||
it('should define the transfer object on the controller and its default properties', () => {
|
|
||||||
let sale = controller.sales[0];
|
|
||||||
sale.checked = true;
|
|
||||||
const expectedResponse = [sale];
|
|
||||||
|
|
||||||
$httpBackend.when('GET', `clients/101/lastActiveTickets?ticketId=1`).respond(expectedResponse);
|
|
||||||
$httpBackend.expect('GET', `clients/101/lastActiveTickets?ticketId=1`).respond(expectedResponse);
|
|
||||||
$httpBackend.whenGET(`Tickets/1/subtotal`).respond(200, 227.5);
|
|
||||||
$httpBackend.whenGET(`Tickets/1/getVAT`).respond(200, 10.5);
|
|
||||||
$httpBackend.whenGET(`Tickets/1/isEditable`).respond();
|
|
||||||
$httpBackend.whenGET(`Tickets/1/isLocked`).respond();
|
|
||||||
controller.setTransferParams();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
const lastActiveTickets = controller.transfer.lastActiveTickets;
|
|
||||||
|
|
||||||
expect(controller.transfer).toBeDefined();
|
|
||||||
expect(lastActiveTickets).toBeDefined();
|
|
||||||
expect(lastActiveTickets[0].id).toEqual(4);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('newOrderFromTicket()', () => {
|
|
||||||
it('should make an HTTP post query and then open the new order on a new tab', () => {
|
|
||||||
const params = {ticketFk: 1};
|
|
||||||
const expectedResponse = {id: 123};
|
|
||||||
|
|
||||||
window.open = jasmine.createSpy('open');
|
|
||||||
controller.$state.href = jasmine.createSpy('href')
|
|
||||||
.and.returnValue('/somePath');
|
|
||||||
|
|
||||||
$httpBackend.when('POST', `Orders/newFromTicket`, params).respond(expectedResponse);
|
|
||||||
$httpBackend.expect('POST', `Orders/newFromTicket`, params).respond(expectedResponse);
|
|
||||||
$httpBackend.whenGET(`Tickets/1/subtotal`).respond(200, 227.5);
|
|
||||||
$httpBackend.whenGET(`Tickets/1/getVAT`).respond(200, 10.5);
|
|
||||||
$httpBackend.whenGET(`Tickets/1/isEditable`).respond();
|
|
||||||
$httpBackend.whenGET(`Tickets/1/isLocked`).respond();
|
|
||||||
controller.newOrderFromTicket();
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(window.open).toHaveBeenCalledWith('/somePath', '_blank');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('hasOneSaleSelected()', () => {
|
|
||||||
it('should return true if just one sale is selected', () => {
|
|
||||||
controller.sales[0].checked = true;
|
|
||||||
|
|
||||||
expect(controller.hasOneSaleSelected()).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('calculateSalePrice()', () => {
|
|
||||||
it('should make an HTTP post query ', () => {
|
|
||||||
controller.sales[0].checked = true;
|
|
||||||
|
|
||||||
$httpBackend.when('POST', `Sales/4/recalculatePrice`).respond(200);
|
|
||||||
$httpBackend.whenGET(`Tickets/1/subtotal`).respond(200, 227.5);
|
|
||||||
$httpBackend.whenGET(`Tickets/1/getVAT`).respond(200, 10.5);
|
|
||||||
$httpBackend.whenGET(`Tickets/1/isEditable`).respond();
|
|
||||||
$httpBackend.whenGET(`Tickets/1/isLocked`).respond();
|
|
||||||
|
|
||||||
controller.calculateSalePrice();
|
|
||||||
$httpBackend.flush();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -14,16 +14,13 @@ module.exports = Self => {
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.getCurrentWorkerMana = async ctx => {
|
Self.getCurrentWorkerMana = async ctx => {
|
||||||
let currentClientId = ctx.req.accessToken.userId;
|
let userId = ctx.req.accessToken.userId;
|
||||||
let currentWorker = await Self.app.models.Worker.findOne({
|
|
||||||
where: {userFk: currentClientId},
|
let workerMana = await Self.app.models.WorkerMana.findOne({
|
||||||
fields: 'id'
|
where: {workerFk: userId},
|
||||||
});
|
|
||||||
let currentWorkerMana = await Self.app.models.WorkerMana.findOne({
|
|
||||||
where: {workerFk: currentWorker.id},
|
|
||||||
fields: 'amount'
|
fields: 'amount'
|
||||||
});
|
});
|
||||||
|
|
||||||
return currentWorkerMana ? currentWorkerMana.amount : 0;
|
return workerMana ? workerMana.amount : 0;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,7 +32,7 @@ module.exports = Self => {
|
||||||
zoneFk: id
|
zoneFk: id
|
||||||
},
|
},
|
||||||
include: {
|
include: {
|
||||||
relation: 'state',
|
relation: 'ticketState',
|
||||||
scope: {
|
scope: {
|
||||||
fields: ['id', 'alertLevel', 'code']
|
fields: ['id', 'alertLevel', 'code']
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ module.exports = Self => {
|
||||||
ticketList.forEach(ticket => {
|
ticketList.forEach(ticket => {
|
||||||
promises.push(ticket.updateAttributes({zoneFk: null}, options));
|
promises.push(ticket.updateAttributes({zoneFk: null}, options));
|
||||||
|
|
||||||
if (ticket.state().alertLevel == 0 && ticket.shipped >= today) {
|
if (ticket.ticketState().alertLevel == 0 && ticket.shipped >= today) {
|
||||||
promises.push(models.TicketTracking.create({
|
promises.push(models.TicketTracking.create({
|
||||||
ticketFk: ticket.id,
|
ticketFk: ticket.id,
|
||||||
stateFk: fixingState.id,
|
stateFk: fixingState.id,
|
||||||
|
|
|
@ -33,6 +33,7 @@ describe('component vnZoneCalendar', () => {
|
||||||
describe('step()', () => {
|
describe('step()', () => {
|
||||||
it('should set the date month to 4 months backwards', () => {
|
it('should set the date month to 4 months backwards', () => {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
|
now.setDate(15);
|
||||||
now.setMonth(now.getMonth() - 4);
|
now.setMonth(now.getMonth() - 4);
|
||||||
|
|
||||||
controller.step(-1);
|
controller.step(-1);
|
||||||
|
@ -45,6 +46,7 @@ describe('component vnZoneCalendar', () => {
|
||||||
|
|
||||||
it('should set the date month to 4 months forwards', () => {
|
it('should set the date month to 4 months forwards', () => {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
|
now.setDate(15);
|
||||||
now.setMonth(now.getMonth() + 4);
|
now.setMonth(now.getMonth() + 4);
|
||||||
|
|
||||||
controller.step(1);
|
controller.step(1);
|
||||||
|
|
Loading…
Reference in New Issue