1368-ticket_sale_refactor #327

Merged
joan merged 20 commits from 1368-ticket_sale_refactor into dev 2020-07-02 12:58:12 +00:00
13 changed files with 136 additions and 153 deletions
Showing only changes of commit b40e09a6cb - Show all commits

View File

@ -1,4 +1,5 @@
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');

View File

@ -4,17 +4,15 @@ module.exports = Self => {
Self.remoteMethodCtx('createFromSales', {
description: 'Create a claim',
accepts: [{
arg: 'claim',
type: 'object',
arg: 'ticketId',
type: 'Number',
required: true,
description: ' newTicketFk, clientFk, ticketCreated',
http: {source: 'body'}
description: 'The origin ticket id'
}, {
arg: 'sales',
type: 'object',
type: ['Object'],
required: true,
description: '[sales IDs]',
http: {source: 'body'}
description: 'The claimed sales'
}],
returns: {
type: 'object',
@ -26,28 +24,27 @@ module.exports = Self => {
}
});
Self.createFromSales = async(ctx, params) => {
let models = Self.app.models;
let userId = ctx.req.accessToken.userId;
let tx = await Self.beginTransaction({});
Self.createFromSales = async(ctx, ticketId, sales) => {
const models = Self.app.models;
const userId = ctx.req.accessToken.userId;
const tx = await Self.beginTransaction({});
try {
let options = {transaction: tx};
const ticketId = params.claim.ticketFk;
const ticket = await models.Ticket.findById(ticketId, null, options);
if (ticket.isDeleted)
throw new UserError(`You can't create a claim for a removed ticket`);
const worker = await models.Worker.findOne({
where: {userFk: userId}
const newClaim = await Self.create({
ticketFk: ticketId,
clientFk: ticket.clientFk,
ticketCreated: ticket.shipped,
workerFk: userId
}, options);
const promises = [];
params.claim.workerFk = worker.id;
let newClaim = await Self.create(params.claim, options);
let promises = [];
for (const sale of params.sales) {
for (const sale of sales) {
const newClaimBeginning = models.ClaimBeginning.create({
saleFk: sale.id,
claimFk: newClaim.id,

View File

@ -1,7 +1,6 @@
const app = require('vn-loopback/server/server');
describe('Claim Create', () => {
let newDate = new Date();
describe('Claim createFromSales()', () => {
let createdClaimFk;
afterAll(async done => {
@ -10,28 +9,18 @@ describe('Claim Create', () => {
done();
});
let newClaim = {
ticketFk: 2,
clientFk: 101,
ticketCreated: newDate
};
let newSale = [{
const ticketId = 2;
const newSale = [{
id: 3,
instance: 0,
quantity: 10
}];
let params = {claim: newClaim, sales: newSale};
let ctx = {req: {accessToken: {userId: 1}}};
const ctx = {req: {accessToken: {userId: 1}}};
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.clientFk).toEqual(newClaim.clientFk);
expect(claim.ticketCreated).toEqual(newClaim.ticketCreated);
expect(claim.workerFk).toEqual(newClaim.workerFk);
expect(claim.ticketFk).toEqual(ticketId);
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() => {
let error;
await app.models.Claim.createFromSales(ctx, params)
await app.models.Claim.createFromSales(ctx, ticketId, newSale)
.catch(e => {
error = e;

View File

@ -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);
};
};

View File

@ -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);
};
};

View File

@ -6,28 +6,43 @@ module.exports = Self => {
description: 'Change the state of a ticket',
accessType: 'WRITE',
accepts: [{
arg: 'params',
type: 'object',
arg: 'ticketId',
type: 'Number',
required: true,
description: '[sales IDs], ticketFk, reserved',
http: {source: 'body'}
description: 'The ticket id'
}, {
arg: 'sales',
type: ['Object'],
required: true,
description: 'The sale to reserve'
},
{
arg: 'reserved',
type: 'Boolean',
required: true
}],
returns: {
type: 'string',
type: ['Object'],
root: true
},
http: {
path: `/reserve`,
verb: 'post'
verb: 'POST'
}
});
Self.reserve = async(ctx, params) => {
let thisTicketIsEditable = await Self.app.models.Ticket.isEditable(ctx, params.ticketFk);
if (!thisTicketIsEditable)
Self.reserve = async(ctx, ticketId, sales, reserved) => {
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`);
for (let i = 0; i < params.sales.length; i++)
await Self.app.models.Sale.update({id: params.sales[i].id}, {reserved: params.reserved});
const promises = [];
for (let sale of sales) {
const reservedSale = models.Sale.update({id: sale.id}, {reserved: reserved});
promises.push(reservedSale);
}
return Promise.all(promises);
};
};

View File

@ -1,6 +1,6 @@
const app = require('vn-loopback/server/server');
describe('sale removes()', () => {
describe('sale deleteSales()', () => {
let sale;
let newsale;
@ -16,13 +16,11 @@ describe('sale removes()', () => {
let ctx = {req: {accessToken: {userId: 9}}};
let error;
let params = {
sales: [{id: 1, instance: 0}, {id: 2, instance: 1}],
actualTicketFk: 2
};
const sales = [{id: 1, instance: 0}, {id: 2, instance: 1}];
const ticketId = 2;
try {
await app.models.Sale.removes(ctx, params);
await app.models.Sale.deleteSales(ctx, sales, ticketId);
} catch (e) {
error = e;
}
@ -32,12 +30,11 @@ describe('sale removes()', () => {
it('should delete the sales', async() => {
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}]);
});

View File

@ -1,6 +1,7 @@
const app = require('vn-loopback/server/server');
describe('sale reserve()', () => {
const ctx = {req: {accessToken: {userId: 9}}};
afterAll(async done => {
let ctx = {req: {accessToken: {userId: 9}}};
let params = {
@ -17,13 +18,12 @@ describe('sale reserve()', () => {
});
it('should throw an error if the ticket can not be modified', async() => {
let ctx = {req: {accessToken: {userId: 9}}};
let error;
let params = {ticketFk: 2,
sales: [{id: 5}],
reserved: false};
const ticketId = 2;
const sales = [{id: 5}];
const reserved = false;
await app.models.Sale.reserve(ctx, params)
await app.models.Sale.reserve(ctx, ticketId, sales, reserved)
.catch(response => {
expect(response).toEqual(new Error(`The sales of this ticket can't be modified`));
error = response;
@ -38,18 +38,13 @@ describe('sale reserve()', () => {
expect(originalTicketSales[0].reserved).toEqual(0);
expect(originalTicketSales[1].reserved).toEqual(0);
let ctx = {req: {accessToken: {userId: 9}}};
let params = {
sales: [
{id: 7},
{id: 8}],
ticketFk: 11,
reserved: true
};
const ticketId = 11;
const sales = [{id: 7}, {id: 8}];
const 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[1].reserved).toEqual(1);

View File

@ -1,12 +1,12 @@
module.exports = Self => {
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',
accepts: [{
arg: 'id',
type: 'number',
required: true,
description: 'ticket id',
description: 'The ticket id',
http: {source: 'path'}
}],
returns: {
@ -18,8 +18,9 @@ module.exports = Self => {
}
});
Self.getSalesPersonMana = async ticketFk => {
let ticket = await Self.app.models.Ticket.findById(ticketFk, {
Self.getSalesPersonMana = async ticketId => {
const models = Self.app.models;
const ticket = await models.Ticket.findById(ticketId, {
include: [{
relation: 'client',
scope: {
@ -29,10 +30,12 @@ module.exports = Self => {
fields: ['id', 'clientFk']
});
if (!ticket)
return 0;
if (!ticket) 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;
};

View File

@ -1,7 +1,7 @@
module.exports = Self => {
require('../methods/sale/getClaimableFromTicket')(Self);
require('../methods/sale/reserve')(Self);
require('../methods/sale/removes')(Self);
require('../methods/sale/deleteSales')(Self);
require('../methods/sale/updatePrice')(Self);
require('../methods/sale/updateQuantity')(Self);
require('../methods/sale/updateConcept')(Self);

View File

@ -145,8 +145,8 @@ class Controller extends Section {
removeSales() {
const sales = this.selectedValidSales();
const params = {sales: sales, actualTicketFk: this.ticket.id};
this.$http.post(`Sales/removes`, params).then(() => {
const params = {sales: sales, ticketId: this.ticket.id};
this.$http.post(`Sales/deleteSales`, params).then(() => {
this.removeSelectedSales();
this.vnApp.showSuccess(this.$t('Data saved!'));
}).finally(() => this.resetChanges());
@ -164,15 +164,7 @@ class Controller extends Section {
createClaim() {
const sales = this.selectedValidSales();
const params = {
claim: {
ticketFk: this.ticket.id,
clientFk: this.ticket.clientFk,
ticketCreated: this.ticket.shipped
},
sales: sales
};
const params = {ticketId: this.ticket.id, sales: sales};
this.resetChanges();
this.$http.post(`Claims/createFromSales`, params)
.then(res => this.$state.go('claim.card.basicData', {id: res.data.id}));
@ -339,21 +331,11 @@ class Controller extends Section {
}
setReserved(reserved) {
let selectedSales = this.selectedValidSales();
let params = {sales: selectedSales, ticketFk: this.ticket.id, reserved: reserved};
let reservedSales = new Map();
this.$http.post(`Sales/reserve`, params).then(res => {
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;
const selectedSales = this.selectedValidSales();
const params = {ticketId: this.ticket.id, sales: selectedSales, reserved: reserved};
this.$http.post(`Sales/reserve`, params).then(() => {
selectedSales.forEach(sale => {
sale.reserved = reserved;
});
}).finally(() => this.resetChanges());
}

View File

@ -261,8 +261,8 @@ describe('Ticket', () => {
const firstSale = controller.sales[0];
firstSale.checked = true;
const expectedParams = {sales: [firstSale], actualTicketFk: 1};
$httpBackend.expect('POST', `Sales/removes`, expectedParams).respond(200);
const expectedParams = {sales: [firstSale], ticketId: 1};
$httpBackend.expect('POST', `Sales/deleteSales`, expectedParams).respond(200);
controller.removeSales();
$httpBackend.flush();
@ -300,11 +300,7 @@ describe('Ticket', () => {
const firstSale = controller.sales[0];
firstSale.checked = true;
const expectedParams = {
claim: {ticketFk: 1, clientFk: 101, ticketCreated: 1},
sales: [firstSale]
};
const expectedParams = {ticketId: 1, sales: [firstSale]};
$httpBackend.expect('POST', `Claims/createFromSales`, expectedParams).respond(200, {id: 1});
controller.createClaim();
$httpBackend.flush();
@ -544,7 +540,7 @@ describe('Ticket', () => {
selectedSale.checked = true;
const expectedParams = {
sales: [selectedSale],
ticketFk: 1,
ticketId: 1,
reserved: false
};

View File

@ -32,7 +32,7 @@ module.exports = Self => {
zoneFk: id
},
include: {
relation: 'state',
relation: 'ticketState',
scope: {
fields: ['id', 'alertLevel', 'code']
}
@ -49,7 +49,7 @@ module.exports = Self => {
ticketList.forEach(ticket => {
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({
ticketFk: ticket.id,
stateFk: fixingState.id,