Merge branch 'dev' of https://git.verdnatura.es/salix into dev
This commit is contained in:
commit
d8dc1f742c
|
@ -41,5 +41,11 @@
|
|||
</vn-card>
|
||||
<vn-button-bar>
|
||||
<vn-submit label="Save"></vn-submit>
|
||||
<button
|
||||
class="mdl-button mdl-button--raised mdl-button--colored"
|
||||
translate
|
||||
ui-sref="clientCard.addresses.list"
|
||||
>Cancel
|
||||
</button>
|
||||
</vn-button-bar>
|
||||
</form>
|
||||
|
|
|
@ -60,6 +60,12 @@
|
|||
</vn-card>
|
||||
<vn-button-bar>
|
||||
<vn-submit label="Create"></vn-submit>
|
||||
<button
|
||||
class="mdl-button mdl-button--raised mdl-button--colored"
|
||||
translate
|
||||
ui-sref="clients"
|
||||
>Cancel
|
||||
</button>
|
||||
</vn-button-bar>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
import './credit-insurance-list';
|
||||
|
||||
describe('Client', () => {
|
||||
describe('Component vnClientCreditInsuranceList', () => {
|
||||
let $componentController;
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
|
||||
beforeEach(() => {
|
||||
angular.mock.module('client');
|
||||
});
|
||||
|
||||
beforeEach(angular.mock.inject((_$componentController_, _$httpBackend_) => {
|
||||
$componentController = _$componentController_;
|
||||
let $state = {params: {classificationId: 1}};
|
||||
$httpBackend = _$httpBackend_;
|
||||
controller = $componentController('vnClientCreditInsuranceList', {$state: $state});
|
||||
}));
|
||||
|
||||
it('should perform a query to GET credit the credit classification', () => {
|
||||
let res = [{finished: 'some value'}];
|
||||
let query = '/client/api/CreditClassifications?filter=%7B%22fields%22%3A%5B%22finished%22%5D%2C%22where%22%3A%7B%22id%22%3A1%7D%7D';
|
||||
|
||||
$httpBackend.whenGET(query).respond(res);
|
||||
$httpBackend.expectGET(query);
|
||||
controller.$onInit();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.isClosed).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -44,6 +44,12 @@
|
|||
</vn-card>
|
||||
<vn-button-bar>
|
||||
<vn-submit label="Create"></vn-submit>
|
||||
<button
|
||||
class="mdl-button mdl-button--raised mdl-button--colored"
|
||||
translate
|
||||
ui-sref="item.index"
|
||||
>Cancel
|
||||
</button>
|
||||
</vn-button-bar>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -29,7 +29,8 @@ export default {
|
|||
email: `${components.vnTextfield}[name="email"]`,
|
||||
salesPersonInput: `vn-autocomplete[field="$ctrl.client.salesPersonFk"] input`,
|
||||
salesBruceBannerOption: `vn-autocomplete[field="$ctrl.client.salesPersonFk"] vn-drop-down ul > li:nth-child(1)`,
|
||||
createButton: `${components.vnSubmit}`
|
||||
createButton: `${components.vnSubmit}`,
|
||||
cancelButton: `button[href="#!/clients"]`
|
||||
},
|
||||
clientBasicData: {
|
||||
basicDataButton: `${components.vnMenuItem}[ui-sref="clientCard.basicData"]`,
|
||||
|
@ -110,7 +111,8 @@ export default {
|
|||
thirdObservationTypeSelectOptionThree: `${components.vnAutocomplete}[field="observation.observationTypeFk"] vn-drop-down ul > li:nth-child(3)`,
|
||||
thirdObservationDescriptionInput: `vn-horizontal:nth-child(5) > vn-textfield[label="Description"] > div > input`,
|
||||
addObservationButton: `${components.vnIcon}[icon="add_circle"]`,
|
||||
saveButton: `${components.vnSubmit}`
|
||||
saveButton: `${components.vnSubmit}`,
|
||||
cancelButton: `button[ui-sref="clientCard.addresses.list"]`
|
||||
},
|
||||
clientWebAccess: {
|
||||
webAccessButton: `${components.vnMenuItem}[ui-sref="clientCard.webAccess"]`,
|
||||
|
@ -168,7 +170,8 @@ export default {
|
|||
intrastatSelectOptionOne: `${components.vnAutocomplete}[field="$ctrl.item.intrastatFk"] vn-drop-down ul > li:nth-child(2)`,
|
||||
originSelect: `${components.vnAutocomplete}[field="$ctrl.item.originFk"] input`,
|
||||
originSelectOptionOne: `${components.vnAutocomplete}[field="$ctrl.item.originFk"] vn-drop-down ul > li:nth-child(2)`,
|
||||
createButton: `${components.vnSubmit}`
|
||||
createButton: `${components.vnSubmit}`,
|
||||
cancelButton: `button[ui-sref="item.index"]`
|
||||
|
||||
},
|
||||
itemBasicData: {
|
||||
|
|
|
@ -42,6 +42,26 @@ describe('Client', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should return to the client index by clicking the cancel button', () => {
|
||||
return nightmare
|
||||
.click(selectors.createClientView.cancelButton)
|
||||
.wait(selectors.clientsIndex.createClientButton)
|
||||
.parsedUrl()
|
||||
.then(url => {
|
||||
expect(url.hash).toEqual('#!/clients');
|
||||
});
|
||||
});
|
||||
|
||||
it('should now access to the create client view by clicking the create-client floating button', () => {
|
||||
return nightmare
|
||||
.click(selectors.clientsIndex.createClientButton)
|
||||
.wait(selectors.createClientView.createButton)
|
||||
.parsedUrl()
|
||||
.then(url => {
|
||||
expect(url.hash).toEqual('#!/create');
|
||||
});
|
||||
});
|
||||
|
||||
it('should receive an error when clicking the create button having all the form fields empty', () => {
|
||||
return nightmare
|
||||
.click(selectors.createClientView.createButton)
|
||||
|
|
|
@ -56,6 +56,26 @@ describe('Client', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it(`should return to the addreses section by clicking the cancel button`, () => {
|
||||
return nightmare
|
||||
.waitToClick(selectors.clientAddresses.cancelButton)
|
||||
.waitForURL('addresses/list')
|
||||
.url()
|
||||
.then(url => {
|
||||
expect(url).toContain('addresses/list');
|
||||
});
|
||||
});
|
||||
|
||||
it(`should now click on the add new address button to access to the new address form`, () => {
|
||||
return nightmare
|
||||
.waitToClick(selectors.clientAddresses.createAddress)
|
||||
.waitForURL('addresses/create')
|
||||
.url()
|
||||
.then(url => {
|
||||
expect(url).toContain('addresses/create');
|
||||
});
|
||||
});
|
||||
|
||||
it('should receive an error after clicking save button as consignee, street and town fields are empty', () => {
|
||||
return nightmare
|
||||
.waitToClick(selectors.clientAddresses.defaultCheckboxInput)
|
||||
|
|
|
@ -41,6 +41,26 @@ describe('Item', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should return to the item index by clickig the cancel button', () => {
|
||||
return nightmare
|
||||
.click(selectors.itemCreateView.cancelButton)
|
||||
.wait(selectors.itemsIndex.createItemButton)
|
||||
.parsedUrl()
|
||||
.then(url => {
|
||||
expect(url.hash).toEqual('#!/item/list');
|
||||
});
|
||||
});
|
||||
|
||||
it('should now access to the create item view by clicking the create floating button', () => {
|
||||
return nightmare
|
||||
.click(selectors.itemsIndex.createItemButton)
|
||||
.wait(selectors.itemCreateView.createButton)
|
||||
.parsedUrl()
|
||||
.then(url => {
|
||||
expect(url.hash).toEqual('#!/item/create');
|
||||
});
|
||||
});
|
||||
|
||||
it('should create the Infinity Gauntlet item', () => {
|
||||
return nightmare
|
||||
.type(selectors.itemCreateView.name, 'Infinity Gauntlet')
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
module.exports = function(Self) {
|
||||
Self.remoteMethod('createWithInsurance', {
|
||||
description: 'Creates both classification and one insurance',
|
||||
accepts: {
|
||||
accepts: [{
|
||||
arg: 'data',
|
||||
type: 'object',
|
||||
http: {source: 'body'}
|
||||
},
|
||||
}, {
|
||||
arg: 'context',
|
||||
type: 'object',
|
||||
http: function(ctx) {
|
||||
return ctx;
|
||||
}
|
||||
}],
|
||||
returns: {
|
||||
root: true,
|
||||
type: 'boolean'
|
||||
|
@ -16,21 +22,23 @@ module.exports = function(Self) {
|
|||
}
|
||||
});
|
||||
|
||||
Self.createWithInsurance = async data => {
|
||||
Self.createWithInsurance = async (data, ctx) => {
|
||||
let transaction = await Self.beginTransaction({});
|
||||
|
||||
try {
|
||||
let classificationSchema = {client: data.clientFk, started: data.started};
|
||||
let newClassification = await Self.create(classificationSchema, {transaction});
|
||||
let CreditInsurance = Self.app.models.CreditInsurance;
|
||||
let insuranceSchema = {
|
||||
creditClassification: newClassification.id,
|
||||
credit: data.credit,
|
||||
grade: data.grade
|
||||
};
|
||||
|
||||
Self.app.models.CreditInsurance.create(insuranceSchema, {transaction});
|
||||
|
||||
let newCreditInsurance = await CreditInsurance.create(insuranceSchema, {transaction});
|
||||
await transaction.commit();
|
||||
await CreditInsurance.messageSend(newCreditInsurance, ctx.req.accessToken);
|
||||
|
||||
return newClassification;
|
||||
} catch (e) {
|
||||
transaction.rollback();
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
}
|
||||
},
|
||||
"relations": {
|
||||
"client": {
|
||||
"customer": {
|
||||
"type": "belongsTo",
|
||||
"model": "Client",
|
||||
"foreignKey": "client"
|
||||
|
|
|
@ -19,4 +19,51 @@ module.exports = function(Self) {
|
|||
message: 'The grade must be an integer greater than or equal to zero',
|
||||
allowNull: true
|
||||
});
|
||||
|
||||
Self.messageSend = async function(data, accessToken) {
|
||||
let filter = {
|
||||
include: {
|
||||
relation: 'classification',
|
||||
scope: {
|
||||
fields: ['client'],
|
||||
include: {
|
||||
relation: 'customer',
|
||||
scope: {
|
||||
fields: ['name', 'salesPersonFk'],
|
||||
include: {
|
||||
relation: 'salesPerson',
|
||||
scope: {
|
||||
fields: 'userFk',
|
||||
include: {
|
||||
relation: 'user',
|
||||
scope: {
|
||||
fields: ['name']
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let ctx = {req: {accessToken: accessToken}};
|
||||
let insurance = await Self.findById(data.id, filter);
|
||||
let customer = insurance.classification().customer();
|
||||
let salesPerson = customer.salesPerson().user().name;
|
||||
let grade = data.grade ? `(Grado ${data.grade})` : '(Sin grado)';
|
||||
let message = {
|
||||
message: `He cambiado el crédito asegurado del cliente "${customer.name}" a ${data.credit} € ${grade}`
|
||||
};
|
||||
|
||||
Self.app.models.Message.send(salesPerson, message, ctx);
|
||||
};
|
||||
|
||||
// Update from transaction misses ctx accessToken.
|
||||
// Fixed passing accessToken from method messageSend()
|
||||
Self.observe('after save', async function(ctx) {
|
||||
if (ctx.options.accessToken)
|
||||
await Self.messageSend(ctx.instance, ctx.options.accessToken);
|
||||
});
|
||||
};
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
module.exports = Self => {
|
||||
Self.remoteMethod('send', {
|
||||
description: 'Send message to user',
|
||||
accessType: 'WRITE',
|
||||
accepts: [{
|
||||
arg: 'recipient',
|
||||
type: 'string',
|
||||
required: true,
|
||||
description: 'The user/alias name',
|
||||
http: {source: 'path'}
|
||||
}, {
|
||||
arg: 'data',
|
||||
type: 'object',
|
||||
required: true,
|
||||
description: 'Message data',
|
||||
http: {source: 'body'}
|
||||
}, {
|
||||
arg: 'context',
|
||||
type: 'object',
|
||||
http: function(ctx) {
|
||||
return ctx;
|
||||
}
|
||||
}],
|
||||
returns: {
|
||||
type: 'boolean',
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/:recipient/send`,
|
||||
verb: 'post'
|
||||
}
|
||||
});
|
||||
|
||||
Self.send = async (recipient, data, ctx) => {
|
||||
let query = `SELECT vn.messageSendWithUser(?, ?, ?) AS sent`;
|
||||
let [result] = await Self.rawSql(query, [ctx.req.accessToken.userId, recipient, data.message]);
|
||||
|
||||
return result;
|
||||
};
|
||||
};
|
|
@ -0,0 +1,12 @@
|
|||
const app = require(`${servicesDir}/client/server/server`);
|
||||
|
||||
describe('message send()', () => {
|
||||
it('should call the send method and return the response', done => {
|
||||
let ctx = {req: {accessToken: {userId: 1}}};
|
||||
app.models.Message.send('salesPerson', {message: 'I changed something'}, ctx)
|
||||
.then(response => {
|
||||
expect(response.sent).toEqual(1);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -10,36 +10,36 @@ module.exports = Self => {
|
|||
limit: params.size,
|
||||
order: params.order || 'concept ASC',
|
||||
include: [{
|
||||
relation: "item",
|
||||
relation: 'item',
|
||||
scope: {
|
||||
include: {
|
||||
relation: "itemTag",
|
||||
relation: 'itemTag',
|
||||
scope: {
|
||||
fields: ["tagFk", "value"],
|
||||
fields: ['tagFk', 'value'],
|
||||
include: {
|
||||
relation: "tag",
|
||||
relation: 'tag',
|
||||
scope: {
|
||||
fields: ["name"]
|
||||
fields: ['name']
|
||||
}
|
||||
},
|
||||
limit: 6
|
||||
}
|
||||
},
|
||||
fields: ["itemFk", "name"]
|
||||
fields: ['itemFk', 'name']
|
||||
}
|
||||
},
|
||||
{
|
||||
relation: "components",
|
||||
relation: 'components',
|
||||
scope: {
|
||||
fields: ["componentFk", "value"],
|
||||
fields: ['componentFk', 'value'],
|
||||
include: {
|
||||
relation: "componentRate",
|
||||
relation: 'componentRate',
|
||||
scope: {
|
||||
fields: ["componentTypeRate", "name"],
|
||||
fields: ['componentTypeRate', 'name'],
|
||||
include: {
|
||||
relation: "componentType",
|
||||
relation: 'componentType',
|
||||
scope: {
|
||||
fields: ["type"]
|
||||
fields: ['type']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,28 +18,28 @@ module.exports = function(Self) {
|
|||
verb: 'post'
|
||||
}
|
||||
});
|
||||
Model[methodName] = async crudStruct => {
|
||||
Model[methodName] = async crudObject => {
|
||||
let promises = [];
|
||||
let tx = await Model.beginTransaction({});
|
||||
let options = {transaction: tx};
|
||||
let transaction = await Model.beginTransaction({});
|
||||
let options = {transaction: transaction};
|
||||
|
||||
try {
|
||||
if (crudStruct.delete && crudStruct.delete.length) {
|
||||
promises.push(Model.destroyAll({id: {inq: crudStruct.delete}}, options));
|
||||
if (crudObject.delete && crudObject.delete.length) {
|
||||
promises.push(Model.destroyAll({id: {inq: crudObject.delete}}, options));
|
||||
}
|
||||
if (crudStruct.create.length) {
|
||||
promises.push(Model.create(crudStruct.create, options));
|
||||
if (crudObject.create.length) {
|
||||
promises.push(Model.create(crudObject.create, options));
|
||||
}
|
||||
if (crudStruct.update.length) {
|
||||
crudStruct.update.forEach(toUpdate => {
|
||||
if (crudObject.update.length) {
|
||||
crudObject.update.forEach(toUpdate => {
|
||||
promises.push(Model.upsert(toUpdate, options));
|
||||
});
|
||||
}
|
||||
await Promise.all(promises);
|
||||
await tx.commit();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw Array.isArray(e) ? e[0] : e;
|
||||
await transaction.commit();
|
||||
} catch (error) {
|
||||
await transaction.rollback();
|
||||
throw Array.isArray(error) ? error[0] : error;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,17 +1,60 @@
|
|||
// const catchErrors = require('../../../../../../services/utils/jasmineHelpers').catchErrors;
|
||||
const app = require('../../../../../item/server/server');
|
||||
|
||||
describe('Model installCrudModel()', () => {
|
||||
it('all models extends installCrudModel propertie', () => {
|
||||
let someModel = app.models.Item;
|
||||
it('should extend installCrudModel properties to any model passed', () => {
|
||||
let exampleModel = app.models.ItemBarcode;
|
||||
|
||||
expect(someModel.installCrudModel).toBeDefined();
|
||||
expect(exampleModel.installCrudModel).toBeDefined();
|
||||
});
|
||||
|
||||
it('installCrudModel() create a new remothed method', () => {
|
||||
let someModel = app.models.Item;
|
||||
someModel.installCrudModel('someCrudMethod');
|
||||
describe('installCrudModel()', () => {
|
||||
it('should create a new remothed method', () => {
|
||||
let exampleModel = app.models.ItemBarcode;
|
||||
exampleModel.installCrudModel('crudItemBarcodes');
|
||||
|
||||
expect(someModel.someCrudMethod).toBeDefined();
|
||||
expect(exampleModel.crudItemBarcodes).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('ItemBarcode crudMethod()', () => {
|
||||
let createdId;
|
||||
it('should create a new barcode', async() => {
|
||||
crudObject = {
|
||||
create: [{code: '500', itemFk: '1'}],
|
||||
update: [],
|
||||
delete: []
|
||||
};
|
||||
await app.models.ItemBarcode.crudItemBarcodes(crudObject);
|
||||
let result = await app.models.ItemBarcode.find({where: {itemFk: 1}});
|
||||
createdId = result[3].id;
|
||||
|
||||
expect(result[3].code).toEqual('500');
|
||||
expect(result.length).toEqual(4);
|
||||
});
|
||||
|
||||
it('should update a barcode', async() => {
|
||||
crudObject = {
|
||||
create: [],
|
||||
update: [{id: createdId, code: '501', itemFk: 1}],
|
||||
delete: []
|
||||
};
|
||||
await app.models.ItemBarcode.crudItemBarcodes(crudObject);
|
||||
let result = await app.models.ItemBarcode.find({where: {itemFk: 1}});
|
||||
|
||||
expect(result[3].code).toEqual('501');
|
||||
expect(result.length).toEqual(4);
|
||||
});
|
||||
|
||||
it('should delete a barcode', async() => {
|
||||
crudObject = {
|
||||
create: [],
|
||||
update: [],
|
||||
delete: [createdId]
|
||||
};
|
||||
await app.models.ItemBarcode.crudItemBarcodes(crudObject);
|
||||
let result = await app.models.ItemBarcode.find({where: {itemFk: 1}});
|
||||
|
||||
expect(result.length).toEqual(3);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
module.exports = Self => {
|
||||
require('../methods/message/send.js')(Self);
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"name": "Message",
|
||||
"base": "VnModel",
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "message"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "Number",
|
||||
"id": true,
|
||||
"description": "Identifier"
|
||||
},
|
||||
"sender": {
|
||||
"type": "String",
|
||||
"required": true
|
||||
},
|
||||
"recipient": {
|
||||
"type": "String",
|
||||
"required": true
|
||||
},
|
||||
"message": {
|
||||
"type": "String"
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
"remitter": {
|
||||
"type": "belongsTo",
|
||||
"model": "User",
|
||||
"foreignKey": "sender"
|
||||
},
|
||||
"receptor": {
|
||||
"type": "belongsTo",
|
||||
"model": "User",
|
||||
"foreignKey": "recipient"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,6 +20,10 @@
|
|||
"name": {
|
||||
"type": "string",
|
||||
"required": true
|
||||
},
|
||||
"userFk": {
|
||||
"type" : "Number",
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
|
|
|
@ -101,5 +101,8 @@
|
|||
},
|
||||
"Producer": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"Message": {
|
||||
"dataSource": "vn"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue