#654 Permisos en claim.basicData

This commit is contained in:
Javi Gallego 2018-09-19 07:41:07 +02:00
parent df02c35068
commit 68e075c496
10 changed files with 295 additions and 111 deletions

View File

@ -15,8 +15,7 @@
"url": "/index?q",
"state": "claim.index",
"component": "vn-claim-index",
"description": "List",
"acl": ["salesAssistant", "salesPerson"]
"description": "List"
},
{
"url": "/:id",
@ -43,7 +42,8 @@
},
"menu": {
"icon": "settings"
}
},
"acl": ["salesPerson"]
},
{
"url": "/detail",
@ -55,7 +55,8 @@
},
"menu": {
"icon": "icon-details"
}
},
"acl": ["salesPerson"]
},
{
"url": "/development",
@ -67,7 +68,8 @@
},
"menu": {
"icon": "icon-traceability"
}
},
"acl": ["salesAssistant"]
},
{
"url": "/action",
@ -79,7 +81,8 @@
},
"menu": {
"icon": "icon-actions"
}
},
"acl": ["salesAssistant"]
}
]
}

View File

@ -1,10 +1,9 @@
<vn-watcher
vn-id="watcher"
data="$ctrl.claim"
id-field="id"
form="form"
url="/claim/api/Claims"
save="patch">
url="/claim/api/Claims/updateClaim"
save="post">
</vn-watcher>
<form name="form" ng-submit="watcher.submit()">
<vn-card pad-large>
@ -50,7 +49,8 @@
<vn-check
vn-one
label="Is paid with mana"
field="$ctrl.claim.isChargedToMana">
field="$ctrl.claim.isChargedToMana"
vn-acl="['salesAssistant']">
</vn-check>
<vn-input-range
vn-one
@ -58,7 +58,8 @@
value="$ctrl.claim.responsibility"
max="4"
min="0"
step="1">
step="1"
vn-acl="['salesAssistant']">
</vn-input-range>
</vn-horizontal>
</vn-horizontal>

View File

@ -15,7 +15,7 @@
value="{{::$ctrl.claim.client.name}}">
</vn-label-value>
<vn-label-value label="State"
value="{{::$ctrl.claim.claimState.description}}">
value="{{$ctrl.claim.claimState.description}}">
</vn-label-value>
<vn-label-value label="Created"
value="{{$ctrl.claim.created | dateTime: 'dd/MM/yyyy'}}">

196
package-lock.json generated
View File

@ -1383,7 +1383,7 @@
"bluebird": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
"integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==",
"integrity": "sha1-2VUfnemPH82h5oPRfukaBgLuLrk=",
"dev": true
},
"bn.js": {
@ -1600,7 +1600,7 @@
"integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
"dev": true,
"requires": {
"ansi-regex": "^3.0.0"
"ansi-regex": "3.0.0"
}
},
"supports-color": {
@ -5465,7 +5465,7 @@
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
"dev": true,
"requires": {
"ms": "2.0.0"
@ -6096,8 +6096,8 @@
"dev": true,
"optional": true,
"requires": {
"co": "^4.6.0",
"json-stable-stringify": "^1.0.1"
"co": "4.6.0",
"json-stable-stringify": "1.0.1"
}
},
"ansi-regex": {
@ -6170,7 +6170,7 @@
"bundled": true,
"dev": true,
"requires": {
"inherits": "~2.0.0"
"inherits": "2.0.3"
}
},
"boom": {
@ -6178,7 +6178,7 @@
"bundled": true,
"dev": true,
"requires": {
"hoek": "2.x.x"
"hoek": "2.16.3"
}
},
"brace-expansion": {
@ -6240,7 +6240,7 @@
"bundled": true,
"dev": true,
"requires": {
"boom": "2.x.x"
"boom": "2.10.1"
}
},
"dashdash": {
@ -6298,7 +6298,7 @@
"dev": true,
"optional": true,
"requires": {
"jsbn": "~0.1.0"
"jsbn": "0.1.1"
}
},
"extend": {
@ -6507,14 +6507,13 @@
"dev": true,
"optional": true,
"requires": {
"jsbn": "~0.1.0"
"jsbn": "0.1.1"
}
},
"jsbn": {
"version": "0.1.1",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"json-schema": {
"version": "0.2.3",
@ -6528,7 +6527,7 @@
"dev": true,
"optional": true,
"requires": {
"jsonify": "~0.0.0"
"jsonify": "0.0.0"
}
},
"json-stringify-safe": {
@ -10852,7 +10851,7 @@
"jasmine-spec-reporter": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-4.2.1.tgz",
"integrity": "sha512-FZBoZu7VE5nR7Nilzy+Np8KuVIOxF4oXDPDknehCYBDE080EnlPu0afdZNmpGDBRCUBv3mj5qgqCRmk6W/K8vg==",
"integrity": "sha1-HWMq7ANBZwrTJPkrqEtLMrNeniI=",
"dev": true,
"requires": {
"colors": "1.1.2"
@ -10998,7 +10997,7 @@
"karma": {
"version": "1.7.1",
"resolved": "https://registry.npmjs.org/karma/-/karma-1.7.1.tgz",
"integrity": "sha512-k5pBjHDhmkdaUccnC7gE3mBzZjcxyxYsYVaqiL2G5AqlfLyBO5nw2VdNK+O16cveEPd/gIOWULH7gkiYYwVNHg==",
"integrity": "sha1-hcwI6eCiLXzpzKN8ShvoJPaisa4=",
"dev": true,
"requires": {
"bluebird": "3.5.1",
@ -11050,7 +11049,7 @@
"karma-chrome-launcher": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz",
"integrity": "sha512-uf/ZVpAabDBPvdPdveyk1EPgbnloPvFFGgmRhYLTDH7gEB4nZdSBk8yTU47w1g/drLSx5uMOkjKk7IWKfWg/+w==",
"integrity": "sha1-zxudBxNswY/iOTJ9JGVMPbw2is8=",
"dev": true,
"requires": {
"fs-access": "1.0.1",
@ -12743,8 +12742,8 @@
"dev": true,
"optional": true,
"requires": {
"delegates": "^1.0.0",
"readable-stream": "^2.0.6"
"delegates": "1.0.0",
"readable-stream": "2.3.6"
}
},
"balanced-match": {
@ -12821,7 +12820,7 @@
"dev": true,
"optional": true,
"requires": {
"minipass": "^2.2.1"
"minipass": "2.2.4"
}
},
"fs.realpath": {
@ -12836,14 +12835,14 @@
"dev": true,
"optional": true,
"requires": {
"aproba": "^1.0.3",
"console-control-strings": "^1.0.0",
"has-unicode": "^2.0.0",
"object-assign": "^4.1.0",
"signal-exit": "^3.0.0",
"string-width": "^1.0.1",
"strip-ansi": "^3.0.1",
"wide-align": "^1.1.0"
"aproba": "1.2.0",
"console-control-strings": "1.1.0",
"has-unicode": "2.0.1",
"object-assign": "4.1.1",
"signal-exit": "3.0.2",
"string-width": "1.0.2",
"strip-ansi": "3.0.1",
"wide-align": "1.1.2"
}
},
"glob": {
@ -12852,12 +12851,12 @@
"dev": true,
"optional": true,
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
"fs.realpath": "1.0.0",
"inflight": "1.0.6",
"inherits": "2.0.3",
"minimatch": "3.0.4",
"once": "1.4.0",
"path-is-absolute": "1.0.1"
}
},
"has-unicode": {
@ -12872,7 +12871,7 @@
"dev": true,
"optional": true,
"requires": {
"safer-buffer": "^2.1.0"
"safer-buffer": "2.1.2"
}
},
"ignore-walk": {
@ -12881,7 +12880,7 @@
"dev": true,
"optional": true,
"requires": {
"minimatch": "^3.0.4"
"minimatch": "3.0.4"
}
},
"inflight": {
@ -12890,8 +12889,8 @@
"dev": true,
"optional": true,
"requires": {
"once": "^1.3.0",
"wrappy": "1"
"once": "1.4.0",
"wrappy": "1.0.2"
}
},
"inherits": {
@ -12910,7 +12909,7 @@
"bundled": true,
"dev": true,
"requires": {
"number-is-nan": "^1.0.0"
"number-is-nan": "1.0.1"
}
},
"isarray": {
@ -12924,7 +12923,7 @@
"bundled": true,
"dev": true,
"requires": {
"brace-expansion": "^1.1.7"
"brace-expansion": "1.1.11"
}
},
"minimist": {
@ -12937,8 +12936,8 @@
"bundled": true,
"dev": true,
"requires": {
"safe-buffer": "^5.1.1",
"yallist": "^3.0.0"
"safe-buffer": "5.1.1",
"yallist": "3.0.2"
}
},
"minizlib": {
@ -12947,7 +12946,7 @@
"dev": true,
"optional": true,
"requires": {
"minipass": "^2.2.1"
"minipass": "2.2.4"
}
},
"mkdirp": {
@ -12970,9 +12969,9 @@
"dev": true,
"optional": true,
"requires": {
"debug": "^2.1.2",
"iconv-lite": "^0.4.4",
"sax": "^1.2.4"
"debug": "2.6.9",
"iconv-lite": "0.4.21",
"sax": "1.2.4"
}
},
"node-pre-gyp": {
@ -12981,16 +12980,16 @@
"dev": true,
"optional": true,
"requires": {
"detect-libc": "^1.0.2",
"mkdirp": "^0.5.1",
"needle": "^2.2.0",
"nopt": "^4.0.1",
"npm-packlist": "^1.1.6",
"npmlog": "^4.0.2",
"rc": "^1.1.7",
"rimraf": "^2.6.1",
"semver": "^5.3.0",
"tar": "^4"
"detect-libc": "1.0.3",
"mkdirp": "0.5.1",
"needle": "2.2.0",
"nopt": "4.0.1",
"npm-packlist": "1.1.10",
"npmlog": "4.1.2",
"rc": "1.2.7",
"rimraf": "2.6.2",
"semver": "5.5.0",
"tar": "4.4.1"
}
},
"nopt": {
@ -12999,8 +12998,8 @@
"dev": true,
"optional": true,
"requires": {
"abbrev": "1",
"osenv": "^0.1.4"
"abbrev": "1.1.1",
"osenv": "0.1.5"
}
},
"npm-bundled": {
@ -13015,8 +13014,8 @@
"dev": true,
"optional": true,
"requires": {
"ignore-walk": "^3.0.1",
"npm-bundled": "^1.0.1"
"ignore-walk": "3.0.1",
"npm-bundled": "1.0.3"
}
},
"npmlog": {
@ -13025,10 +13024,10 @@
"dev": true,
"optional": true,
"requires": {
"are-we-there-yet": "~1.1.2",
"console-control-strings": "~1.1.0",
"gauge": "~2.7.3",
"set-blocking": "~2.0.0"
"are-we-there-yet": "1.1.4",
"console-control-strings": "1.1.0",
"gauge": "2.7.4",
"set-blocking": "2.0.0"
}
},
"number-is-nan": {
@ -13047,7 +13046,7 @@
"bundled": true,
"dev": true,
"requires": {
"wrappy": "1"
"wrappy": "1.0.2"
}
},
"os-homedir": {
@ -13068,8 +13067,8 @@
"dev": true,
"optional": true,
"requires": {
"os-homedir": "^1.0.0",
"os-tmpdir": "^1.0.0"
"os-homedir": "1.0.2",
"os-tmpdir": "1.0.2"
}
},
"path-is-absolute": {
@ -13090,10 +13089,10 @@
"dev": true,
"optional": true,
"requires": {
"deep-extend": "^0.5.1",
"ini": "~1.3.0",
"minimist": "^1.2.0",
"strip-json-comments": "~2.0.1"
"deep-extend": "0.5.1",
"ini": "1.3.5",
"minimist": "1.2.0",
"strip-json-comments": "2.0.1"
},
"dependencies": {
"minimist": {
@ -13110,13 +13109,13 @@
"dev": true,
"optional": true,
"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"
"core-util-is": "1.0.2",
"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.2"
}
},
"rimraf": {
@ -13125,7 +13124,7 @@
"dev": true,
"optional": true,
"requires": {
"glob": "^7.0.5"
"glob": "7.1.2"
}
},
"safe-buffer": {
@ -13168,9 +13167,9 @@
"bundled": true,
"dev": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
"strip-ansi": "^3.0.0"
"code-point-at": "1.1.0",
"is-fullwidth-code-point": "1.0.0",
"strip-ansi": "3.0.1"
}
},
"string_decoder": {
@ -13179,7 +13178,7 @@
"dev": true,
"optional": true,
"requires": {
"safe-buffer": "~5.1.0"
"safe-buffer": "5.1.1"
}
},
"strip-ansi": {
@ -13187,7 +13186,7 @@
"bundled": true,
"dev": true,
"requires": {
"ansi-regex": "^2.0.0"
"ansi-regex": "2.1.1"
}
},
"strip-json-comments": {
@ -13202,13 +13201,13 @@
"dev": true,
"optional": true,
"requires": {
"chownr": "^1.0.1",
"fs-minipass": "^1.2.5",
"minipass": "^2.2.4",
"minizlib": "^1.1.0",
"mkdirp": "^0.5.0",
"safe-buffer": "^5.1.1",
"yallist": "^3.0.2"
"chownr": "1.0.1",
"fs-minipass": "1.2.5",
"minipass": "2.2.4",
"minizlib": "1.1.0",
"mkdirp": "0.5.1",
"safe-buffer": "5.1.1",
"yallist": "3.0.2"
}
},
"util-deprecate": {
@ -13223,7 +13222,7 @@
"dev": true,
"optional": true,
"requires": {
"string-width": "^1.0.2"
"string-width": "1.0.2"
}
},
"wrappy": {
@ -13388,10 +13387,10 @@
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=",
"dev": true,
"requires": {
"brace-expansion": "^1.1.7"
"brace-expansion": "1.1.11"
}
},
"ms": {
@ -17785,6 +17784,11 @@
}
}
},
"object-diff": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/object-diff/-/object-diff-0.0.4.tgz",
"integrity": "sha1-2IOwRE/o/W4E5ZXXu2ZWgskWBH8="
},
"object-keys": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
@ -17890,7 +17894,6 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
"integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
"dev": true,
"requires": {
"isobject": "3.0.1"
},
@ -17898,8 +17901,7 @@
"isobject": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
"dev": true
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
}
}
},
@ -21351,7 +21353,7 @@
"useragent": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz",
"integrity": "sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw==",
"integrity": "sha1-IX+UOtVAyyEoZYqyP8lg9qiMmXI=",
"dev": true,
"requires": {
"lru-cache": "4.1.1",

View File

@ -21,6 +21,8 @@
"material-design-lite": "^1.3.0",
"mg-crud": "^1.1.2",
"npm": "^5.10.0",
"object-diff": "0.0.4",
"object.pick": "^1.3.0",
"oclazyload": "^0.6.3",
"require-yaml": "0.0.1",
"validator": "^6.2.1"

View File

@ -24,7 +24,7 @@ describe('Claim Create', () => {
let params = {claim: newClaim, sales: newSale};
it('should create a new claim', async() => {
let claim = await app.models.Claim.createFromSales(params);
let claim = await app.models.Claim.update(params);
expect(claim.ticketFk).toEqual(newClaim.ticketFk);
expect(claim.clientFk).toEqual(newClaim.clientFk);

View File

@ -0,0 +1,124 @@
const app = require(`${servicesDir}/claim/server/server`);
fdescribe('Update Claim', () => {
let newDate = new Date();
let newInstance;
let original = {
ticketFk: 3,
clientFk: 101,
ticketCreated: newDate,
workerFk: 18,
claimStateFk: 2,
isChargedToMana: true,
responsibility: 4,
observation: 'observation'
};
beforeAll(async() => {
newInstance = await app.models.Claim.create(original);
});
afterAll(async() => {
await app.models.Claim.destroyById(newInstance.id);
});
it('should throw error if isSaleAssistant is false and try to modify a forbidden field', async() => {
let params = {
id: newInstance.id,
ticketFk: 3,
clientFk: 101,
ticketCreated: newDate,
workerFk: 18,
isChargedToMana: false,
responsibility: 3,
observation: 'another'
};
let ctx = {
req: {
accessToken: {
userId: 18
}
}
};
await app.models.Claim.updateClaim(ctx, params)
.catch(e => {
error = e;
});
expect(error.message).toEqual(`You don't have enough privileges to change that field`);
});
it('should throw error if isSaleAssistant is false and try to modify a valid field but a forbidden stated', async() => {
let params = {
id: newInstance.id,
ticketFk: 3,
clientFk: 101,
ticketCreated: newDate,
workerFk: 18,
claimStateFk: 4,
observation: 'another'
};
let ctx = {
req: {
accessToken: {
userId: 18
}
}
};
await app.models.Claim.updateClaim(ctx, params)
.catch(e => {
error = e;
});
expect(error.message).toEqual(`You don't have enough privileges to change that field`);
});
it('should change field observation', async() => {
let params = {
id: newInstance.id,
ticketCreated: newDate,
observation: 'another3'
};
let ctx = {
req: {
accessToken: {
userId: 18
}
}
};
await app.models.Claim.updateClaim(ctx, params);
let claimUpdated = await app.models.Claim.findById(newInstance.id);
expect(claimUpdated.observation).toEqual(params.observation);
});
it('should change sensible fields as salesAssistant', async() => {
let params = {
id: newInstance.id,
ticketFk: 3,
clientFk: 101,
ticketCreated: newDate,
workerFk: 18,
claimStateFk: 3,
isChargedToMana: true,
responsibility: 3,
observation: 'another'
};
let ctx = {
req: {
accessToken: {
userId: 21
}
}
};
await app.models.Claim.updateClaim(ctx, params);
let claimUpdated = await app.models.Claim.findById(newInstance.id);
expect(claimUpdated.observation).toEqual(params.observation);
expect(claimUpdated.claimStateFk).toEqual(params.claimStateFk);
expect(claimUpdated.responsibility).toEqual(params.responsibility);
expect(claimUpdated.isChargedToMana).toEqual(params.isChargedToMana);
});
});

View File

@ -0,0 +1,50 @@
const UserError = require('vn-loopback/common/helpers').UserError;
var pick = require('object.pick');
var diff = require('object-diff');
module.exports = Self => {
Self.remoteMethodCtx('updateClaim', {
description: 'Update a claim with privileges',
accessType: 'WRITE',
accepts: [{
arg: 'params',
type: 'object',
required: true,
description: 'ticketFk, stateFk',
http: {source: 'body'}
}],
returns: {
type: 'string',
root: true
},
http: {
path: `/updateClaim`,
verb: 'post'
}
});
Self.updateClaim = async(ctx, params) => {
let models = Self.app.models;
let isSalesAssistant;
let token = ctx.req.accessToken;
let currentUserId = token && token.userId;
isSalesAssistant = await models.Account.hasRole(currentUserId, 'SalesAssistant');
if (!isSalesAssistant) {
let oldClaim = await models.Claim.findById(params.id);
let notModifiable = ['responsibility', 'isChargedToMana'];
let changedFields = diff(oldClaim, params);
let changedFieldsPicked = pick(changedFields, notModifiable);
let statesViables = ['Gestionado', 'Pendiente'];
let oldState = await models.ClaimState.findOne({where: {id: oldClaim.claimStateFk}});
let newState = await models.ClaimState.findOne({where: {id: params.claimStateFk}});
let canChangeState = statesViables.includes(oldState.description)
&& statesViables.includes(newState.description);
if (Object.keys(changedFieldsPicked).length != 0 || !canChangeState)
throw new UserError(`You don't have enough privileges to change that field`);
}
return await Self.updateAll({id: params.id}, params);
};
};

View File

@ -1,4 +1,5 @@
module.exports = Self => {
require('../methods/claim/getSummary')(Self);
require('../methods/claim/createFromSales')(Self);
require('../methods/claim/updateClaim')(Self);
};

View File

@ -47,5 +47,6 @@
"The warehouse can't be repeated": "El almacén no puede repetirse",
"The tag can't be repeated": "El tag no puede repetirse",
"The observation type can't be repeated": "El tipo de observación no puede repetirse",
"A claim with that sale already exists": "Ya existe una reclamación para esta línea"
"A claim with that sale already exists": "Ya existe una reclamación para esta línea",
"You don't have enough privileges to change that field": "You don't have enough privileges to change that field"
}