Merge branch 'dev' of https://git.verdnatura.es/salix into dev

This commit is contained in:
Joan Sanchez 2018-09-26 14:15:09 +02:00
commit 0277130077
16 changed files with 193 additions and 22 deletions

View File

@ -15,6 +15,16 @@
</vn-label-value> </vn-label-value>
</div> </div>
</vn-horizontal> </vn-horizontal>
<vn-horizontal>
<vn-tool-bar margin-medium-bottom>
<vn-button
vn-acl="salesAssistant"
label="Import sales"
ng-click="$ctrl.importToNewRefundTicket()"
vn-tooltip="Imports sales details">
</vn-button>
</vn-tool-bar>
</vn-horizontal>
<vn-table model="model"> <vn-table model="model">
<vn-thead> <vn-thead>
<vn-tr> <vn-tr>

View File

@ -59,6 +59,14 @@ class Controller {
}); });
} }
importToNewRefundTicket() {
let query = `claim/api/ClaimBeginnings/${this.$state.params.id}/importToNewRefundTicket`;
this.$http.post(query).then(() => {
this.$.model.refresh();
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
});
}
focusLastInput() { focusLastInput() {
let inputs = document.querySelectorAll("#claimDestinationFk"); let inputs = document.querySelectorAll("#claimDestinationFk");
inputs[inputs.length - 1].querySelector("input").focus(); inputs[inputs.length - 1].querySelector("input").focus();

View File

@ -1,7 +1,7 @@
import './index.js'; import './index.js';
describe('claim', () => { describe('claim', () => {
describe('Component vnClaimDetail', () => { describe('Component vnClaimAction', () => {
let $componentController; let $componentController;
let controller; let controller;
let $httpBackend; let $httpBackend;
@ -11,11 +11,10 @@ describe('claim', () => {
angular.mock.module('claim'); angular.mock.module('claim');
}); });
beforeEach(angular.mock.inject((_$componentController_, _$state_, _$httpBackend_, $rootScope) => { beforeEach(angular.mock.inject((_$componentController_, _$state_, _$httpBackend_) => {
$componentController = _$componentController_; $componentController = _$componentController_;
$httpBackend = _$httpBackend_; $httpBackend = _$httpBackend_;
$httpBackend.when('GET', /\/locale\/\w+\/[a-z]{2}\.json/).respond({}); $httpBackend.when('GET', /\/locale\/\w+\/[a-z]{2}\.json/).respond({});
$httpBackend.when('GET', 'claim/api/Claims/ClaimBeginnings').respond({});
$state = _$state_; $state = _$state_;
$state.params.id = 1; $state.params.id = 1;
@ -104,5 +103,18 @@ describe('claim', () => {
expect(controller.claimedTotal).toEqual(50); expect(controller.claimedTotal).toEqual(50);
}); });
}); });
describe('importToNewRefundTicket()', () => {
it('should perform a post query', () => {
spyOn(controller.$.model, 'refresh');
spyOn(controller.vnApp, 'showSuccess');
$httpBackend.expect('POST', `claim/api/ClaimBeginnings/1/importToNewRefundTicket`).respond({});
controller.importToNewRefundTicket();
$httpBackend.flush();
expect(controller.$.model.refresh).toHaveBeenCalledWith();
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
});
});
}); });
}); });

View File

@ -13,4 +13,3 @@ vn-claim-action {
} }
} }
} }

View File

@ -0,0 +1,129 @@
module.exports = Self => {
Self.remoteMethodCtx('importToNewRefundTicket', {
description: 'Imports lines from claimBeginning to a new ticket with specific shipped, landed dates, agency and company',
accessType: 'WRITE',
accepts: [{
arg: 'id',
type: 'number',
required: true,
description: 'the claim id',
http: {source: 'path'}
}],
returns: {
type: 'string',
root: true
},
http: {
path: `/:id/importToNewRefundTicket`,
verb: 'POST'
}
});
async function addSalesToTicket(salesToRefund, newRefundTicket, transaction) {
let promises = [];
salesToRefund.forEach(sale => {
let formatedSale = {
itemFk: sale.sale().itemFk,
ticketFk: newRefundTicket,
concept: sale.sale().concept,
quantity: -Math.abs(sale.quantity),
price: sale.sale().price,
discount: sale.sale().discount,
reserved: sale.sale().reserved,
isPicked: sale.sale().isPicked,
created: sale.sale().created
};
promises.push(Self.app.models.Sale.create(formatedSale, transaction));
});
return await Promise.all(promises);
}
async function insertIntoClaimEnd(createdSales, claimId, workerId, transaction) {
let promises = [];
createdSales.forEach(sale => {
let formatedSale = {
saleFk: sale.id,
claimFk: claimId,
workerFk: workerId
};
promises.push(Self.app.models.ClaimEnd.create(formatedSale, transaction));
});
return await Promise.all(promises);
}
async function saveObservation(observation, transaction) {
let query = `INSERT INTO vn.ticketObservation(ticketFk, observationTypeFk, description) VALUES(?, ?, ?)
ON DUPLICATE KEY UPDATE description = CONCAT(vn.ticketObservation.description, VALUES(description),' ')`;
await Self.rawSql(query, [
observation.ticketFk,
observation.observationTypeFk,
observation.description
], transaction);
}
Self.importToNewRefundTicket = async(ctx, id) => {
let models = Self.app.models;
let token = ctx.req.accessToken;
let userId = token.userId;
let worker = await models.Worker.findOne({where: {userFk: userId}});
let obsevationType = await models.ObservationType.findOne({where: {description: 'comercial'}});
let agency = await models.AgencyMode.findOne({where: {code: 'refund'}});
let state = await models.State.findOne({where: {code: 'DELIVERED'}});
let filter = {
where: {id: id},
include: [
{
relation: 'ticket',
scope: {
fields: ['id', 'clientFk', 'warehouseFk', 'companyFk', 'addressFk']
}
}
]
};
let claim = await models.Claim.findOne(filter);
let today = new Date();
let params = {
clientFk: claim.ticket().clientFk,
shipped: today,
landed: today,
warehouseFk: claim.ticket().warehouseFk,
companyFk: claim.ticket().companyFk,
addressFk: claim.ticket().addressFk,
agencyModeFk: agency.id,
userId: userId
};
let salesFilter = {
where: {claimFk: id},
include: [
{
relation: 'sale',
scope: {
fields: ['id', 'itemFk', 'concept', 'price', 'discount', 'reserved', 'isPicked', 'created', 'priceFixed', 'isPriceFixed']
}
}
]
};
let transaction = await Self.beginTransaction({});
try {
let newRefundTicket = await models.Ticket.new(params, {transaction: transaction});
let observation = {description: `Reclama ticket: ${claim.ticketFk}`, ticketFk: newRefundTicket, observationTypeFk: obsevationType.id};
await saveObservation(observation, {transaction: transaction});
await models.TicketTracking.create({ticketFk: newRefundTicket, stateFk: state.id, workerFk: worker.id}, {transaction: transaction});
let salesToRefund = await models.ClaimBeginning.find(salesFilter);
let createdSales = await addSalesToTicket(salesToRefund, newRefundTicket, {transaction: transaction});
insertIntoClaimEnd(createdSales, id, worker.id, {transaction: transaction});
await Self.rawSql('CALL vn.ticketCalculateClon(?)', [newRefundTicket], {transaction: transaction});
await transaction.commit();
} catch (e) {
await transaction.rollback();
throw e;
}
};
};

View File

@ -1,6 +1,5 @@
module.exports = Self => { module.exports = Self => {
// Validations require('../methods/claim-beginning/importToNewRefundTicket')(Self);
Self.validatesUniquenessOf('saleFk', { Self.validatesUniquenessOf('saleFk', {
message: `A claim with that sale already exists` message: `A claim with that sale already exists`
}); });

View File

@ -31,6 +31,15 @@
}, },
"ticketFk": { "ticketFk": {
"type": "Number" "type": "Number"
},
"claimStateFk": {
"type": "Number"
},
"clientFk": {
"type": "Number"
},
"workerFk": {
"type": "Number"
} }
}, },
"relations": { "relations": {
@ -48,6 +57,11 @@
"type": "belongsTo", "type": "belongsTo",
"model": "Worker", "model": "Worker",
"foreignKey": "workerFk" "foreignKey": "workerFk"
},
"ticket": {
"type": "belongsTo",
"model": "Ticket",
"foreignKey": "ticketFk"
} }
} }
} }

View File

@ -21,7 +21,7 @@ module.exports = Self => {
} }
}); });
Self.new = async params => { Self.new = async(params, transaction) => {
let existsAddress = await Self.app.models.Address.findOne({where: {id: params.addressFk, clientFk: params.clientFk}}); let existsAddress = await Self.app.models.Address.findOne({where: {id: params.addressFk, clientFk: params.clientFk}});
if (!existsAddress) if (!existsAddress)
throw new UserError(`This address doesn't exist`); throw new UserError(`This address doesn't exist`);
@ -38,7 +38,7 @@ module.exports = Self => {
params.routeFk | null, params.routeFk | null,
params.landed, params.landed,
params.userId params.userId
]); ], transaction);
return result[1][0].newTicketId; return result[1][0].newTicketId;
}; };

View File

@ -1,4 +1,4 @@
const UserError = require('vn-loopback/common/helpers').UserError; const UserError = require(`../helpers`).UserError;
module.exports = Self => { module.exports = Self => {
Self.rewriteDbError(function(err) { Self.rewriteDbError(function(err) {

View File

@ -1,5 +1,5 @@
module.exports = function(Self) { module.exports = function(Self) {
require('../methods/ticket-tracking/changeState')(Self); require('../../../ticket/common/methods/ticket-tracking/changeState')(Self);
Self.validatesPresenceOf('stateFk', {message: 'State cannot be blank'}); Self.validatesPresenceOf('stateFk', {message: 'State cannot be blank'});
}; };

View File

@ -173,10 +173,10 @@ module.exports = function(Self) {
}; };
}; };
Self.rawSql = function(query, params, cb) { Self.rawSql = function(query, params, options = {}, cb) {
var connector = this.dataSource.connector; var connector = this.dataSource.connector;
return new Promise(function(resolve, reject) { return new Promise(function(resolve, reject) {
connector.execute(query, params, function(error, response) { connector.execute(query, params, options, function(error, response) {
if (cb) if (cb)
cb(error, response); cb(error, response);
if (error) if (error)

View File

@ -15,6 +15,15 @@
"ACL": { "ACL": {
"dataSource": "salix" "dataSource": "salix"
}, },
"ObservationType": {
"dataSource": "vn"
},
"TicketObservation": {
"dataSource": "vn"
},
"TicketTracking": {
"dataSource": "vn"
},
"RoleMapping": { "RoleMapping": {
"dataSource": "salix" "dataSource": "salix"
}, },

View File

@ -1,13 +1,4 @@
{ {
"TicketObservation": {
"dataSource": "vn"
},
"ObservationType": {
"dataSource": "vn"
},
"TicketTracking": {
"dataSource": "vn"
},
"TicketPackaging": { "TicketPackaging": {
"dataSource": "vn" "dataSource": "vn"
}, },