This commit is contained in:
Bernat 2019-09-03 14:38:40 +02:00
commit fc872a2b21
11 changed files with 88 additions and 84 deletions

View File

@ -0,0 +1,14 @@
DROP TRIGGER IF EXISTS `vn2008`.`ticket_afterUpdate`;
DELIMITER $$
CREATE DEFINER=`root`@`%` TRIGGER `vn2008`.`ticket_afterUpdate`
AFTER UPDATE ON `Tickets`
FOR EACH ROW
BEGIN
IF !(NEW.Id_Ticket <=> OLD.Id_Ticket)
OR !(NEW.warehouse_id <=> OLD.warehouse_id)
OR !(NEW.Fecha <=> OLD.Fecha) THEN
CALL stock.log_add('ticket', NEW.Id_Ticket, OLD.Id_Ticket);
END IF;
END$$
DELIMITER ;

View File

@ -1,45 +0,0 @@
const UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
Self.remoteMethodCtx('delete', {
description: 'Sets the isDeleted value of a ticket to 1',
accessType: 'WRITE',
accepts: [{
arg: 'ticketFk',
type: 'Object',
required: true,
description: 'TicketFk',
http: {source: 'body'}
}],
returns: {
type: 'string',
root: true
},
http: {
path: `/delete`,
verb: 'post'
}
});
Self.delete = async(ctx, params) => {
const transaction = await Self.beginTransaction({});
try {
let claimOfATicket = await Self.app.models.Claim.findOne({where: {ticketFk: params.id}});
if (claimOfATicket)
throw new UserError('You must delete the claim id %d first', 'DELETE_CLAIM_FIRST', claimOfATicket.id);
let currentTicket = await Self.app.models.Ticket.findById(params.id);
await currentTicket.updateAttributes({isDeleted: true});
let userId = ctx.req.accessToken.userId;
let worker = await Self.app.models.Worker.findOne({where: {userFk: userId}});
params.workerFk = worker.id;
let state = await Self.app.models.State.findOne({where: {code: 'ERASED'}});
return await Self.app.models.TicketTracking.create({ticketFk: params.id, stateFk: state.id, workerFk: params.workerFk});
} catch (e) {
await transaction.rollback();
throw e;
}
};
};

View File

@ -53,7 +53,7 @@ module.exports = Self => {
Self.priceDifference = async(ctx, id, landed, addressId, agencyModeId, zoneId, warehouseId) => {
const models = Self.app.models;
const isEditable = await models.Ticket.isEditable(ctx, id);
const isEditable = await Self.isEditable(ctx, id);
const userId = ctx.req.accessToken.userId;
if (!isEditable)
@ -67,19 +67,18 @@ module.exports = Self => {
throw new UserError(`You don't have privileges to change the zone`);
}
let salesObj = {};
salesObj.items = await models.Sale.find({
where: {
ticketFk: id
},
order: 'concept ASC',
include: [{
relation: 'item'
}]
});
salesObj.totalUnitPrice = 0.00;
salesObj.totalNewPrice = 0.00;
salesObj.totalDifference = 0.00;
let salesObj = {
items: await models.Sale.find({
where: {
ticketFk: id
},
order: 'concept ASC',
include: 'item'
}),
totalUnitPrice: 0.00,
totalNewPrice: 0.00,
totalDifference: 0.00,
};
const query = `CALL vn.ticket_priceDifference(?, ?, ?, ?, ?)`;
const args = [id, landed, addressId, zoneId, warehouseId];
@ -91,20 +90,25 @@ module.exports = Self => {
map.set(difComponent.saleFk, difComponent);
});
function round(value) {
return Math.round(value * 100) / 100;
}
salesObj.items.forEach(sale => {
const difComponent = map.get(sale.id);
if (difComponent) {
sale.component = difComponent;
salesObj.totalNewPrice += sale.component.newPrice;
salesObj.totalDifference += sale.component.difference;
salesObj.totalUnitPrice = Math.round(salesObj.totalUnitPrice * 100) / 100;
salesObj.totalNewPrice = Math.round(salesObj.totalNewPrice * 100) / 100;
salesObj.totalDifference += difComponent.difference;
salesObj.totalDifference = round(salesObj.totalDifference);
salesObj.totalNewPrice += difComponent.newPrice;
salesObj.totalNewPrice = round(salesObj.totalNewPrice);
}
salesObj.totalUnitPrice += sale.price;
salesObj.totalDifference = Math.round(salesObj.totalDifference * 100) / 100;
salesObj.totalUnitPrice = round(salesObj.totalUnitPrice);
});
return salesObj;

View File

@ -0,0 +1,36 @@
const UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
Self.remoteMethod('setDeleted', {
description: 'Sets true the isDeleted value of a ticket',
accessType: 'WRITE',
accepts: [{
arg: 'id',
type: 'Number',
required: true,
description: 'The ticket id',
http: {source: 'path'}
}],
returns: {
type: 'string',
root: true
},
http: {
path: `/:id/setDeleted`,
verb: 'post'
}
});
Self.setDeleted = async id => {
try {
let claimOfATicket = await Self.app.models.Claim.findOne({where: {ticketFk: id}});
if (claimOfATicket)
throw new UserError('You must delete the claim id %d first', 'DELETE_CLAIM_FIRST', claimOfATicket.id);
let currentTicket = await Self.app.models.Ticket.findById(id);
return await currentTicket.updateAttributes({isDeleted: true});
} catch (e) {
throw e;
}
};
};

View File

@ -21,25 +21,20 @@ describe('ticket deleted()', () => {
expect(ticket.isDeleted).toEqual(false);
});
it('should set a ticket to deleted and log the change on TicketState table', async() => {
let ctx = {req: {accessToken: {userId: 9}}};
let params = {id: ticket.id};
await app.models.Ticket.delete(ctx, params);
it('should set a ticket to deleted', async() => {
await app.models.Ticket.setDeleted(ticket.id);
let deletedTicket = await app.models.Ticket.findOne({where: {id: ticket.id}, fields: ['isDeleted']});
let changedState = await app.models.TicketState.findOne({where: {ticketFk: ticket.id}});
expect(deletedTicket.isDeleted).toEqual(true);
expect(changedState.stateFk).toEqual(17);
});
it('should throw an error if the given ticket has a claim', async() => {
let ctx = {req: {accessToken: {userId: 9}}};
let params = {id: 16};
let ticketId = 16;
let error;
try {
await app.models.Ticket.delete(ctx, params);
await app.models.Ticket.setDeleted(ticketId);
} catch (e) {
error = e;
}

View File

@ -11,7 +11,7 @@ module.exports = Self => {
require('../methods/ticket/componentUpdate')(Self);
require('../methods/ticket/new')(Self);
require('../methods/ticket/isEditable')(Self);
require('../methods/ticket/delete')(Self);
require('../methods/ticket/setDeleted')(Self);
require('../methods/ticket/getVAT')(Self);
require('../methods/ticket/getSales')(Self);
require('../methods/ticket/getSalesPersonMana')(Self);

View File

@ -77,11 +77,5 @@
</tpl-item>
</vn-autocomplete>
</vn-horizontal>
<vn-horizontal>
<vn-check vn-one
label="Deleted"
field="$ctrl.ticket.isDeleted">
</vn-check>
</vn-horizontal>
</vn-card>
</form>

View File

@ -66,6 +66,11 @@
icon="icon-no036"
ng-class="{bright: $ctrl.ticket.client.isTaxDataChecked == false}">
</vn-icon>
<vn-icon vn-one
vn-tooltip="Deleted ticket"
icon="warning"
ng-class="{bright: $ctrl.ticket.isDeleted == true}">
</vn-icon>
</div>
<div class="quicklinks">
<a ng-if="$ctrl.quicklinks.btnOne"

View File

@ -126,8 +126,8 @@ class Controller {
deleteTicket(response) {
if (response === 'ACCEPT') {
let params = {id: this.ticket.id};
this.$http.post(`/ticket/api/Tickets/delete`, params).then(() => {
const query = `/api/Tickets/${this.ticket.id}/setDeleted`;
this.$http.post(query).then(() => {
this.$state.go('ticket.index');
this.vnApp.showSuccess(this.$translate.instant('Ticket deleted'));
});

View File

@ -62,7 +62,7 @@ describe('Ticket Component vnTicketDescriptor', () => {
spyOn(controller.$state, 'go');
spyOn(controller.vnApp, 'showSuccess');
$httpBackend.expectPOST(`/ticket/api/Tickets/delete`, {id: 2}).respond();
$httpBackend.expectPOST(`/api/Tickets/2/setDeleted`).respond();
controller.deleteTicket('ACCEPT');
$httpBackend.flush();

View File

@ -22,4 +22,5 @@ Are you sure you want to invoice this ticket?: ¿Seguro que quieres facturar est
You are going to regenerate the invoice: Vas a regenerar la factura
Are you sure you want to regenerate the invoice?: ¿Seguro que quieres regenerar la factura?
Invoice sent for a regeneration, will be available in a few minutes: La factura ha sido enviada para ser regenerada, estará disponible en unos minutos
Shipped hour updated: Hora de envio modificada
Shipped hour updated: Hora de envio modificada
Deleted ticket: Ticket eliminado