Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 3430-ticket_step-two
gitea/salix/pipeline/head There was a failure building this commit Details

This commit is contained in:
Alex Moreno 2021-12-20 13:50:50 +01:00
commit 50db693e51
58 changed files with 1628 additions and 617 deletions

View File

@ -618,8 +618,10 @@ INSERT INTO `vn`.`ticket`(`id`, `priority`, `agencyModeFk`,`warehouseFk`,`routeF
(21, NULL, 5, 5, 5, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 1109, 'Somewhere in Holland', 102, NULL, 0, 13, 5, 1, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)), (21, NULL, 5, 5, 5, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 1109, 'Somewhere in Holland', 102, NULL, 0, 13, 5, 1, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)),
(22, NULL, 5, 5, 5, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 1109, 'Somewhere in Japan', 103, NULL, 0, 13, 5, 1, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)), (22, NULL, 5, 5, 5, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 1109, 'Somewhere in Japan', 103, NULL, 0, 13, 5, 1, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)),
(23, NULL, 8, 1, 7, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 1101, 'address 21', 121, NULL, 0, 5, 5, 1, CURDATE()), (23, NULL, 8, 1, 7, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 1101, 'address 21', 121, NULL, 0, 5, 5, 1, CURDATE()),
(24 ,NULL, 8, 1, 7, CURDATE(), CURDATE(), 1101, 'Bruce Wayne', 1, NULL, 0, 5, 5, 1, CURDATE()); (24 ,NULL, 8, 1, 7, CURDATE(), CURDATE(), 1101, 'Bruce Wayne', 1, NULL, 0, 5, 5, 1, CURDATE()),
(25 ,NULL, 8, 1, NULL, CURDATE(), CURDATE(), 1101, 'Bruce Wayne', 1, NULL, 0, 1, 5, 1, CURDATE()),
(26 ,NULL, 8, 1, NULL, CURDATE(), CURDATE(), 1101, 'An incredibly long alias for testing purposes', 1, NULL, 0, 1, 5, 1, CURDATE()),
(27 ,NULL, 8, 1, NULL, CURDATE(), CURDATE(), 1101, 'Wolverine', 1, NULL, 0, 1, 5, 1, CURDATE());
INSERT INTO `vn`.`ticketObservation`(`id`, `ticketFk`, `observationTypeFk`, `description`) INSERT INTO `vn`.`ticketObservation`(`id`, `ticketFk`, `observationTypeFk`, `description`)
VALUES VALUES
(1, 11, 1, 'ready'), (1, 11, 1, 'ready'),

View File

@ -127,8 +127,8 @@ describe('Item regularize path', () => {
await page.waitForState('ticket.index'); await page.waitForState('ticket.index');
}); });
it('should search for the ticket with id 25 once again', async() => { it('should search for the ticket with id 28 once again', async() => {
await page.accessToSearchResult('25'); await page.accessToSearchResult('28');
await page.waitForState('ticket.card.summary'); await page.waitForState('ticket.card.summary');
}); });

View File

@ -33,7 +33,7 @@ describe('Ticket index payout path', () => {
await page.waitToClick(selectors.ticketsIndex.openAdvancedSearchButton); await page.waitToClick(selectors.ticketsIndex.openAdvancedSearchButton);
await page.write(selectors.ticketsIndex.advancedSearchClient, '1101'); await page.write(selectors.ticketsIndex.advancedSearchClient, '1101');
await page.keyboard.press('Enter'); await page.keyboard.press('Enter');
await page.waitForNumberOfElements(selectors.ticketsIndex.anySearchResult, 6); await page.waitForNumberOfElements(selectors.ticketsIndex.anySearchResult, 9);
await page.waitToClick(selectors.ticketsIndex.firstTicketCheckbox); await page.waitToClick(selectors.ticketsIndex.firstTicketCheckbox);
await page.waitToClick(selectors.ticketsIndex.secondTicketCheckbox); await page.waitToClick(selectors.ticketsIndex.secondTicketCheckbox);

View File

@ -52,8 +52,6 @@
"Agency cannot be blank": "La agencia no puede quedar en blanco", "Agency cannot be blank": "La agencia no puede quedar en blanco",
"You can't make changes on a client with verified data": "No puedes hacer cambios en un cliente con datos comprobados", "You can't make changes on a client with verified data": "No puedes hacer cambios en un cliente con datos comprobados",
"This address doesn't exist": "Este consignatario no existe", "This address doesn't exist": "Este consignatario no existe",
"You can't create an order for a inactive client": "You can't create an order for a inactive client",
"You can't create an order for a client that doesn't has tax data verified": "You can't create an order for a client that doesn't has tax data verified",
"You must delete the claim id %d first": "Antes debes borrar la reclamación %d", "You must delete the claim id %d first": "Antes debes borrar la reclamación %d",
"You don't have enough privileges": "No tienes suficientes permisos", "You don't have enough privileges": "No tienes suficientes permisos",
"Cannot check Equalization Tax in this NIF/CIF": "No se puede marcar RE en este NIF/CIF", "Cannot check Equalization Tax in this NIF/CIF": "No se puede marcar RE en este NIF/CIF",

View File

@ -1,4 +1,4 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context'); const LoopBackContext = require('loopback-context');
describe('entry addBuy()', () => { describe('entry addBuy()', () => {
@ -25,11 +25,11 @@ describe('entry addBuy()', () => {
packageFk: 3 packageFk: 3
}; };
const tx = await app.models.Entry.beginTransaction({}); const tx = await models.Entry.beginTransaction({});
const options = {transaction: tx}; const options = {transaction: tx};
try { try {
const newBuy = await app.models.Entry.addBuy(ctx, options); const newBuy = await models.Entry.addBuy(ctx, options);
expect(newBuy.itemFk).toEqual(itemId); expect(newBuy.itemFk).toEqual(itemId);

View File

@ -1,4 +1,4 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context'); const LoopBackContext = require('loopback-context');
describe('sale deleteBuys()', () => { describe('sale deleteBuys()', () => {
@ -15,13 +15,13 @@ describe('sale deleteBuys()', () => {
active: activeCtx active: activeCtx
}); });
const tx = await app.models.Entry.beginTransaction({}); const tx = await models.Entry.beginTransaction({});
const options = {transaction: tx}; const options = {transaction: tx};
ctx.args = {buys: [{id: 1}]}; ctx.args = {buys: [{id: 1}]};
try { try {
const result = await app.models.Buy.deleteBuys(ctx, options); const result = await models.Buy.deleteBuys(ctx, options);
expect(result).toEqual([{count: 1}]); expect(result).toEqual([{count: 1}]);
await tx.rollback(); await tx.rollback();

View File

@ -1,9 +1,8 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
const model = app.models.Buy;
describe('Buy editLatestsBuys()', () => { describe('Buy editLatestsBuys()', () => {
it('should change the value of a given column for the selected buys', async() => { it('should change the value of a given column for the selected buys', async() => {
const tx = await app.models.Entry.beginTransaction({}); const tx = await models.Buy.beginTransaction({});
const options = {transaction: tx}; const options = {transaction: tx};
try { try {
@ -13,15 +12,15 @@ describe('Buy editLatestsBuys()', () => {
} }
}; };
const [original] = await model.latestBuysFilter(ctx, null, options); const [original] = await models.Buy.latestBuysFilter(ctx, null, options);
const field = 'size'; const field = 'size';
const newValue = 99; const newValue = 99;
const lines = [{itemFk: original.itemFk, id: original.id}]; const lines = [{itemFk: original.itemFk, id: original.id}];
await model.editLatestBuys(field, newValue, lines, options); await models.Buy.editLatestBuys(field, newValue, lines, options);
const [result] = await model.latestBuysFilter(ctx, null, options); const [result] = await models.Buy.latestBuysFilter(ctx, null, options);
expect(result[field]).toEqual(newValue); expect(result[field]).toEqual(newValue);

View File

@ -1,77 +1,137 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('Entry filter()', () => { describe('Entry filter()', () => {
it('should return the entry matching "search"', async() => { it('should return the entry matching "search"', async() => {
let ctx = { const tx = await models.Entry.beginTransaction({});
const options = {transaction: tx};
try {
const ctx = {
args: { args: {
search: 1 search: 1
} }
}; };
let result = await app.models.Entry.filter(ctx); const result = await models.Entry.filter(ctx, options);
expect(result.length).toEqual(1); expect(result.length).toEqual(1);
expect(result[0].id).toEqual(1); expect(result[0].id).toEqual(1);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return the entry matching the currency', async() => { it('should return the entry matching the currency', async() => {
let ctx = { const tx = await models.Entry.beginTransaction({});
const options = {transaction: tx};
try {
const ctx = {
args: { args: {
currencyFk: 1 currencyFk: 1
} }
}; };
let result = await app.models.Entry.filter(ctx); const result = await models.Entry.filter(ctx, options);
expect(result.length).toEqual(8); expect(result.length).toEqual(8);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return the entry matching the supplier', async() => { it('should return the entry matching the supplier', async() => {
let ctx = { const tx = await models.Entry.beginTransaction({});
const options = {transaction: tx};
try {
const ctx = {
args: { args: {
supplierFk: 2 supplierFk: 2
} }
}; };
let result = await app.models.Entry.filter(ctx); const result = await models.Entry.filter(ctx, options);
expect(result.length).toEqual(6); expect(result.length).toEqual(6);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return the entry matching the company', async() => { it('should return the entry matching the company', async() => {
let ctx = { const tx = await models.Entry.beginTransaction({});
const options = {transaction: tx};
try {
const ctx = {
args: { args: {
companyFk: 442 companyFk: 442
} }
}; };
let result = await app.models.Entry.filter(ctx); const result = await models.Entry.filter(ctx, options);
expect(result.length).toEqual(7); expect(result.length).toEqual(7);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return the entries matching isBooked', async() => { it('should return the entries matching isBooked', async() => {
let ctx = { const tx = await models.Entry.beginTransaction({});
const options = {transaction: tx};
try {
const ctx = {
args: { args: {
isBooked: true, isBooked: true,
} }
}; };
let result = await app.models.Entry.filter(ctx); const result = await models.Entry.filter(ctx, options);
expect(result.length).toEqual(0); expect(result.length).toEqual(0);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return the routes matching the reference and travel', async() => { it('should return the routes matching the reference and travel', async() => {
let ctx = { const tx = await models.Entry.beginTransaction({});
const options = {transaction: tx};
try {
const ctx = {
args: { args: {
reference: 'movement', reference: 'movement',
travelFk: '2' travelFk: '2'
} }
}; };
let result = await app.models.Entry.filter(ctx); const result = await models.Entry.filter(ctx, options);
expect(result.length).toEqual(2); expect(result.length).toEqual(2);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
}); });

View File

@ -1,14 +1,24 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('entry getBuys()', () => { describe('entry getBuys()', () => {
const entryId = 4; const entryId = 4;
it('should get the buys and items of an entry', async() => { it('should get the buys and items of an entry', async() => {
const result = await app.models.Entry.getBuys(entryId); const tx = await models.Entry.beginTransaction({});
const options = {transaction: tx};
try {
const result = await models.Entry.getBuys(entryId, options);
const length = result.length; const length = result.length;
const anyResult = result[Math.floor(Math.random() * Math.floor(length))]; const anyResult = result[Math.floor(Math.random() * Math.floor(length))];
expect(result.length).toEqual(4); expect(result.length).toEqual(4);
expect(anyResult.item).toBeDefined(); expect(anyResult.item).toBeDefined();
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
}); });

View File

@ -1,31 +1,71 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('travel getEntry()', () => { describe('travel getEntry()', () => {
const entryId = 1; const entryId = 1;
it('should check the entry contains the id', async() => { it('should check the entry contains the id', async() => {
const entry = await app.models.Entry.getEntry(entryId); const tx = await models.Entry.beginTransaction({});
const options = {transaction: tx};
try {
const entry = await models.Entry.getEntry(entryId, options);
expect(entry.id).toEqual(entryId); expect(entry.id).toEqual(entryId);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should check the entry contains the supplier name', async() => { it('should check the entry contains the supplier name', async() => {
const entry = await app.models.Entry.getEntry(entryId); const tx = await models.Entry.beginTransaction({});
const options = {transaction: tx};
try {
const entry = await models.Entry.getEntry(entryId, options);
const supplierName = entry.supplier().nickname; const supplierName = entry.supplier().nickname;
expect(supplierName).toEqual('Plants nick'); expect(supplierName).toEqual('Plants nick');
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should check the entry contains the receiver warehouse name', async() => { it('should check the entry contains the receiver warehouse name', async() => {
const entry = await app.models.Entry.getEntry(entryId); const tx = await models.Entry.beginTransaction({});
const options = {transaction: tx};
try {
const entry = await models.Entry.getEntry(entryId, options);
const receiverWarehouseName = entry.travel().warehouseIn().name; const receiverWarehouseName = entry.travel().warehouseIn().name;
expect(receiverWarehouseName).toEqual('Warehouse One'); expect(receiverWarehouseName).toEqual('Warehouse One');
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should check the entry contains the company code', async() => { it('should check the entry contains the company code', async() => {
const entry = await app.models.Entry.getEntry(entryId); const tx = await models.Entry.beginTransaction({});
const options = {transaction: tx};
try {
const entry = await models.Entry.getEntry(entryId, options);
const companyCode = entry.company().code; const companyCode = entry.company().code;
expect(companyCode).toEqual('VNL'); expect(companyCode).toEqual('VNL');
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
}); });

View File

@ -1,4 +1,4 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context'); const LoopBackContext = require('loopback-context');
describe('entry import()', () => { describe('entry import()', () => {
@ -48,10 +48,10 @@ describe('entry import()', () => {
] ]
} }
}; };
const tx = await app.models.Entry.beginTransaction({}); const tx = await models.Entry.beginTransaction({});
try { try {
const options = {transaction: tx}; const options = {transaction: tx};
const newEntry = await app.models.Entry.create({ const newEntry = await models.Entry.create({
dated: new Date(), dated: new Date(),
supplierFk: supplierId, supplierFk: supplierId,
travelFk: travelId, travelFk: travelId,
@ -60,10 +60,10 @@ describe('entry import()', () => {
ref: 'Entry ref' ref: 'Entry ref'
}, options); }, options);
await app.models.Entry.importBuys(ctx, newEntry.id, options); await models.Entry.importBuys(ctx, newEntry.id, options);
const updatedEntry = await app.models.Entry.findById(newEntry.id, null, options); const updatedEntry = await models.Entry.findById(newEntry.id, null, options);
const entryBuys = await app.models.Buy.find({ const entryBuys = await models.Buy.find({
where: {entryFk: newEntry.id} where: {entryFk: newEntry.id}
}, options); }, options);

View File

@ -1,4 +1,4 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context'); const LoopBackContext = require('loopback-context');
describe('entry importBuysPreview()', () => { describe('entry importBuysPreview()', () => {
@ -10,6 +10,10 @@ describe('entry importBuysPreview()', () => {
}); });
it('should return the buys with the calculated packageFk', async() => { it('should return the buys with the calculated packageFk', async() => {
const tx = await models.Entry.beginTransaction({});
const options = {transaction: tx};
try {
const expectedPackageFk = '3'; const expectedPackageFk = '3';
const buys = [ const buys = [
{ {
@ -30,10 +34,16 @@ describe('entry importBuysPreview()', () => {
} }
]; ];
const result = await app.models.Entry.importBuysPreview(entryId, buys); const result = await models.Entry.importBuysPreview(entryId, buys, options);
const randomIndex = Math.floor(Math.random() * result.length); const randomIndex = Math.floor(Math.random() * result.length);
const buy = result[randomIndex]; const buy = result[randomIndex];
expect(buy.packageFk).toEqual(expectedPackageFk); expect(buy.packageFk).toEqual(expectedPackageFk);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
}); });

View File

@ -1,34 +1,58 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('Buy latests buys filter()', () => { describe('Buy latests buys filter()', () => {
it('should return the entry matching "search"', async() => { it('should return the entry matching "search"', async() => {
let ctx = { const tx = await models.Buy.beginTransaction({});
const options = {transaction: tx};
try {
const ctx = {
args: { args: {
search: 'Ranged weapon longbow 2m' search: 'Ranged weapon longbow 2m'
} }
}; };
let results = await app.models.Buy.latestBuysFilter(ctx); const results = await models.Buy.latestBuysFilter(ctx);
let firstBuy = results[0]; const firstBuy = results[0];
expect(results.length).toEqual(1); expect(results.length).toEqual(1);
expect(firstBuy.size).toEqual(70); expect(firstBuy.size).toEqual(70);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return the entry matching "id"', async() => { it('should return the entry matching "id"', async() => {
let ctx = { const tx = await models.Buy.beginTransaction({});
const options = {transaction: tx};
try {
const ctx = {
args: { args: {
id: 1 id: 1
} }
}; };
let results = await app.models.Buy.latestBuysFilter(ctx); const results = await models.Buy.latestBuysFilter(ctx, options);
expect(results.length).toEqual(1); expect(results.length).toEqual(1);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return results matching "tags"', async() => { it('should return results matching "tags"', async() => {
let ctx = { const tx = await models.Buy.beginTransaction({});
const options = {transaction: tx};
try {
const ctx = {
args: { args: {
tags: [ tags: [
{tagFk: 27, value: '2m'} {tagFk: 27, value: '2m'}
@ -36,160 +60,286 @@ describe('Buy latests buys filter()', () => {
} }
}; };
let results = await app.models.Buy.latestBuysFilter(ctx); const results = await models.Buy.latestBuysFilter(ctx, options);
expect(results.length).toBe(2); expect(results.length).toBe(2);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return results matching "categoryFk"', async() => { it('should return results matching "categoryFk"', async() => {
let ctx = { const tx = await models.Buy.beginTransaction({});
const options = {transaction: tx};
try {
const ctx = {
args: { args: {
categoryFk: 1 categoryFk: 1
} }
}; };
let results = await app.models.Buy.latestBuysFilter(ctx); const results = await models.Buy.latestBuysFilter(ctx, options);
expect(results.length).toBe(4); expect(results.length).toBe(4);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return results matching "typeFk"', async() => { it('should return results matching "typeFk"', async() => {
let ctx = { const tx = await models.Buy.beginTransaction({});
const options = {transaction: tx};
try {
const ctx = {
args: { args: {
typeFk: 2 typeFk: 2
} }
}; };
let results = await app.models.Buy.latestBuysFilter(ctx); const results = await models.Buy.latestBuysFilter(ctx, options);
expect(results.length).toBe(4); expect(results.length).toBe(4);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return results matching "active"', async() => { it('should return results matching "active"', async() => {
let ctx = { const tx = await models.Buy.beginTransaction({});
const options = {transaction: tx};
try {
const ctx = {
args: { args: {
active: true active: true
} }
}; };
let results = await app.models.Buy.latestBuysFilter(ctx); const results = await models.Buy.latestBuysFilter(ctx, options);
expect(results.length).toBe(6); expect(results.length).toBe(6);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return results matching "not active"', async() => { it('should return results matching "not active"', async() => {
let ctx = { const tx = await models.Buy.beginTransaction({});
const options = {transaction: tx};
try {
const ctx = {
args: { args: {
active: false active: false
} }
}; };
let results = await app.models.Buy.latestBuysFilter(ctx); const results = await models.Buy.latestBuysFilter(ctx, options);
expect(results.length).toBe(0); expect(results.length).toBe(0);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return results matching "visible"', async() => { it('should return results matching "visible"', async() => {
let ctx = { const tx = await models.Buy.beginTransaction({});
const options = {transaction: tx};
try {
const ctx = {
args: { args: {
visible: true visible: true
} }
}; };
let results = await app.models.Buy.latestBuysFilter(ctx); const results = await models.Buy.latestBuysFilter(ctx, options);
expect(results.length).toBe(5); expect(results.length).toBe(5);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return results matching "not visible"', async() => { it('should return results matching "not visible"', async() => {
let ctx = { const tx = await models.Buy.beginTransaction({});
const options = {transaction: tx};
try {
const ctx = {
args: { args: {
visible: false visible: false
} }
}; };
let results = await app.models.Buy.latestBuysFilter(ctx); const results = await models.Buy.latestBuysFilter(ctx, options);
expect(results.length).toBe(0); expect(results.length).toBe(0);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return results matching "floramondo"', async() => { it('should return results matching "floramondo"', async() => {
let ctx = { const tx = await models.Buy.beginTransaction({});
const options = {transaction: tx};
try {
const ctx = {
args: { args: {
floramondo: true floramondo: true
} }
}; };
let results = await app.models.Buy.latestBuysFilter(ctx); const results = await models.Buy.latestBuysFilter(ctx, options);
expect(results.length).toBe(1); expect(results.length).toBe(1);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return results matching "not floramondo"', async() => { it('should return results matching "not floramondo"', async() => {
let ctx = { const tx = await models.Buy.beginTransaction({});
const options = {transaction: tx};
try {
const ctx = {
args: { args: {
floramondo: false floramondo: false
} }
}; };
let results = await app.models.Buy.latestBuysFilter(ctx); const results = await models.Buy.latestBuysFilter(ctx, options);
expect(results.length).toBe(5); expect(results.length).toBe(5);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return results matching "salesPersonFk"', async() => { it('should return results matching "salesPersonFk"', async() => {
let ctx = { const tx = await models.Buy.beginTransaction({});
const options = {transaction: tx};
try {
const ctx = {
args: { args: {
salesPersonFk: 35 salesPersonFk: 35
} }
}; };
let results = await app.models.Buy.latestBuysFilter(ctx); const results = await models.Buy.latestBuysFilter(ctx, options);
expect(results.length).toBe(6); expect(results.length).toBe(6);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return results matching "description"', async() => { it('should return results matching "description"', async() => {
let ctx = { const tx = await models.Buy.beginTransaction({});
const options = {transaction: tx};
try {
const ctx = {
args: { args: {
description: 'Increases block' description: 'Increases block'
} }
}; };
let results = await app.models.Buy.latestBuysFilter(ctx); const results = await models.Buy.latestBuysFilter(ctx, options);
expect(results.length).toBe(1); expect(results.length).toBe(1);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return results matching "supplierFk"', async() => { it('should return results matching "supplierFk"', async() => {
let ctx = { const tx = await models.Buy.beginTransaction({});
const options = {transaction: tx};
try {
const ctx = {
args: { args: {
supplierFk: 1 supplierFk: 1
} }
}; };
let results = await app.models.Buy.latestBuysFilter(ctx); const results = await models.Buy.latestBuysFilter(ctx, options);
expect(results.length).toBe(2); expect(results.length).toBe(2);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return results matching "from" and "to"', async() => { it('should return results matching "from" and "to"', async() => {
const tx = await models.Buy.beginTransaction({});
const options = {transaction: tx};
try {
const from = new Date(); const from = new Date();
from.setHours(0, 0, 0, 0); from.setHours(0, 0, 0, 0);
const to = new Date(); const to = new Date();
to.setHours(23, 59, 59, 999); to.setHours(23, 59, 59, 999);
let ctx = { const ctx = {
args: { args: {
from: from, from: from,
to: to to: to
} }
}; };
let results = await app.models.Buy.latestBuysFilter(ctx); const results = await models.Buy.latestBuysFilter(ctx, options);
expect(results.length).toBe(2); expect(results.length).toBe(2);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
}); });

View File

@ -11,7 +11,7 @@ describe('SalesMonitor salesFilter()', () => {
const filter = {order: 'id DESC'}; const filter = {order: 'id DESC'};
const result = await models.SalesMonitor.salesFilter(ctx, filter, options); const result = await models.SalesMonitor.salesFilter(ctx, filter, options);
expect(result.length).toEqual(24); expect(result.length).toEqual(27);
await tx.rollback(); await tx.rollback();
} catch (e) { } catch (e) {
@ -39,7 +39,7 @@ describe('SalesMonitor salesFilter()', () => {
const filter = {}; const filter = {};
const result = await models.SalesMonitor.salesFilter(ctx, filter, options); const result = await models.SalesMonitor.salesFilter(ctx, filter, options);
expect(result.length).toEqual(13); expect(result.length).toEqual(16);
await tx.rollback(); await tx.rollback();
} catch (e) { } catch (e) {
@ -87,7 +87,7 @@ describe('SalesMonitor salesFilter()', () => {
const filter = {}; const filter = {};
const result = await models.SalesMonitor.salesFilter(ctx, filter, options); const result = await models.SalesMonitor.salesFilter(ctx, filter, options);
expect(result.length).toEqual(24); expect(result.length).toEqual(27);
await tx.rollback(); await tx.rollback();
} catch (e) { } catch (e) {
@ -130,7 +130,7 @@ describe('SalesMonitor salesFilter()', () => {
const length = result.length; const length = result.length;
const anyResult = result[Math.floor(Math.random() * Math.floor(length))]; const anyResult = result[Math.floor(Math.random() * Math.floor(length))];
expect(length).toEqual(7); expect(length).toEqual(10);
expect(anyResult.state).toMatch(/(Libre|Arreglar)/); expect(anyResult.state).toMatch(/(Libre|Arreglar)/);
await tx.rollback(); await tx.rollback();
@ -175,7 +175,7 @@ describe('SalesMonitor salesFilter()', () => {
const filter = {}; const filter = {};
const result = await models.SalesMonitor.salesFilter(ctx, filter, options); const result = await models.SalesMonitor.salesFilter(ctx, filter, options);
expect(result.length).toEqual(20); expect(result.length).toEqual(23);
await tx.rollback(); await tx.rollback();
} catch (e) { } catch (e) {

View File

@ -21,22 +21,42 @@ module.exports = Self => {
} }
}); });
Self.addToOrder = async params => { Self.addToOrder = async(params, options) => {
let isEditable = await Self.app.models.Order.isEditable(params.orderFk); const myOptions = {};
let tx;
if (typeof options == 'object')
Object.assign(myOptions, options);
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
try {
const isEditable = await Self.app.models.Order.isEditable(params.orderFk, myOptions);
if (!isEditable) if (!isEditable)
throw new UserError('This order is not editable'); throw new UserError('This order is not editable');
let promises = []; const promises = [];
params.items.forEach(item => { for (const item of params.items) {
promises.push( promises.push(
Self.rawSql( Self.rawSql(
`CALL hedera.order_addItem(?, ?, ?, ?)`, `CALL hedera.order_addItem(?, ?, ?, ?)`,
[params.orderFk, item.warehouseFk, item.itemFk, item.quantity] [params.orderFk, item.warehouseFk, item.itemFk, item.quantity],
myOptions
) )
); );
}); }
await Promise.all(promises); await Promise.all(promises);
if (tx) await tx.commit();
return true; return true;
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
}; };
}; };

View File

@ -21,19 +21,39 @@ module.exports = Self => {
} }
}); });
Self.removes = async params => { Self.removes = async(params, options) => {
const myOptions = {};
let tx;
if (typeof options == 'object')
Object.assign(myOptions, options);
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
try {
if (!params.rows || !params.rows.length) if (!params.rows || !params.rows.length)
throw new UserError('There is nothing to delete'); throw new UserError('There is nothing to delete');
let isEditable = await Self.app.models.Order.isEditable(params.actualOrderId); const isEditable = await Self.app.models.Order.isEditable(params.actualOrderId, myOptions);
if (!isEditable) if (!isEditable)
throw new UserError('This order is not editable'); throw new UserError('This order is not editable');
let promises = []; const promises = [];
for (let i = 0; i < params.rows.length; i++) for (let i = 0; i < params.rows.length; i++)
promises.push(Self.app.models.OrderRow.destroyById(params.rows[i])); promises.push(Self.app.models.OrderRow.destroyById(params.rows[i], myOptions));
return await Promise.all(promises); const deletions = await Promise.all(promises);
if (tx) await tx.commit();
return deletions;
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
}; };
}; };

View File

@ -1,18 +1,18 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('order addToOrder()', () => { describe('order addToOrder()', () => {
const orderId = 8; const orderId = 8;
let rowToDelete;
afterAll(async() => {
await app.models.OrderRow.removes({rows: [rowToDelete], actualOrderId: orderId});
});
it('should add a row to a given order', async() => { it('should add a row to a given order', async() => {
let unmodifiedRows = await app.models.OrderRow.find({where: {orderFk: orderId}}); const tx = await models.Order.beginTransaction({});
try {
const options = {transaction: tx};
const unmodifiedRows = await models.OrderRow.find({where: {orderFk: orderId}}, options);
expect(unmodifiedRows.length).toBe(2); expect(unmodifiedRows.length).toBe(2);
let params = { const params = {
orderFk: orderId, orderFk: orderId,
items: [{ items: [{
itemFk: 1, itemFk: 1,
@ -21,12 +21,16 @@ describe('order addToOrder()', () => {
}] }]
}; };
await app.models.OrderRow.addToOrder(params); await models.OrderRow.addToOrder(params, options);
let modifiedRows = await app.models.OrderRow.find({where: {orderFk: orderId}}); const modifiedRows = await models.OrderRow.find({where: {orderFk: orderId}}, options);
rowToDelete = modifiedRows[modifiedRows.length - 1].id;
expect(modifiedRows.length).toBe(3); expect(modifiedRows.length).toBe(3);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
}); });

View File

@ -1,20 +1,18 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('order removes()', () => { describe('order removes()', () => {
let row;
let newRow;
beforeAll(async() => {
row = await app.models.OrderRow.findOne({where: {id: 12}});
row.id = null;
newRow = await app.models.OrderRow.create(row);
});
it('should throw an error if rows property is empty', async() => { it('should throw an error if rows property is empty', async() => {
const tx = await models.Order.beginTransaction({});
let error; let error;
try { try {
await app.models.OrderRow.removes({rows: []}); const options = {transaction: tx};
await models.OrderRow.removes({rows: []}, options);
await tx.rollback();
} catch (e) { } catch (e) {
await tx.rollback();
error = e; error = e;
} }
@ -22,10 +20,17 @@ describe('order removes()', () => {
}); });
it('should throw an error if the row selected is not editable', async() => { it('should throw an error if the row selected is not editable', async() => {
const tx = await models.Order.beginTransaction({});
let error; let error;
try { try {
await app.models.OrderRow.removes({rows: [2]}); const options = {transaction: tx};
await models.OrderRow.removes({rows: [2]}, options);
await tx.rollback();
} catch (e) { } catch (e) {
await tx.rollback();
error = e; error = e;
} }
@ -33,13 +38,24 @@ describe('order removes()', () => {
}); });
it('should delete the row', async() => { it('should delete the row', async() => {
let params = { const tx = await models.Order.beginTransaction({});
rows: [newRow.id],
try {
const options = {transaction: tx};
const params = {
rows: [12],
actualOrderId: 16 actualOrderId: 16
}; };
let res = await app.models.OrderRow.removes(params); const res = await models.OrderRow.removes(params, options);
expect(res).toEqual([{count: 1}]); expect(res).toEqual([{count: 1}]);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
}); });

View File

@ -7,28 +7,28 @@ module.exports = Self => {
accepts: [ accepts: [
{ {
arg: 'orderFk', arg: 'orderFk',
type: 'Number', type: 'number',
required: true required: true
}, },
{ {
arg: 'orderBy', arg: 'orderBy',
type: 'Object', type: 'object',
description: 'Items order', description: 'Items order',
required: true required: true
}, },
{ {
arg: 'filter', arg: 'filter',
type: 'Object', type: 'object',
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string' description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string'
}, },
{ {
arg: 'tagGroups', arg: 'tagGroups',
type: ['Object'], type: ['object'],
description: 'Filter by tag' description: 'Filter by tag'
}, },
], ],
returns: { returns: {
type: ['Object'], type: ['object'],
root: true, root: true,
}, },
http: { http: {
@ -37,8 +37,13 @@ module.exports = Self => {
}, },
}); });
Self.catalogFilter = async(orderFk, orderBy, filter, tagGroups) => { Self.catalogFilter = async(orderFk, orderBy, filter, tagGroups, options) => {
let conn = Self.dataSource.connector; const conn = Self.dataSource.connector;
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
const stmts = []; const stmts = [];
let stmt; let stmt;
@ -85,7 +90,7 @@ module.exports = Self => {
stmts.push(stmt); stmts.push(stmt);
// Calculate items // Calculate items
const order = await Self.findById(orderFk); const order = await Self.findById(orderFk, null, myOptions);
stmts.push(new ParameterizedSQL( stmts.push(new ParameterizedSQL(
'CALL vn.catalog_calculate(?, ?, ?)', [ 'CALL vn.catalog_calculate(?, ?, ?)', [
order.landed, order.landed,
@ -131,9 +136,9 @@ module.exports = Self => {
params: [orderBy.field], params: [orderBy.field],
}); });
let way = orderBy.way == 'DESC' ? 'DESC' : 'ASC'; const way = orderBy.way == 'DESC' ? 'DESC' : 'ASC';
let tag = await Self.app.models.Tag.findById(orderBy.field); const tag = await Self.app.models.Tag.findById(orderBy.field, null, myOptions);
let orderSql = ` const orderSql = `
ORDER BY ORDER BY
itg.value IS NULL, itg.value IS NULL,
${tag.isQuantitative ? 'CAST(itg.value AS SIGNED)' : 'itg.value'} ${tag.isQuantitative ? 'CAST(itg.value AS SIGNED)' : 'itg.value'}
@ -181,7 +186,7 @@ module.exports = Self => {
stmts.push('CALL vn.ticketCalculatePurge()'); stmts.push('CALL vn.ticketCalculatePurge()');
const sql = ParameterizedSQL.join(stmts, ';'); const sql = ParameterizedSQL.join(stmts, ';');
const result = await conn.executeStmt(sql); const result = await conn.executeStmt(sql, myOptions);
// Add prices to items // Add prices to items
result[itemsIndex].forEach(item => { result[itemsIndex].forEach(item => {

View File

@ -21,7 +21,10 @@ module.exports = Self => {
Self.confirm = async(ctx, orderFk) => { Self.confirm = async(ctx, orderFk) => {
const userId = ctx.req.accessToken.userId; const userId = ctx.req.accessToken.userId;
let query = `CALL hedera.order_confirmWithUser(?, ?)`;
return await Self.rawSql(query, [orderFk, userId]); const query = `CALL hedera.order_confirmWithUser(?, ?)`;
const response = await Self.rawSql(query, [orderFk, userId]);
return response;
}; };
}; };

View File

@ -9,60 +9,60 @@ module.exports = Self => {
accepts: [ accepts: [
{ {
arg: 'ctx', arg: 'ctx',
type: 'Object', type: 'object',
http: {source: 'context'} http: {source: 'context'}
}, { }, {
arg: 'filter', arg: 'filter',
type: 'Object', type: 'object',
description: `Filter defining where, order, offset, and limit - must be a JSON-encoded string` description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string'
}, { }, {
arg: 'search', arg: 'search',
type: 'String', type: 'string',
description: `If it's and integer searchs by id, otherwise it searchs by nickname` description: `If it's and integer searchs by id, otherwise it searchs by nickname`
}, { }, {
arg: 'from', arg: 'from',
type: 'Date', type: 'date',
description: `The from date` description: 'The from date'
}, { }, {
arg: 'to', arg: 'to',
type: 'Date', type: 'date',
description: `The to date` description: 'The to date'
}, { }, {
arg: 'id', arg: 'id',
type: 'Integer', type: 'integer',
description: `The ticket id` description: 'The ticket id'
}, { }, {
arg: 'clientFk', arg: 'clientFk',
type: 'Integer', type: 'integer',
description: `The client id` description: 'The client id'
}, { }, {
arg: 'ticketFk', arg: 'ticketFk',
type: 'Integer', type: 'integer',
description: `The ticket id` description: 'The ticket id'
}, { }, {
arg: 'agencyModeFk', arg: 'agencyModeFk',
type: 'Integer', type: 'integer',
description: `The agency mode id` description: 'The agency mode id'
}, { }, {
arg: 'workerFk', arg: 'workerFk',
type: 'Integer', type: 'integer',
description: `The salesperson id` description: 'The salesperson id'
}, { }, {
arg: 'myTeam', arg: 'myTeam',
type: 'Boolean', type: 'boolean',
description: `Whether to show only tickets for the current logged user team (For now it shows only the current user tickets)` description: 'Whether to show only tickets for the current logged user team (currently user tickets)'
}, { }, {
arg: 'isConfirmed', arg: 'isConfirmed',
type: 'Boolean', type: 'boolean',
description: `Order is confirmed` description: 'Order is confirmed'
}, { }, {
arg: 'showEmpty', arg: 'showEmpty',
type: 'boolean', type: 'boolean',
description: `Show empty orders` description: 'Show empty orders'
} }
], ],
returns: { returns: {
type: ['Object'], type: ['object'],
root: true root: true
}, },
http: { http: {
@ -71,34 +71,35 @@ module.exports = Self => {
} }
}); });
Self.filter = async(ctx, filter) => { Self.filter = async(ctx, filter, options) => {
let conn = Self.dataSource.connector; const conn = Self.dataSource.connector;
let worker = await Self.app.models.Worker.findOne({ const myOptions = {};
where: {userFk: ctx.req.accessToken.userId},
include: [ if (typeof options == 'object')
{relation: 'collegues'} Object.assign(myOptions, options);
]
});
const args = ctx.args; const args = ctx.args;
let teamIds = [];
if (worker.collegues().length && args.myTeam) { // Apply filter by team
worker.collegues().forEach(collegue => { const teamMembersId = [];
teamIds.push(collegue.collegueFk); if (args.myTeam != null) {
}); const worker = await models.Worker.findById(userId, {
include: {
relation: 'collegues'
} }
}, myOptions);
const collegues = worker.collegues() || [];
for (let collegue of collegues)
teamMembersId.push(collegue.collegueFk);
if (worker.collegues().length === 0 && args.myTeam) { if (teamMembersId.length == 0)
worker = await Self.app.models.Worker.findOne({ teamMembersId.push(userId);
fields: ['id'],
where: {userFk: ctx.req.accessToken.userId}
});
teamIds = [worker && worker.id];
} }
if (args && args.myTeam) if (args && args.myTeam)
args.teamIds = teamIds; args.teamIds = teamIds;
let where = buildFilter(args, (param, value) => {
const where = buildFilter(args, (param, value) => {
switch (param) { switch (param) {
case 'search': case 'search':
return /^\d+$/.test(value) return /^\d+$/.test(value)
@ -123,7 +124,10 @@ module.exports = Self => {
case 'isConfirmed': case 'isConfirmed':
return {'o.confirmed': value ? 1 : 0}; return {'o.confirmed': value ? 1 : 0};
case 'myTeam': case 'myTeam':
return {'c.salesPersonFk': {inq: teamIds}}; if (value)
return {'c.salesPersonFk': {inq: teamMembersId}};
else
return {'c.salesPersonFk': {nin: teamMembersId}};
case 'showEmpty': case 'showEmpty':
return {'o.total': {neq: value}}; return {'o.total': {neq: value}};
case 'id': case 'id':
@ -133,7 +137,7 @@ module.exports = Self => {
}); });
filter = mergeFilters(filter, {where}); filter = mergeFilters(filter, {where});
let stmts = []; const stmts = [];
let stmt; let stmt;
stmt = new ParameterizedSQL( stmt = new ParameterizedSQL(
@ -183,7 +187,7 @@ module.exports = Self => {
stmts.push(`DROP TEMPORARY TABLE tmp.filter`); stmts.push(`DROP TEMPORARY TABLE tmp.filter`);
const sql = ParameterizedSQL.join(stmts, ';'); const sql = ParameterizedSQL.join(stmts, ';');
const result = await conn.executeStmt(sql); const result = await conn.executeStmt(sql, myOptions);
return result[ordersIndex]; return result[ordersIndex];
}; };

View File

@ -3,7 +3,7 @@ const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
module.exports = Self => { module.exports = Self => {
Self.remoteMethod('getItemTypeAvailable', { Self.remoteMethod('getItemTypeAvailable', {
description: 'Gets the item types available for an rder and item category ', description: 'Gets the item types available for an order and item category',
accessType: 'READ', accessType: 'READ',
accepts: [{ accepts: [{
arg: 'id', arg: 'id',
@ -27,11 +27,16 @@ module.exports = Self => {
} }
}); });
Self.getItemTypeAvailable = async(orderId, itemCategoryId) => { Self.getItemTypeAvailable = async(orderId, itemCategoryId, options) => {
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
const stmts = []; const stmts = [];
let stmt; let stmt;
const order = await app.models.Order.findById(orderId); const order = await app.models.Order.findById(orderId, null, myOptions);
stmt = new ParameterizedSQL('call vn.available_calc(?, ?, ?)', [ stmt = new ParameterizedSQL('call vn.available_calc(?, ?, ?)', [
order.landed, order.landed,
order.addressFk, order.addressFk,
@ -78,7 +83,7 @@ module.exports = Self => {
stmts.push('DROP TEMPORARY TABLE tmp.item'); stmts.push('DROP TEMPORARY TABLE tmp.item');
const sql = ParameterizedSQL.join(stmts, ';'); const sql = ParameterizedSQL.join(stmts, ';');
const result = await Self.rawStmt(sql); const result = await Self.rawStmt(sql, myOptions);
return result[categoriesIndex]; return result[categoriesIndex];
}; };

View File

@ -3,7 +3,7 @@ module.exports = Self => {
description: 'Gets the sourceApp type set', description: 'Gets the sourceApp type set',
accessType: 'READ', accessType: 'READ',
returns: { returns: {
type: ['String'], type: ['string'],
root: true root: true
}, },
http: { http: {

View File

@ -21,10 +21,14 @@ module.exports = Self => {
} }
}); });
Self.getTaxes = async orderFk => { Self.getTaxes = async(orderFk, options) => {
let conn = Self.dataSource.connector; const conn = Self.dataSource.connector;
let stmts = []; const stmts = [];
let stmt; let stmt;
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.order'); stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.order');
@ -37,15 +41,15 @@ module.exports = Self => {
stmts.push('CALL hedera.order_getTax()'); stmts.push('CALL hedera.order_getTax()');
let orderTaxIndex = stmts.push('SELECT * FROM tmp.orderAmount') - 1; const orderTaxIndex = stmts.push('SELECT * FROM tmp.orderAmount') - 1;
stmts.push(` stmts.push(`
DROP TEMPORARY TABLE DROP TEMPORARY TABLE
tmp.order, tmp.order,
tmp.orderTax`); tmp.orderTax`);
let sql = ParameterizedSQL.join(stmts, ';'); const sql = ParameterizedSQL.join(stmts, ';');
let result = await conn.executeStmt(sql); const result = await conn.executeStmt(sql, myOptions);
return result[orderTaxIndex]; return result[orderTaxIndex];
}; };

View File

@ -19,9 +19,14 @@ module.exports = Self => {
} }
}); });
Self.getTotal = async orderFk => { Self.getTotal = async(orderFk, options) => {
let query = `SELECT hedera.order_getTotal(?) total;`; const myOptions = {};
let [total] = await Self.rawSql(query, [orderFk]);
if (typeof options == 'object')
Object.assign(myOptions, options);
const query = `SELECT hedera.order_getTotal(?) total;`;
const [total] = await Self.rawSql(query, [orderFk], myOptions);
return total.total; return total.total;
}; };

View File

@ -19,9 +19,14 @@ module.exports = Self => {
} }
}); });
Self.getTotalVolume = async orderFk => { Self.getTotalVolume = async(orderFk, options) => {
let query = `SELECT vn.orderTotalVolume(?) totalVolume, vn.orderTotalVolumeBoxes(?) totalBoxes`; const myOptions = {};
let [res] = await Self.rawSql(query, [orderFk, orderFk]);
if (typeof options == 'object')
Object.assign(myOptions, options);
const query = `SELECT vn.orderTotalVolume(?) totalVolume, vn.orderTotalVolumeBoxes(?) totalBoxes`;
const [res] = await Self.rawSql(query, [orderFk, orderFk], myOptions);
return res; return res;
}; };
}; };

View File

@ -19,9 +19,14 @@ module.exports = Self => {
} }
}); });
Self.getVAT = async orderId => { Self.getVAT = async(orderId, options) => {
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
let totalTax = 0.00; let totalTax = 0.00;
let taxes = await Self.app.models.Order.getTaxes(orderId); const taxes = await Self.app.models.Order.getTaxes(orderId, myOptions);
taxes.forEach(tax => { taxes.forEach(tax => {
totalTax += tax.tax; totalTax += tax.tax;
}); });

View File

@ -18,8 +18,13 @@ module.exports = Self => {
} }
}); });
Self.getVolumes = async orderFk => { Self.getVolumes = async(orderFk, options) => {
let [volume] = await Self.rawSql(`CALL vn.orderListVolume(?)`, [orderFk]); const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
const [volume] = await Self.rawSql(`CALL vn.orderListVolume(?)`, [orderFk], myOptions);
return volume; return volume;
}; };
}; };

View File

@ -19,8 +19,13 @@ module.exports = Self => {
} }
}); });
Self.isEditable = async orderId => { Self.isEditable = async(orderId, options) => {
let exists = await Self.app.models.Order.findOne({ const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
const exists = await Self.app.models.Order.findOne({
where: {id: orderId}, where: {id: orderId},
fields: ['isConfirmed', 'clientFk'], fields: ['isConfirmed', 'clientFk'],
include: [ include: [
@ -32,7 +37,7 @@ module.exports = Self => {
} }
} }
] ]
}); }, myOptions);
if (exists && exists.client().type().code !== 'normal') if (exists && exists.client().type().code !== 'normal')
return true; return true;

View File

@ -32,8 +32,20 @@ module.exports = Self => {
} }
}); });
Self.new = async(landed, addressId, agencyModeId) => { Self.new = async(landed, addressId, agencyModeId, options) => {
let address = await Self.app.models.Address.findOne({ const myOptions = {};
let tx;
if (typeof options == 'object')
Object.assign(myOptions, options);
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
try {
const address = await Self.app.models.Address.findOne({
where: {id: addressId}, where: {id: addressId},
fields: ['clientFk'], fields: ['clientFk'],
include: [ include: [
@ -45,11 +57,11 @@ module.exports = Self => {
} }
} }
] ]
}); }, myOptions);
if (address.client().type().code === 'normal') { if (address.client().type().code === 'normal') {
if (!address.client().isActive) if (!address.client().isActive)
throw new UserError(`You can't create an order for a inactive client`); throw new UserError(`You can't create an order for an inactive client`);
} }
query = `CALL vn.orderListCreate(?, ?, ?, ?);`; query = `CALL vn.orderListCreate(?, ?, ?, ?);`;
@ -58,8 +70,14 @@ module.exports = Self => {
agencyModeId, agencyModeId,
addressId, addressId,
'SALIX' 'SALIX'
]); ], myOptions);
if (tx) await tx.commit();
return result[0].vOrderId; return result[0].vOrderId;
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
}; };
}; };

View File

@ -18,17 +18,35 @@ module.exports = Self => {
} }
}); });
Self.newFromTicket = async ticketFk => { Self.newFromTicket = async(ticketFk, options) => {
let ticket = await Self.app.models.Ticket.findOne({ const myOptions = {};
let tx;
if (typeof options == 'object')
Object.assign(myOptions, options);
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
try {
const ticket = await Self.app.models.Ticket.findOne({
where: {id: ticketFk} where: {id: ticketFk}
}); }, myOptions);
let landed = ticket.landed; const landed = ticket.landed;
let addressFk = ticket.addressFk; const addressFk = ticket.addressFk;
let agencyModeFk = ticket.agencyModeFk; const agencyModeFk = ticket.agencyModeFk;
let orderID = await Self.app.models.Order.new(landed, addressFk, agencyModeFk); const orderID = await Self.app.models.Order.new(landed, addressFk, agencyModeFk, myOptions);
if (tx) await tx.commit();
return orderID; return orderID;
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
}; };
}; };

View File

@ -1,27 +1,43 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('order catalogFilter()', () => { describe('order catalogFilter()', () => {
const colorTagId = 1; const colorTagId = 1;
const categoryTagId = 67; const categoryTagId = 67;
it('should return an array of items', async() => { it('should return an array of items', async() => {
let filter = { const tx = await models.Order.beginTransaction({});
try {
const options = {transaction: tx};
const filter = {
where: { where: {
categoryFk: 1, categoryFk: 1,
typeFk: 2 typeFk: 2
} }
}; };
let tags = []; const tags = [];
let orderFk = 11; const orderFk = 11;
let orderBy = {field: 'relevancy DESC, name', way: 'DESC'}; const orderBy = {field: 'relevancy DESC, name', way: 'DESC'};
let result = await app.models.Order.catalogFilter(orderFk, orderBy, filter, tags); const result = await models.Order.catalogFilter(orderFk, orderBy, filter, tags, options);
let firstItemId = result[0].id; const firstItemId = result[0].id;
expect(result.length).toEqual(4); expect(result.length).toEqual(4);
expect(firstItemId).toEqual(1); expect(firstItemId).toEqual(1);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should now return an array of items based on tag filter', async() => { it('should now return an array of items based on tag filter', async() => {
const tx = await models.Order.beginTransaction({});
try {
const options = {transaction: tx};
const filter = { const filter = {
where: { where: {
categoryFk: 1, categoryFk: 1,
@ -35,7 +51,7 @@ describe('order catalogFilter()', () => {
]; ];
const orderFk = 11; const orderFk = 11;
const orderBy = {field: 'relevancy DESC, name', way: 'DESC'}; const orderBy = {field: 'relevancy DESC, name', way: 'DESC'};
const result = await app.models.Order.catalogFilter(orderFk, orderBy, filter, tagGroups); const result = await models.Order.catalogFilter(orderFk, orderBy, filter, tagGroups, options);
const randomIndex = Math.round(Math.random()); const randomIndex = Math.round(Math.random());
const item = result[randomIndex]; const item = result[randomIndex];
@ -47,5 +63,11 @@ describe('order catalogFilter()', () => {
expect(result.length).toEqual(2); expect(result.length).toEqual(2);
expect(colorTag.value).toEqual('Silver'); expect(colorTag.value).toEqual('Silver');
expect(categoryTag.value).toEqual('Concussion'); expect(categoryTag.value).toEqual('Concussion');
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
}); });

View File

@ -1,4 +1,4 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('order filter()', () => { describe('order filter()', () => {
const ctx = { const ctx = {
@ -8,51 +8,107 @@ describe('order filter()', () => {
}; };
it('should call the filter method with a basic search', async() => { it('should call the filter method with a basic search', async() => {
const myCtx = Object.assign({}, ctx);
const tx = await models.Order.beginTransaction({});
try {
const options = {transaction: tx};
const filter = {where: {'o.id': 2}}; const filter = {where: {'o.id': 2}};
const result = await app.models.Order.filter(ctx, filter); const result = await models.Order.filter(myCtx, filter, options);
const orderId = result[0].id; const orderId = result[0].id;
expect(orderId).toEqual(2); expect(orderId).toEqual(2);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should call the filter method with a single advanced search', async() => { it('should call the filter method with a single advanced search', async() => {
const myCtx = Object.assign({}, ctx);
const tx = await models.Order.beginTransaction({});
try {
const options = {transaction: tx};
const filter = {where: {'o.confirmed': false}}; const filter = {where: {'o.confirmed': false}};
const result = await app.models.Order.filter(ctx, filter); const result = await models.Order.filter(myCtx, filter, options);
expect(result.length).toEqual(16); expect(result.length).toEqual(16);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should call the filter method with a complex advanced search', async() => { it('should call the filter method with a complex advanced search', async() => {
const myCtx = Object.assign({}, ctx);
const tx = await models.Order.beginTransaction({});
try {
const options = {transaction: tx};
const filter = {where: {'o.confirmed': false, 'c.salesPersonFk': 18}}; const filter = {where: {'o.confirmed': false, 'c.salesPersonFk': 18}};
const result = await app.models.Order.filter(ctx, filter); const result = await models.Order.filter(myCtx, filter, options);
expect(result.length).toEqual(9); expect(result.length).toEqual(9);
expect(result[0].id).toEqual(7); expect(result[0].id).toEqual(7);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return the orders matching the showEmpty on false', async() => { it('should return the orders matching the showEmpty on false', async() => {
const myCtx = Object.assign({}, ctx);
const tx = await models.Order.beginTransaction({});
try {
const options = {transaction: tx};
const filter = {}; const filter = {};
ctx.args = {showEmpty: false}; myCtx.args = {showEmpty: false};
const result = await app.models.Order.filter(ctx, filter); const result = await models.Order.filter(myCtx, filter, options);
const hasEmptyLines = result.some(order => { const hasEmptyLines = result.some(order => {
return order.total === 0; return order.total === 0;
}); });
expect(hasEmptyLines).toBeFalsy(); expect(hasEmptyLines).toBeFalsy();
ctx.args = {showEmpty: null}; await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return the orders matching the showEmpty on true', async() => { it('should return the orders matching the showEmpty on true', async() => {
const myCtx = Object.assign({}, ctx);
const tx = await models.Order.beginTransaction({});
try {
const options = {transaction: tx};
const filter = {}; const filter = {};
ctx.args = {showEmpty: true}; myCtx.args = {showEmpty: true};
const result = await app.models.Order.filter(ctx, filter); const result = await models.Order.filter(myCtx, filter, options);
const hasEmptyLines = result.some(order => { const hasEmptyLines = result.some(order => {
return order.total === 0; return order.total === 0;
}); });
expect(hasEmptyLines).toBeTruthy(); expect(hasEmptyLines).toBeTruthy();
ctx.args = {showEmpty: null}; await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
}); });

View File

@ -1,19 +1,41 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('order getItemTypeAvailable()', () => { describe('order getItemTypeAvailable()', () => {
it('should call the getItemTypeAvailable method with a valid order and item category', async() => { it('should call the getItemTypeAvailable method with a valid order and item category', async() => {
let orderId = 11; const tx = await models.Order.beginTransaction({});
let itemCategoryId = 1;
let result = await app.models.Order.getItemTypeAvailable(orderId, itemCategoryId); try {
const options = {transaction: tx};
const orderId = 11;
const itemCategoryId = 1;
const result = await models.Order.getItemTypeAvailable(orderId, itemCategoryId, options);
expect(result.length).toEqual(1); expect(result.length).toEqual(1);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should call the getItemTypeAvailable method with the same order and different item category', async() => { it('should call the getItemTypeAvailable method with the same order and different item category', async() => {
let orderId = 11; const tx = await models.Order.beginTransaction({});
let itemCategoryId = 4;//
let result = await app.models.Order.getItemTypeAvailable(orderId, itemCategoryId); try {
const options = {transaction: tx};
const orderId = 11;
const itemCategoryId = 4;
const result = await models.Order.getItemTypeAvailable(orderId, itemCategoryId, options);
expect(result.length).toEqual(0); expect(result.length).toEqual(0);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
}); });

View File

@ -1,31 +1,75 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('order getTaxes()', () => { describe('order getTaxes()', () => {
it('should call the getTaxes method and return undefined if its called with a string', async() => { it('should call the getTaxes method and return undefined if its called with a string', async() => {
let result = await app.models.Order.getTaxes('string'); const tx = await models.Order.beginTransaction({});
try {
const options = {transaction: tx};
const result = await models.Order.getTaxes('string', options);
expect(result.length).toEqual(0); expect(result.length).toEqual(0);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should call the getTaxes method and return undefined if its called with unknown id', async() => { it('should call the getTaxes method and return undefined if its called with unknown id', async() => {
let result = await app.models.Order.getTaxes(99999999999999999999999); const tx = await models.Order.beginTransaction({});
try {
const options = {transaction: tx};
const result = await models.Order.getTaxes(9999, options);
expect(result.length).toEqual(0); expect(result.length).toEqual(0);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should call the getTaxes method and return the taxes splited if different type of taxes', async() => { it('should call the getTaxes method and return the taxes splited if different type of taxes', async() => {
let result = await app.models.Order.getTaxes(1); const tx = await models.Order.beginTransaction({});
try {
const options = {transaction: tx};
const result = await models.Order.getTaxes(1, options);
const expectedResult = result[0].tax + result[1].tax; const expectedResult = result[0].tax + result[1].tax;
expect(expectedResult).toEqual(20.29); expect(expectedResult).toEqual(20.29);
expect(result.length).toEqual(2); expect(result.length).toEqual(2);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should call the getTaxes method and return the taxes for them same type', async() => { it('should call the getTaxes method and return the taxes for them same type', async() => {
let result = await app.models.Order.getTaxes(2); const tx = await models.Order.beginTransaction({});
try {
const options = {transaction: tx};
const result = await models.Order.getTaxes(2, options);
expect(result[0].tax).toEqual(9.1); expect(result[0].tax).toEqual(9.1);
expect(result.length).toEqual(1); expect(result.length).toEqual(1);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
}); });

View File

@ -1,9 +1,19 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('order getTotal()', () => { describe('order getTotal()', () => {
it('should return the order total', async() => { it('should return the order total', async() => {
let result = await app.models.Order.getTotal(1); const tx = await models.Order.beginTransaction({});
try {
const options = {transaction: tx};
const result = await models.Order.getTotal(1, options);
expect(result).toEqual(155.89); expect(result).toEqual(155.89);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
}); });

View File

@ -1,10 +1,21 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('order getTotalVolume()', () => { describe('order getTotalVolume()', () => {
it('should return the total', async() => { it('should return the total', async() => {
let result = await app.models.Order.getTotalVolume(1); const tx = await models.Order.beginTransaction({});
try {
const options = {transaction: tx};
const result = await models.Order.getTotalVolume(1, options);
expect(result.totalVolume).toEqual(1.568); expect(result.totalVolume).toEqual(1.568);
expect(result.totalBoxes).toEqual(11.1); expect(result.totalBoxes).toEqual(11.1);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
}); });

View File

@ -1,9 +1,20 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('order getVAT()', () => { describe('order getVAT()', () => {
it('should return the order VAT', async() => { it('should return the order VAT', async() => {
const result = await app.models.Order.getVAT(1); const tx = await models.Order.beginTransaction({});
try {
const options = {transaction: tx};
const result = await models.Order.getVAT(1, options);
expect(result).toEqual(20.29); expect(result).toEqual(20.29);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
}); });

View File

@ -1,9 +1,20 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('order getVolumes()', () => { describe('order getVolumes()', () => {
it('should return the volumes of a given order id', async() => { it('should return the volumes of a given order id', async() => {
let [result] = await app.models.Order.getVolumes(1); const tx = await models.Order.beginTransaction({});
try {
const options = {transaction: tx};
const [result] = await models.Order.getVolumes(1, options);
expect(result.volume).toEqual(1.09); expect(result.volume).toEqual(1.09);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
}); });

View File

@ -1,21 +1,54 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('order isEditable()', () => { describe('order isEditable()', () => {
it('should return false when the given order is not editable', async() => { it('should return false when the given order is not editable', async() => {
let isEditable = await app.models.Order.isEditable(2); const tx = await models.Order.beginTransaction({});
try {
const options = {transaction: tx};
const isEditable = await models.Order.isEditable(2, options);
expect(isEditable).toBeFalsy(); expect(isEditable).toBeFalsy();
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return false when the given order doesnt exists', async() => { it('should return false when the given order doesnt exists', async() => {
let isEditable = await app.models.Order.isEditable(99999); const tx = await models.Order.beginTransaction({});
try {
const options = {transaction: tx};
const isEditable = await models.Order.isEditable(999, options);
expect(isEditable).toBeFalsy(); expect(isEditable).toBeFalsy();
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return true when the given order is editable', async() => { it('should return true when the given order is editable', async() => {
let isEditable = await app.models.Order.isEditable(16); const tx = await models.Order.beginTransaction({});
try {
const options = {transaction: tx};
const isEditable = await models.Order.isEditable(16, options);
expect(isEditable).toBeTruthy(); expect(isEditable).toBeTruthy();
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
}); });

View File

@ -1,36 +1,49 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
let UserError = require('vn-loopback/util/user-error'); const UserError = require('vn-loopback/util/user-error');
describe('order new()', () => { describe('order new()', () => {
let orderId;
afterAll(async() => {
await app.models.Order.destroyById(orderId);
});
it('should throw an error if the client isnt active', async() => { it('should throw an error if the client isnt active', async() => {
const tx = await models.Order.beginTransaction({});
let error; let error;
let landed = new Date(); try {
let addressFk = 6; const options = {transaction: tx};
let agencyModeFk = 1;
await app.models.Order.new(landed, addressFk, agencyModeFk) const landed = new Date();
.catch(e => { const addressFk = 6;
const agencyModeFk = 1;
await models.Order.new(landed, addressFk, agencyModeFk, options);
await tx.rollback();
} catch (e) {
await tx.rollback();
error = e; error = e;
}); }
expect(error).toEqual(new UserError(`You can't create an order for a inactive client`)); expect(error).toEqual(new UserError(`You can't create an order for an inactive client`));
}); });
it('should now create a new order when all conditions are met', async() => { it('should now create a new order when all conditions are met', async() => {
let landed = new Date(); const tx = await models.Order.beginTransaction({});
let addressFk = 121;
let agencyModeFk = 1;
orderId = await app.models.Order.new(landed, addressFk, agencyModeFk); try {
const options = {transaction: tx};
let highestOrderIdInFixtures = 3; const landed = new Date();
const addressFk = 121;
const agencyModeFk = 1;
orderId = await models.Order.new(landed, addressFk, agencyModeFk, options);
const highestOrderIdInFixtures = 3;
expect(orderId).toBeGreaterThan(highestOrderIdInFixtures); expect(orderId).toBeGreaterThan(highestOrderIdInFixtures);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
}); });

View File

@ -0,0 +1,24 @@
const models = require('vn-loopback/server/server').models;
describe('order newFromTicket()', () => {
it('should create a new order from an existing ticket', async() => {
const tx = await models.Order.beginTransaction({});
try {
const options = {transaction: tx};
const ticketId = 11;
const orderId = await models.Order.newFromTicket(ticketId, options);
const highestOrderIdInFixtures = 3;
expect(orderId).toBeGreaterThan(highestOrderIdInFixtures);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
});

View File

@ -1,36 +1,91 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
describe('order summary()', () => { describe('order summary()', () => {
it('should return a summary object containing data from 1 order', async() => { it('should return a summary object containing data from 1 order', async() => {
let result = await app.models.Order.summary(1); const tx = await models.Order.beginTransaction({});
try {
const options = {transaction: tx};
const result = await models.Order.summary(1, options);
expect(result.id).toEqual(1); expect(result.id).toEqual(1);
expect(result.clientFk).toEqual(1101); expect(result.clientFk).toEqual(1101);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return a summary object containing sales from 1 order', async() => { it('should return a summary object containing sales from 1 order', async() => {
let result = await app.models.Order.summary(1); const tx = await models.Order.beginTransaction({});
try {
const options = {transaction: tx};
const result = await models.Order.summary(1, options);
expect(result.rows.length).toEqual(3); expect(result.rows.length).toEqual(3);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return a summary object containing subTotal for 1 order', async() => { it('should return a summary object containing subTotal for 1 order', async() => {
let result = await app.models.Order.summary(1); const tx = await models.Order.beginTransaction({});
try {
const options = {transaction: tx};
const result = await models.Order.summary(1, options);
expect(Math.round(result.subTotal * 100) / 100).toEqual(135.60); expect(Math.round(result.subTotal * 100) / 100).toEqual(135.60);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return a summary object containing VAT for 1 order', async() => { it('should return a summary object containing VAT for 1 order', async() => {
let result = await app.models.Order.summary(1); const tx = await models.Order.beginTransaction({});
try {
const options = {transaction: tx};
const result = await models.Order.summary(1, options);
expect(Math.round(result.VAT * 100) / 100).toEqual(20.29); expect(Math.round(result.VAT * 100) / 100).toEqual(20.29);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should return a summary object containing total for 1 order', async() => { it('should return a summary object containing total for 1 order', async() => {
let result = await app.models.Order.summary(1); const tx = await models.Order.beginTransaction({});
let total = result.subTotal + result.VAT;
let expectedTotal = Math.round(total * 100) / 100; try {
const options = {transaction: tx};
const result = await models.Order.summary(1, options);
const total = result.subTotal + result.VAT;
const expectedTotal = Math.round(total * 100) / 100;
expect(result.total).toEqual(expectedTotal); expect(result.total).toEqual(expectedTotal);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
}); });

View File

@ -1,61 +1,93 @@
const app = require('vn-loopback/server/server'); const models = require('vn-loopback/server/server').models;
const UserError = require('vn-loopback/util/user-error');
describe('Order updateBasicData', () => { describe('Order updateBasicData', () => {
const orderId = 21; const orderId = 21;
afterAll(async() => {
let validparams = {note: null};
await app.models.Order.updateBasicData(orderId, validparams);
});
it('should return an error if the order is confirmed', async() => { it('should return an error if the order is confirmed', async() => {
const tx = await models.Order.beginTransaction({});
let error; let error;
try {
const options = {transaction: tx};
const params = [];
const orderConfirmed = 1;
let params = []; await models.Order.updateBasicData(orderConfirmed, params, options);
let orderConfirmed = 1;
await app.models.Order.updateBasicData(orderConfirmed, params) await tx.rollback();
.catch(e => { } catch (e) {
await tx.rollback();
error = e; error = e;
}); }
const expectedError = `You can't make changes on the basic data of an confirmed order or with rows`;
expect(error.toString()).toContain(`You can't make changes on the basic data of an confirmed order or with rows`); expect(error).toEqual(new UserError(expectedError));
}); });
it('should return an error if the order has rows', async() => { it('should return an error if the order has rows', async() => {
const tx = await models.Order.beginTransaction({});
let error; let error;
try {
const options = {transaction: tx};
let params = []; const params = [];
let orderWithRows = 16; const orderWithRows = 16;
await app.models.Order.updateBasicData(orderWithRows, params) await models.Order.updateBasicData(orderWithRows, params, options);
.catch(e => {
await tx.rollback();
} catch (e) {
await tx.rollback();
error = e; error = e;
}); }
expect(error.toString()).toContain(`You can't make changes on the basic data of an confirmed order or with rows`); const expectedError = `You can't make changes on the basic data of an confirmed order or with rows`;
expect(error).toEqual(new UserError(expectedError));
}); });
it('should skip invalid params', async() => { it('should skip invalid params', async() => {
const tx = await models.Order.beginTransaction({});
try {
const options = {transaction: tx};
let success; let success;
let invalidparams = {invalid: 'param for update'}; const invalidparams = {invalid: 'param for update'};
await app.models.Order.updateBasicData(orderId, invalidparams) await models.Order.updateBasicData(orderId, invalidparams, options)
.then(() => success = true); .then(() => success = true);
expect(success).toBeTruthy(); expect(success).toBeTruthy();
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
it('should update the client fiscal data and return the count if changes made', async() => { it('should update the client fiscal data and return the count if changes made', async() => {
let validparams = {note: 'test note'}; const tx = await models.Order.beginTransaction({});
let order = await app.models.Order.findById(orderId); try {
const options = {transaction: tx};
const validparams = {note: 'test note'};
const order = await models.Order.findById(orderId, null, options);
expect(order.note).toEqual(null); expect(order.note).toEqual(null);
let result = await app.models.Order.updateBasicData(orderId, validparams); const result = await models.Order.updateBasicData(orderId, validparams, options);
expect(result.note).toEqual('test note'); expect(result.note).toEqual('test note');
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
}); });
}); });

View File

@ -19,17 +19,22 @@ module.exports = Self => {
} }
}); });
Self.summary = async orderId => { Self.summary = async(orderId, options) => {
let models = Self.app.models; const models = Self.app.models;
let summary = await getOrderData(Self, orderId); const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
const summary = await getOrderData(Self, orderId, myOptions);
summary.subTotal = getSubTotal(summary.rows); summary.subTotal = getSubTotal(summary.rows);
summary.VAT = await models.Order.getVAT(orderId); summary.VAT = await models.Order.getVAT(orderId, myOptions);
summary.total = await models.Order.getTotal(orderId); summary.total = await models.Order.getTotal(orderId, myOptions);
return summary; return summary;
}; };
async function getOrderData(Self, orderId) { async function getOrderData(Self, orderId, options) {
let filter = { const filter = {
include: [ include: [
{ {
relation: 'agencyMode', scope: {fields: ['name']}}, relation: 'agencyMode', scope: {fields: ['name']}},
@ -69,7 +74,7 @@ module.exports = Self => {
where: {id: orderId} where: {id: orderId}
}; };
return await Self.findOne(filter); return Self.findOne(filter, options);
} }
function getSubTotal(rows) { function getSubTotal(rows) {

View File

@ -31,16 +31,27 @@ module.exports = Self => {
} }
}); });
Self.updateBasicData = async(id, params) => { Self.updateBasicData = async(id, params, options) => {
let models = Self.app.models; const models = Self.app.models;
const myOptions = {};
let tx;
let order = await models.Order.findById(id); if (typeof options == 'object')
let orderRows = await models.OrderRow.find({where: {orderFk: id}}); Object.assign(myOptions, options);
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
try {
const order = await models.Order.findById(id, null, myOptions);
const orderRows = await models.OrderRow.find({where: {orderFk: id}}, myOptions);
if (order.isConfirmed || orderRows.length != 0) if (order.isConfirmed || orderRows.length != 0)
throw new UserError(`You can't make changes on the basic data of an confirmed order or with rows`); throw new UserError(`You can't make changes on the basic data of an confirmed order or with rows`);
let updateParams = pick(params, [ const updateParams = pick(params, [
'clientFk', 'clientFk',
'addressFk', 'addressFk',
'landed', 'landed',
@ -48,8 +59,14 @@ module.exports = Self => {
'note', 'note',
]); ]);
if (Object.keys(updateParams).length) if (Object.keys(updateParams).length)
await order.updateAttributes(updateParams); await order.updateAttributes(updateParams, myOptions);
return await order; if (tx) await tx.commit();
return order;
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
}; };
}; };

View File

@ -1,5 +1,5 @@
You can't create an order for a frozen client: No puedes crear una orden a un cliente congelado You can't create an order for a frozen client: No puedes crear una orden a un cliente congelado
You can't create an order for a inactive client: No puedes crear una orden a un cliente inactivo You can't create an order for an inactive client: No puedes crear una orden a un cliente inactivo
You can't create an order for a client that doesn't has tax data verified: You can't create an order for a client that doesn't has tax data verified:
No puedes crear una orden a un cliente cuyos datos fiscales no han sido verificados No puedes crear una orden a un cliente cuyos datos fiscales no han sido verificados
You can't create an order for a client that has a debt: No puedes crear una orden a un cliente que tiene deuda You can't create an order for a client that has a debt: No puedes crear una orden a un cliente que tiene deuda

View File

@ -29,9 +29,9 @@ describe('route getSuggestedTickets()', () => {
const length = result.length; const length = result.length;
const anyResult = result[Math.floor(Math.random() * Math.floor(length))]; const anyResult = result[Math.floor(Math.random() * Math.floor(length))];
expect(result.length).toEqual(1); expect(result.length).toEqual(4);
expect(anyResult.zoneFk).toEqual(1); expect(anyResult.zoneFk).toEqual(1);
expect(anyResult.agencyModeFk).toEqual(1); expect(anyResult.agencyModeFk).toEqual(8);
await tx.rollback(); await tx.rollback();
} catch (e) { } catch (e) {

View File

@ -11,7 +11,7 @@ describe('ticket filter()', () => {
const filter = {order: 'id DESC'}; const filter = {order: 'id DESC'};
const result = await models.Ticket.filter(ctx, filter, options); const result = await models.Ticket.filter(ctx, filter, options);
expect(result.length).toEqual(24); expect(result.length).toEqual(27);
await tx.rollback(); await tx.rollback();
} catch (e) { } catch (e) {
@ -87,7 +87,7 @@ describe('ticket filter()', () => {
const filter = {}; const filter = {};
const result = await models.Ticket.filter(ctx, filter, options); const result = await models.Ticket.filter(ctx, filter, options);
expect(result.length).toEqual(24); expect(result.length).toEqual(27);
await tx.rollback(); await tx.rollback();
} catch (e) { } catch (e) {
@ -130,7 +130,7 @@ describe('ticket filter()', () => {
const length = result.length; const length = result.length;
const anyResult = result[Math.floor(Math.random() * Math.floor(length))]; const anyResult = result[Math.floor(Math.random() * Math.floor(length))];
expect(length).toEqual(7); expect(length).toEqual(10);
expect(anyResult.state).toMatch(/(Libre|Arreglar)/); expect(anyResult.state).toMatch(/(Libre|Arreglar)/);
await tx.rollback(); await tx.rollback();
@ -175,7 +175,7 @@ describe('ticket filter()', () => {
const filter = {}; const filter = {};
const result = await models.Ticket.filter(ctx, filter, options); const result = await models.Ticket.filter(ctx, filter, options);
expect(result.length).toEqual(20); expect(result.length).toEqual(23);
await tx.rollback(); await tx.rollback();
} catch (e) { } catch (e) {

View File

@ -10,6 +10,10 @@
</slot-dot-menu> </slot-dot-menu>
<slot-body> <slot-body>
<div class="attributes"> <div class="attributes">
<vn-label-value
label="Client"
value="{{$ctrl.ticket.client.id}}">
</vn-label-value>
<vn-label-value <vn-label-value
label="State" label="State"
value="{{$ctrl.ticket.ticketState.state.name}}"> value="{{$ctrl.ticket.ticketState.state.name}}">

View File

@ -0,0 +1,8 @@
const Stylesheet = require(`${appPath}/core/stylesheet`);
module.exports = new Stylesheet([
`${appPath}/common/css/layout.css`,
`${appPath}/common/css/report.css`,
`${appPath}/common/css/misc.css`,
`${__dirname}/style.css`])
.mergeStyles();

View File

@ -0,0 +1,31 @@
.grid-block {
font-size: 1.2em
}
.signature .dummy-signature {
width: 400px;
height: 190px;
display: block;
content: '';
overflow: hidden;
clear:both
}
.signature img {
width: 400px
}
.signature table {
width: 100%;
font-size: inherit;
border-collapse: separate;
border-spacing: 0 10px;
}
.signature table tr > td:first-child {
width: 50%
}
.signature table tr > td:last-child {
border-bottom: 1px dashed #CCC
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

View File

@ -0,0 +1,99 @@
<!DOCTYPE html>
<html v-bind:lang="$i18n.locale">
<body>
<table class="grid">
<tbody>
<tr>
<td>
<!-- Header block -->
<report-header v-bind="$props"></report-header>
<!-- Block -->
<div class="grid-row">
<div class="grid-block">
<p v-html="$t('description', {
socialName: client.socialName,
name: client.name,
address: client.street,
country: client.country,
fiscalID: client.fi
})"></p>
<p v-html="$t('declaration', {
socialName: client.socialName
})"></p>
<p
v-for="(declaration, $index) in $t('declarations')"
v-html="$t('declarations[' + $index + ']', {
socialName: client.socialName,
destinationCountry: ticket.country,
destinationWarehouse: ticket.warehouse
})">
</p>
<div class="columns">
<div class="size50 signature">
<p class="centered">{{client.name}}</p>
<div class="dummy-signature centered"></div>
<p>
<table>
<tbody>
<tr>
<td>{{$t('signer.representative')}}:</td>
<td></td>
</tr>
<tr>
<td>{{$t('signer.representativeRole')}}:</td>
<td></td>
</tr>
<tr>
<td>{{$t('signer.signed')}}:</td>
<td></td>
</tr>
</tbody>
</table>
</p>
</div>
<div class="size50 signature centered">
<p>{{$t('signature')}}</p>
<img v-bind:src="getReportSrc('signature.png')">
<p>
<div>Juan Vicente Ferrer Roig</div>
<div>Director</div>
<p>{{$t('issued', [
'Algemesí',
issued.getDate(),
$t('months')[issued.getMonth()],
issued.getFullYear()])
}}
</p>
</p>
</div>
</div>
<!-- <div class="signature">
<p>{{$t('issued', [
'Algemesí',
invoice.issued.getDate(),
$t('months')[invoice.issued.getMonth()],
invoice.issued.getFullYear()])
}}
</p>
<p><em>({{$t('signature')}})</em></p>
<img v-bind:src="getReportSrc('signature.png')">
<p>
<div>{{$t('signer.name')}}: JUAN VICENTE FERRER ROIG</div>
<div>{{$t('signer.ID')}}: 73943586N</div>
<div>{{$t('signer.position')}}: ADMINISTRADOR</div>
</p>
</div> -->
</div>
</div>
<!-- Footer block -->
<report-footer id="pageFooter"
v-bind:left-text="$t('client', [client.id])"
v-bind="$props">
</report-footer>
</td>
</tr>
</tbody>
</table>
</body>
</html>

View File

@ -0,0 +1,29 @@
const Component = require(`${appPath}/core/component`);
const reportHeader = new Component('report-header');
const reportFooter = new Component('report-footer');
module.exports = {
name: 'cmr-authorization',
async serverPrefetch() {
this.ticket = await this.findOneFromDef('ticket', [this.ticketId]);
if (!this.ticket)
throw new Error('Something went wrong');
this.client = await this.findOneFromDef('client', [this.ticket.clientFk]);
},
computed: {
issued: function() {
return new Date();
}
},
components: {
'report-header': reportHeader.build(),
'report-footer': reportFooter.build()
},
props: {
ticketId: {
required: true
}
}
};

View File

@ -0,0 +1,41 @@
description: '<em>{socialName}</em> una sociedad debidamente constituida con responsabilidad <em>limitada</em>
y registrada conforme al derecho de sociedades de {country} y aquí representada por
<span>___________________</span>. {socialName}, con domicilio en {address},
CIF <em>{fiscalID}</em>. En adelante denominada {name}.'
issued: 'En {0}, a {1} de {2} de {3}'
client: 'Client {0}'
declaration: '<em>{socialName}</em> declara por la presente que:'
declarations:
- 'Todas las compras realizadas por {socialName} con Verdnatura Levante, S.L. se
entregan, Ex Works (Incoterms), en el almacén de Verdnatura Levante, S.L. situado en
{destinationWarehouse}.'
- '{socialName} reconoce que es importante para Verdnatura Levante, S.L. tener
comprobante de la entrega intracomunitaria de la mercancía a {destinationCountry} para
poder facturar con 0% de IVA.'
- 'Por tanto, al firmar este acuerdo, {socialName} declara que todos los bienes que
se compren a Verdnatura Levante, S.L. serán entregados a {destinationCountry}.'
- 'Además, {socialName} deberá, a primera solicitud de Verdnatura Levante, S.L.,
proporcionar una prueba de que todos los productos comprados a Verdnatura Levante, S.L. han
sido entregados en {destinationCountry}.'
- 'Además de lo anterior, Verdnatura Levante, S.L. proporcionará a {socialName}
un resumen mensual en el que se incluyen todas las facturas (y las entregas correspondientes).
{socialName} firmará y devolverá el resumen mensual a Verdnatura Levante,
S.L. dentro de los 5 días posteriores a la recepción del resumen.'
signature: Verdnatura Levante, S.L.
signer:
representative: Representante
representativeRole: Cargo del representante
signed: Fecha de firma
months:
- 'Enero'
- 'Febrero'
- 'Marzo'
- 'Abril'
- 'Mayo'
- 'Junio'
- 'Julio'
- 'Agosto'
- 'Septiembre'
- 'Octubre'
- 'Noviembre'
- 'Diciembre'

View File

@ -0,0 +1,10 @@
SELECT
c.id,
c.socialName,
c.name,
c.fi,
c.street,
cty.country
FROM client c
JOIN country cty ON cty.id = c.countryFk
WHERE c.id = ?

View File

@ -0,0 +1,12 @@
SELECT
t.id,
t.clientFk,
cty.country,
w.name AS warehouse
FROM ticket t
JOIN warehouse w ON w.id = t.warehouseFk
JOIN address a ON a.id = t.addressFk
JOIN province p ON p.id = a.provinceFk
JOIN autonomy au ON au.id = p.autonomyFk
JOIN country cty ON cty.id = au.countryFk
WHERE t.id = ?