3795-client_administraive #938

Merged
joan merged 9 commits from 3795-client_administraive into dev 2022-05-10 08:26:42 +00:00
11 changed files with 142 additions and 16 deletions
Showing only changes of commit 4a714a4b6f - Show all commits

View File

@ -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() => {
const isDisabled = await page.isDisabled(selectors.clientFiscalData.verifiedDataCheckbox); const isDisabled = await page.isDisabled(selectors.clientFiscalData.verifiedDataCheckbox);
expect(isDisabled).toBeFalsy(); expect(isDisabled).toBeTruthy();
}); });
it('should now edit the social name', async() => { it('should now edit the social name', async() => {
@ -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() => {

View File

@ -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({});

View File

@ -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({});

View File

@ -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({});

View File

@ -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
}; };

View File

@ -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({});

View File

@ -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`);
// Sage data validation // Sage data validation

View File

@ -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
Review

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`);
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) {

View File

@ -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',

View File

@ -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>

View File

@ -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);