3795-client_administraive #938
|
@ -126,7 +126,7 @@ describe('Client lock verified data path', () => {
|
||||||
it('should confirm verified data button is enabled for salesAssistant', async() => {
|
it('should confirm verified data button is enabled for salesAssistant', async() => {
|
||||||
alexm marked this conversation as resolved
Outdated
|
|||||||
const isDisabled = await page.isDisabled(selectors.clientFiscalData.verifiedDataCheckbox);
|
const isDisabled = await page.isDisabled(selectors.clientFiscalData.verifiedDataCheckbox);
|
||||||
|
|
||||||
expect(isDisabled).toBeFalsy();
|
expect(isDisabled).toBeTruthy();
|
||||||
alexm marked this conversation as resolved
Outdated
carlosjr
commented
when evaluating booleans use boolean matchers ie: toBeTrue or toEqual(true) any defined variable would pass as truthy, therefore may be a false negative. when evaluating booleans use boolean matchers ie: toBeTrue or toEqual(true)
any defined variable would pass as truthy, therefore may be a false negative.
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should now edit the social name', async() => {
|
it('should now edit the social name', async() => {
|
||||||
alexm marked this conversation as resolved
Outdated
carlosjr
commented
doesn't seem to be changing data doesn't seem to be changing data
|
|||||||
|
@ -135,7 +135,7 @@ describe('Client lock verified data path', () => {
|
||||||
await page.waitToClick(selectors.clientFiscalData.saveButton);
|
await page.waitToClick(selectors.clientFiscalData.saveButton);
|
||||||
const message = await page.waitForSnackbar();
|
const message = await page.waitForSnackbar();
|
||||||
|
|
||||||
expect(message.text).toContain('Data saved!');
|
expect(message.text).toContain(`You can't make changes on a client with verified data`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should now confirm the social name have been edited once and for all', async() => {
|
it('should now confirm the social name have been edited once and for all', async() => {
|
||||||
|
|
|
@ -1,6 +1,22 @@
|
||||||
const models = require('vn-loopback/server/server').models;
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
const LoopBackContext = require('loopback-context');
|
||||||
|
|
||||||
describe('Client addressesPropagateRe', () => {
|
describe('Client addressesPropagateRe', () => {
|
||||||
|
beforeAll(async() => {
|
||||||
|
const activeCtx = {
|
||||||
|
accessToken: {userId: 9},
|
||||||
|
http: {
|
||||||
|
req: {
|
||||||
|
headers: {origin: 'http://localhost'}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||||
|
active: activeCtx
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should propagate the isEqualizated on both addresses of Mr Wayne and set hasToInvoiceByAddress to false', async() => {
|
it('should propagate the isEqualizated on both addresses of Mr Wayne and set hasToInvoiceByAddress to false', async() => {
|
||||||
const tx = await models.Client.beginTransaction({});
|
const tx = await models.Client.beginTransaction({});
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
const models = require('vn-loopback/server/server').models;
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
const LoopBackContext = require('loopback-context');
|
||||||
|
|
||||||
describe('Address createAddress', () => {
|
describe('Address createAddress', () => {
|
||||||
const clientFk = 1101;
|
const clientFk = 1101;
|
||||||
|
@ -6,6 +7,21 @@ describe('Address createAddress', () => {
|
||||||
const incotermsFk = 'FAS';
|
const incotermsFk = 'FAS';
|
||||||
const customAgentOneId = 1;
|
const customAgentOneId = 1;
|
||||||
|
|
||||||
|
beforeAll(async() => {
|
||||||
|
const activeCtx = {
|
||||||
|
accessToken: {userId: 9},
|
||||||
|
http: {
|
||||||
|
req: {
|
||||||
|
headers: {origin: 'http://localhost'}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||||
|
active: activeCtx
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should throw a non uee member error if no incoterms is defined', async() => {
|
it('should throw a non uee member error if no incoterms is defined', async() => {
|
||||||
const tx = await models.Client.beginTransaction({});
|
const tx = await models.Client.beginTransaction({});
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
const models = require('vn-loopback/server/server').models;
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
const LoopBackContext = require('loopback-context');
|
||||||
|
|
||||||
describe('Client Create', () => {
|
describe('Client Create', () => {
|
||||||
const newAccount = {
|
const newAccount = {
|
||||||
|
@ -12,6 +13,21 @@ describe('Client Create', () => {
|
||||||
businessTypeFk: 'florist'
|
businessTypeFk: 'florist'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
beforeAll(async() => {
|
||||||
|
const activeCtx = {
|
||||||
|
accessToken: {userId: 9},
|
||||||
|
http: {
|
||||||
|
req: {
|
||||||
|
headers: {origin: 'http://localhost'}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||||
|
active: activeCtx
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it(`should not find Deadpool as he's not created yet`, async() => {
|
it(`should not find Deadpool as he's not created yet`, async() => {
|
||||||
const tx = await models.Client.beginTransaction({});
|
const tx = await models.Client.beginTransaction({});
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
const models = require('vn-loopback/server/server').models;
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
const LoopBackContext = require('loopback-context');
|
||||||
|
|
||||||
describe('Address updateAddress', () => {
|
describe('Address updateAddress', () => {
|
||||||
const clientId = 1101;
|
const clientId = 1101;
|
||||||
|
@ -13,6 +14,21 @@ describe('Address updateAddress', () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
beforeAll(async() => {
|
||||||
|
const activeCtx = {
|
||||||
|
accessToken: {userId: 9},
|
||||||
|
http: {
|
||||||
|
req: {
|
||||||
|
headers: {origin: 'http://localhost'}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||||
|
active: activeCtx
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should throw the non uee member error if no incoterms is defined', async() => {
|
it('should throw the non uee member error if no incoterms is defined', async() => {
|
||||||
const tx = await models.Client.beginTransaction({});
|
const tx = await models.Client.beginTransaction({});
|
||||||
|
|
||||||
|
@ -90,9 +106,10 @@ describe('Address updateAddress', () => {
|
||||||
|
|
||||||
it('should return an error for a user without enough privileges', async() => {
|
it('should return an error for a user without enough privileges', async() => {
|
||||||
const tx = await models.Client.beginTransaction({});
|
const tx = await models.Client.beginTransaction({});
|
||||||
|
const employeeId = 1;
|
||||||
try {
|
try {
|
||||||
const options = {transaction: tx};
|
const options = {transaction: tx};
|
||||||
|
ctx.req.accessToken.userId = employeeId;
|
||||||
ctx.args = {
|
ctx.args = {
|
||||||
isLogifloraAllowed: true
|
isLogifloraAllowed: true
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,10 +1,25 @@
|
||||||
const models = require('vn-loopback/server/server').models;
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
const LoopBackContext = require('loopback-context');
|
||||||
|
|
||||||
describe('Client updateFiscalData', () => {
|
describe('Client updateFiscalData', () => {
|
||||||
const clientId = 1101;
|
const clientId = 1101;
|
||||||
const employeeId = 1;
|
const employeeId = 1;
|
||||||
const salesAssistantId = 21;
|
const salesAssistantId = 21;
|
||||||
const administrativeId = 5;
|
const administrativeId = 5;
|
||||||
|
const activeCtx = {
|
||||||
|
accessToken: {userId: employeeId},
|
||||||
|
http: {
|
||||||
|
req: {
|
||||||
|
headers: {origin: 'http://localhost'}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||||
|
active: activeCtx
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should return an error if the user is not salesAssistant and the isTaxDataChecked value is true', async() => {
|
it('should return an error if the user is not salesAssistant and the isTaxDataChecked value is true', async() => {
|
||||||
const tx = await models.Client.beginTransaction({});
|
const tx = await models.Client.beginTransaction({});
|
||||||
|
|
|
@ -125,10 +125,10 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const isSalesAssistant = await models.Account.hasRole(userId, 'salesAssistant', myOptions);
|
const isAdministrative = await models.Account.hasRole(userId, 'administrative', myOptions);
|
||||||
const client = await models.Client.findById(clientId, null, myOptions);
|
const client = await models.Client.findById(clientId, null, myOptions);
|
||||||
|
|
||||||
if (!isSalesAssistant && client.isTaxDataChecked)
|
if (!isAdministrative && client.isTaxDataChecked)
|
||||||
throw new UserError(`You can't make changes on a client with verified data`);
|
throw new UserError(`You can't make changes on a client with verified data`);
|
||||||
alexm marked this conversation as resolved
Outdated
carlosjr
commented
the error shown here doesn't mention the lack of privileges, we believe the following error would be better:
don't forget to add translation to it please. the error shown here doesn't mention the lack of privileges, we believe the following error would be better:
`throw new UserError(`Not enough privileges to edit a client with verified data`);`
don't forget to add translation to it please.
|
|||||||
|
|
||||||
// Sage data validation
|
// Sage data validation
|
||||||
|
|
|
@ -208,6 +208,34 @@ module.exports = Self => {
|
||||||
throw new UserError(`The type of business must be filled in basic data`);
|
throw new UserError(`The type of business must be filled in basic data`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Self.observe('before save', async ctx => {
|
||||||
|
const changes = ctx.data || ctx.instance;
|
||||||
|
const orgData = ctx.currentInstance;
|
||||||
|
const models = Self.app.models;
|
||||||
|
|
||||||
|
const loopBackContext = LoopBackContext.getCurrentContext();
|
||||||
|
const userId = loopBackContext.active.accessToken.userId;
|
||||||
|
|
||||||
|
const isAdministrative = await models.Account.hasRole(userId, 'administrative', ctx.options);
|
||||||
|
const isSalesAssistant = await models.Account.hasRole(userId, 'salesAssistant', ctx.options);
|
||||||
|
const hasChanges = orgData && changes;
|
||||||
|
|
||||||
|
const isTaxDataChecked = hasChanges && (changes.isTaxDataChecked || orgData.isTaxDataChecked);
|
||||||
|
const isTaxDataCheckedChanged = hasChanges && orgData.isTaxDataChecked != isTaxDataChecked;
|
||||||
|
|
||||||
|
const sageTaxType = hasChanges && (changes.sageTaxTypeFk || orgData.sageTaxTypeFk);
|
||||||
|
const sageTaxTypeChanged = hasChanges && orgData.sageTaxTypeFk != sageTaxType;
|
||||||
|
|
||||||
|
const sageTransactionType = hasChanges && (changes.sageTransactionTypeFk || orgData.sageTransactionTypeFk);
|
||||||
|
const sageTransactionTypeChanged = hasChanges && orgData.sageTransactionTypeFk != sageTransactionType;
|
||||||
|
|
||||||
|
if (isTaxDataCheckedChanged && !isAdministrative)
|
||||||
alexm marked this conversation as resolved
carlosjr
commented
To avoid code repetition you can extract conditions to constants and then use a single "if"
To avoid code repetition you can extract conditions to constants and then use a single "if"
```
const cantEditVerifiedData = isTaxDataCheckedChanged && !isAdministrative;
const cantChangeSageData = (sageTaxTypeChanged || sageTransactionTypeChanged) && !isSalesAssistant;
if (cantEditVerifiedData || cantChangeSageData)
throw new UserError(`You don't have enough privileges`);
```
|
|||||||
|
throw new UserError(`You don't have enough privileges`);
|
||||||
|
|
||||||
|
if ((sageTaxTypeChanged || sageTransactionTypeChanged) && !isSalesAssistant)
|
||||||
|
throw new UserError(`You don't have enough privileges`);
|
||||||
|
});
|
||||||
|
|
||||||
Self.observe('before save', async function(ctx) {
|
Self.observe('before save', async function(ctx) {
|
||||||
const changes = ctx.data || ctx.instance;
|
const changes = ctx.data || ctx.instance;
|
||||||
const orgData = ctx.currentInstance;
|
const orgData = ctx.currentInstance;
|
||||||
|
@ -221,10 +249,10 @@ module.exports = Self => {
|
||||||
|
|
||||||
const socialNameChanged = hasChanges
|
const socialNameChanged = hasChanges
|
||||||
&& orgData.socialName != socialName;
|
&& orgData.socialName != socialName;
|
||||||
const dataCheckedChanged = hasChanges
|
const isTaxDataCheckedChanged = hasChanges
|
||||||
&& orgData.isTaxDataChecked != isTaxDataChecked;
|
&& orgData.isTaxDataChecked != isTaxDataChecked;
|
||||||
|
|
||||||
if ((socialNameChanged || dataCheckedChanged) && !isAlpha(socialName))
|
if ((socialNameChanged || isTaxDataCheckedChanged) && !isAlpha(socialName))
|
||||||
throw new UserError(`The social name has an invalid format`);
|
throw new UserError(`The social name has an invalid format`);
|
||||||
|
|
||||||
if (changes.salesPerson === null) {
|
if (changes.salesPerson === null) {
|
||||||
|
|
|
@ -1,20 +1,36 @@
|
||||||
const app = require('vn-loopback/server/server');
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
const LoopBackContext = require('loopback-context');
|
||||||
|
|
||||||
describe('loopback model address', () => {
|
describe('loopback model address', () => {
|
||||||
let createdAddressId;
|
let createdAddressId;
|
||||||
const clientId = 1101;
|
const clientId = 1101;
|
||||||
|
|
||||||
afterAll(async() => {
|
const activeCtx = {
|
||||||
let client = await app.models.Client.findById(clientId);
|
accessToken: {userId: 9},
|
||||||
|
http: {
|
||||||
|
req: {
|
||||||
|
headers: {origin: 'http://localhost'}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
await app.models.Address.destroyById(createdAddressId);
|
beforeEach(() => {
|
||||||
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||||
|
active: activeCtx
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(async() => {
|
||||||
|
const client = await models.Client.findById(clientId);
|
||||||
|
|
||||||
|
await models.Address.destroyById(createdAddressId);
|
||||||
await client.updateAttribute('isEqualizated', false);
|
await client.updateAttribute('isEqualizated', false);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('observe()', () => {
|
describe('observe()', () => {
|
||||||
it('should throw an error when deactivating a consignee if its the default address', async() => {
|
it('should throw an error when deactivating a consignee if its the default address', async() => {
|
||||||
let error;
|
let error;
|
||||||
let address = await app.models.Address.findById(1);
|
const address = await models.Address.findById(1);
|
||||||
|
|
||||||
await address.updateAttribute('isActive', false)
|
await address.updateAttribute('isActive', false)
|
||||||
.catch(e => {
|
.catch(e => {
|
||||||
|
@ -27,13 +43,13 @@ describe('loopback model address', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set isEqualizated to true of a given Client to trigger any new address to have it', async() => {
|
it('should set isEqualizated to true of a given Client to trigger any new address to have it', async() => {
|
||||||
let client = await app.models.Client.findById(clientId);
|
const client = await models.Client.findById(clientId);
|
||||||
|
|
||||||
expect(client.isEqualizated).toBeFalsy();
|
expect(client.isEqualizated).toBeFalsy();
|
||||||
|
|
||||||
await client.updateAttribute('isEqualizated', true);
|
await client.updateAttribute('isEqualizated', true);
|
||||||
|
|
||||||
let newAddress = await app.models.Address.create({
|
const newAddress = await models.Address.create({
|
||||||
clientFk: clientId,
|
clientFk: clientId,
|
||||||
agencyModeFk: 5,
|
agencyModeFk: 5,
|
||||||
city: 'here',
|
city: 'here',
|
||||||
|
|
|
@ -182,7 +182,7 @@
|
||||||
vn-one
|
vn-one
|
||||||
label="Verified data"
|
label="Verified data"
|
||||||
ng-model="$ctrl.client.isTaxDataChecked"
|
ng-model="$ctrl.client.isTaxDataChecked"
|
||||||
vn-acl="salesAssistant">
|
vn-acl="administrative">
|
||||||
</vn-check>
|
</vn-check>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
</vn-card>
|
</vn-card>
|
||||||
|
|
|
@ -93,10 +93,12 @@ describe('InvoiceOut createManualInvoice()', () => {
|
||||||
|
|
||||||
it('should throw an error for a non-invoiceable client', async() => {
|
it('should throw an error for a non-invoiceable client', async() => {
|
||||||
spyOn(models.InvoiceOut, 'createPdf').and.returnValue(new Promise(resolve => resolve(true)));
|
spyOn(models.InvoiceOut, 'createPdf').and.returnValue(new Promise(resolve => resolve(true)));
|
||||||
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||||
|
active: activeCtx
|
||||||
|
});
|
||||||
|
|
||||||
const tx = await models.InvoiceOut.beginTransaction({});
|
const tx = await models.InvoiceOut.beginTransaction({});
|
||||||
const options = {transaction: tx};
|
const options = {transaction: tx};
|
||||||
|
|
||||||
let error;
|
let error;
|
||||||
try {
|
try {
|
||||||
const client = await models.Client.findById(clientId, null, options);
|
const client = await models.Client.findById(clientId, null, options);
|
||||||
|
|
Loading…
Reference in New Issue
button doens't seem to be enabled.