Merge pull request '2281 - Added claim pickup checkbox' (#292) from 2281-claim_pickup_checkbox into dev
gitea/salix/pipeline/head This commit looks good Details

Reviewed-by: Carlos Jimenez <carlosjr@verdnatura.es>
This commit is contained in:
Joan Sanchez 2020-06-04 08:37:20 +00:00
commit bfeef77040
15 changed files with 108 additions and 71 deletions

View File

@ -1,7 +1,7 @@
const app = require('vn-loopback/server/server');
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
fdescribe('zone zone_getEvents()', () => {
describe('zone zone_getEvents()', () => {
it(`should return data for a agencyMode with deliveryMethod pickup`, async() => {
let stmts = [];
let stmt;
@ -18,7 +18,6 @@ fdescribe('zone zone_getEvents()', () => {
]);
stmts.push(stmt);
let firstResultIndex = stmts.push(stmt) - 1;
stmts.push('ROLLBACK');

View File

@ -585,6 +585,7 @@ export default {
claimState: 'vn-claim-basic-data vn-autocomplete[ng-model="$ctrl.claim.claimStateFk"]',
responsabilityInputRange: 'vn-range',
observation: 'vn-textarea[ng-model="$ctrl.claim.observation"]',
hasToPickUpCheckbox: 'vn-claim-basic-data vn-check[ng-model="$ctrl.claim.hasToPickUp"]',
saveButton: `button[type=submit]`
},
claimDetail: {
@ -619,8 +620,7 @@ export default {
firstLineDestination: 'vn-claim-action vn-tr:nth-child(1) vn-autocomplete[ng-model="saleClaimed.claimDestinationFk"]',
secondLineDestination: 'vn-claim-action vn-tr:nth-child(2) vn-autocomplete[ng-model="saleClaimed.claimDestinationFk"]',
firstDeleteLine: 'vn-claim-action vn-tr:nth-child(1) vn-icon-button[icon="delete"]',
isPaidWithManaCheckbox: 'vn-claim-action vn-check[ng-model="$ctrl.claim.isChargedToMana"]',
hasToPickUpCheckbox: 'vn-claim-action vn-check[ng-model="$ctrl.claim.hasToPickUp"]'
isPaidWithManaCheckbox: 'vn-claim-action vn-check[ng-model="$ctrl.claim.isChargedToMana"]'
},
ordersIndex: {
searchResult: 'vn-order-index vn-card > vn-table > div > vn-tbody > a.vn-tr',

View File

@ -34,6 +34,15 @@ describe('Claim edit basic data path', () => {
await page.waitForState('claim.card.detail');
});
it('should check the "Pick up" checkbox', async() => {
await page.reloadSection('claim.card.basicData');
await page.waitToClick(selectors.claimBasicData.hasToPickUpCheckbox);
await page.waitToClick(selectors.claimBasicData.saveButton);
const message = await page.waitForSnackbar();
expect(message.type).toBe('success');
});
it('should confirm the claim state was edited', async() => {
await page.reloadSection('claim.card.basicData');
await page.wait(selectors.claimBasicData.claimState);
@ -42,6 +51,12 @@ describe('Claim edit basic data path', () => {
expect(result).toEqual('Gestionado');
});
it('should confirm the "is paid with mana" and "Pick up" checkbox are checked', async() => {
const hasToPickUpCheckbox = await page.checkboxState(selectors.claimBasicData.hasToPickUpCheckbox);
expect(hasToPickUpCheckbox).toBe('checked');
});
it('should confirm the claim observation was edited', async() => {
const result = await page
.waitToGetProperty(selectors.claimBasicData.observation, 'value');

View File

@ -72,19 +72,10 @@ describe('Claim action path', () => {
expect(message.type).toBe('success');
});
it('should check the "Pick up" checkbox', async() => {
await page.waitToClick(selectors.claimAction.hasToPickUpCheckbox);
const message = await page.waitForSnackbar();
expect(message.type).toBe('success');
});
it('should confirm the "is paid with mana" and "Pick up" checkbox are checked', async() => {
it('should confirm the "is paid with mana" is checked', async() => {
await page.reloadSection('claim.card.action');
const isPaidWithManaCheckbox = await page.checkboxState(selectors.claimAction.isPaidWithManaCheckbox);
const hasToPickUpCheckbox = await page.checkboxState(selectors.claimAction.hasToPickUpCheckbox);
expect(isPaidWithManaCheckbox).toBe('checked');
expect(hasToPickUpCheckbox).toBe('checked');
});
});

View File

@ -88,32 +88,11 @@ module.exports = Self => {
}, options);
}
let claim = await Self.findById(claimFk, {
include: {
relation: 'client',
scope: {
include: {
relation: 'salesPerson'
}
}
}
}, options);
let claim = await Self.findById(claimFk, null, options);
claim = await claim.updateAttributes({
claimStateFk: resolvedState
}, options);
// Get sales person from claim client
const salesPerson = claim.client().salesPerson();
if (salesPerson && claim.hasToPickUp) {
const origin = ctx.req.headers.origin;
const message = $t('Claim will be picked', {
claimId: claim.id,
clientName: claim.client().name,
claimUrl: `${origin}/#!/claim/${claim.id}/summary`
});
await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message);
}
await tx.commit();
return claim;

View File

@ -103,11 +103,9 @@ describe('regularizeClaim()', () => {
claimEnd.updateAttributes({claimDestinationFk: okDestination});
});
const claim = await app.models.Claim.findById(claimFk);
await claim.updateAttribute('hasToPickUp', true);
await app.models.Claim.regularizeClaim(ctx, claimFk);
expect(chatModel.sendCheckingPresence).toHaveBeenCalledWith(ctx, 18, 'Bueno');
expect(chatModel.sendCheckingPresence).toHaveBeenCalledTimes(5);
expect(chatModel.sendCheckingPresence).toHaveBeenCalledTimes(4);
});
});

View File

@ -54,6 +54,7 @@ describe('Update Claim', () => {
let data = {
observation: 'valid observation',
claimStateFk: correctState,
hasToPickUp: false
};
let ctx = {
req: {
@ -70,19 +71,25 @@ describe('Update Claim', () => {
});
it('should change some sensible fields as salesAssistant', async() => {
const chatModel = app.models.Chat;
spyOn(chatModel, 'sendCheckingPresence').and.callThrough();
const salesAssistantId = 21;
let data = {
claimStateFk: 3,
workerFk: 5,
observation: 'another valid observation'
observation: 'another valid observation',
hasToPickUp: true
};
let ctx = {
const ctx = {
req: {
accessToken: {
userId: salesAssistantId
}
accessToken: {userId: salesAssistantId},
headers: {origin: 'http://localhost'}
}
};
ctx.req.__ = (value, params) => {
return params.nickname;
};
await app.models.Claim.updateClaim(ctx, newInstance.id, data);
let claimUpdated = await app.models.Claim.findById(newInstance.id);
@ -90,5 +97,6 @@ describe('Update Claim', () => {
expect(claimUpdated.observation).toEqual(data.observation);
expect(claimUpdated.claimStateFk).toEqual(data.claimStateFk);
expect(claimUpdated.workerFk).toEqual(data.workerFk);
expect(chatModel.sendCheckingPresence).toHaveBeenCalled();
});
});

View File

@ -27,16 +27,44 @@ module.exports = Self => {
});
Self.updateClaim = async(ctx, id, data) => {
let models = Self.app.models;
let claim = await models.Claim.findById(id);
const models = Self.app.models;
const userId = ctx.req.accessToken.userId;
let canUpdate = await canChangeState(ctx, claim.claimStateFk);
let hasRights = await canChangeState(ctx, data.claimStateFk);
const $t = ctx.req.__; // $translate
const claim = await models.Claim.findById(id, {
include: {
relation: 'client',
scope: {
include: {
relation: 'salesPerson'
}
}
}
});
if (!canUpdate || !hasRights)
const canUpdate = await canChangeState(ctx, claim.claimStateFk);
const hasRights = await canChangeState(ctx, data.claimStateFk);
const isSalesAssistant = await models.Account.hasRole(userId, 'salesAssistant');
const changedHasToPickUp = claim.hasToPickUp != data.hasToPickUp;
if (!canUpdate || !hasRights || changedHasToPickUp && !isSalesAssistant)
throw new UserError(`You don't have enough privileges to change that field`);
return await claim.updateAttributes(data);
const updatedClaim = await claim.updateAttributes(data);
// Get sales person from claim client
const salesPerson = claim.client().salesPerson();
if (salesPerson && changedHasToPickUp && updatedClaim.hasToPickUp) {
const origin = ctx.req.headers.origin;
const message = $t('Claim will be picked', {
claimId: claim.id,
clientName: claim.client().name,
claimUrl: `${origin}/#!/claim/${claim.id}/summary`
});
await models.Chat.sendCheckingPresence(ctx, salesPerson.id, message);
}
return updatedClaim;
};
async function canChangeState(ctx, id) {

View File

@ -17,10 +17,6 @@ module.exports = Self => {
arg: 'isChargedToMana',
type: 'boolean',
required: false
}, {
arg: 'hasToPickUp',
type: 'boolean',
required: false
}],
returns: {
type: 'object',

View File

@ -43,11 +43,6 @@
on-change="$ctrl.save({responsibility: value})">
</vn-range>
</vn-tool-bar>
<vn-check vn-one class="vn-mr-md"
label="Pick up"
ng-model="$ctrl.claim.hasToPickUp"
on-change="$ctrl.save({hasToPickUp: value})">
</vn-check>
<vn-check vn-one
label="Is paid with mana"
ng-model="$ctrl.claim.isChargedToMana"

View File

@ -9,5 +9,4 @@ Regularize: Regularizar
Do you want to insert greuges?: Desea insertar greuges?
Insert greuges on client card: Insertar greuges en la ficha del cliente
Greuge inserted: Greuge insertado
ClaimGreugeDescription: Reclamación id {{claimId}}
Pick up: Recoger
ClaimGreugeDescription: Reclamación id {{claimId}}

View File

@ -53,6 +53,13 @@
rule>
</vn-textarea>
</vn-horizontal>
<vn-horizontal>
<vn-check vn-one class="vn-mr-md"
label="Pick up"
ng-model="$ctrl.claim.hasToPickUp"
vn-acl="salesAssistant">
</vn-check>
</vn-horizontal>
</vn-card>
<vn-button-bar>
<vn-submit label="Save"></vn-submit>

View File

@ -3,4 +3,5 @@ Claim state: Estado de la reclamación
Is paid with mana: Cargado al maná
Responsability: Responsabilidad
Company: Empresa
Sales/Client: Comercial/Cliente
Sales/Client: Comercial/Cliente
Pick up: Recoger

37
package-lock.json generated
View File

@ -11410,9 +11410,9 @@
}
},
"loopback-connector-mysql": {
"version": "5.4.2",
"resolved": "https://registry.npmjs.org/loopback-connector-mysql/-/loopback-connector-mysql-5.4.2.tgz",
"integrity": "sha512-f5iIIcJdfUuBUkScGcK7m4dLZnpjFjl1iFG5OHTk8pFwDq7+Xap/0H99ulueRp2ljfqbULTUvt3Rg1y/W5smtw==",
"version": "5.4.3",
"resolved": "https://registry.npmjs.org/loopback-connector-mysql/-/loopback-connector-mysql-5.4.3.tgz",
"integrity": "sha512-HQ0Nnscyhhk+4zsDhXyR8dYdkhxIBN8r8N1futX5xznWjCZ4dpkG5svoPOMUjoNaDEtZuLr1I2E4CKb6f5u9Mw==",
"requires": {
"async": "^2.6.1",
"debug": "^3.1.0",
@ -12231,14 +12231,35 @@
}
},
"mysql": {
"version": "2.17.1",
"resolved": "https://registry.npmjs.org/mysql/-/mysql-2.17.1.tgz",
"integrity": "sha512-7vMqHQ673SAk5C8fOzTG2LpPcf3bNt0oL3sFpxPEEFp1mdlDcrLK0On7z8ZYKaaHrHwNcQ/MTUz7/oobZ2OyyA==",
"version": "2.18.1",
"resolved": "https://registry.npmjs.org/mysql/-/mysql-2.18.1.tgz",
"integrity": "sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==",
"requires": {
"bignumber.js": "7.2.1",
"readable-stream": "2.3.6",
"bignumber.js": "9.0.0",
"readable-stream": "2.3.7",
"safe-buffer": "5.1.2",
"sqlstring": "2.3.1"
},
"dependencies": {
"bignumber.js": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz",
"integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A=="
},
"readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"requires": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
}
}
},
"mysql2": {

View File

@ -17,7 +17,7 @@
"loopback-boot": "^2.27.1",
"loopback-component-explorer": "^6.5.0",
"loopback-component-storage": "^3.6.1",
"loopback-connector-mysql": "^5.4.2",
"loopback-connector-mysql": "^5.4.3",
"loopback-connector-remote": "^3.4.1",
"loopback-context": "^3.4.0",
"md5": "^2.2.1",