Merge pull request '2973-module_zone_transactions' (#669) from 2973-module_zone_transactions into dev
gitea/salix/pipeline/head This commit looks good
Details
gitea/salix/pipeline/head This commit looks good
Details
Reviewed-on: #669 Reviewed-by: Joan Sanchez <joan@verdnatura.es>
This commit is contained in:
commit
7d93f0ac0e
|
@ -6,7 +6,7 @@ module.exports = Self => {
|
|||
description: 'Returns a list of agencies from a warehouse',
|
||||
accepts: [{
|
||||
arg: 'filter',
|
||||
type: 'Object',
|
||||
type: 'object',
|
||||
description: `Filter defining where, order, offset, and limit - must be a JSON-encoded string`
|
||||
}],
|
||||
returns: {
|
||||
|
@ -19,9 +19,14 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.byWarehouse = async filter => {
|
||||
Self.byWarehouse = async(filter, options) => {
|
||||
const conn = Self.dataSource.connector;
|
||||
const where = {isActive: true};
|
||||
let myOptions = {};
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
filter = mergeFilters(filter, {where});
|
||||
|
||||
let stmt = new ParameterizedSQL(
|
||||
|
@ -30,7 +35,9 @@ module.exports = Self => {
|
|||
SELECT DISTINCT am.id, am.name, am.isActive, zw.warehouseFk
|
||||
FROM zoneWarehouse zw
|
||||
JOIN zone z ON z.id = zw.zoneFk
|
||||
JOIN agencyMode am ON am.id = z.agencyModeFk) am`);
|
||||
JOIN agencyMode am ON am.id = z.agencyModeFk) am`,
|
||||
null, myOptions);
|
||||
|
||||
stmt.merge(conn.makeSuffix(filter));
|
||||
|
||||
return conn.executeStmt(stmt);
|
||||
|
|
|
@ -4,17 +4,41 @@ describe('AgencyMode byWarehhouse()', () => {
|
|||
const warehouseId = 1;
|
||||
it('should return all the agencies', async() => {
|
||||
const where = {};
|
||||
const agencies = await app.models.AgencyMode.byWarehouse({where});
|
||||
|
||||
expect(agencies.length).toBeGreaterThan(10);
|
||||
const tx = await app.models.Zone.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const agencies = await app.models.AgencyMode.byWarehouse({where}, options);
|
||||
|
||||
expect(agencies.length).toBeGreaterThan(10);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
it('should return only the agencies for a warehouse', async() => {
|
||||
const where = {warehouseFk: warehouseId};
|
||||
const agencies = await app.models.AgencyMode.byWarehouse({where});
|
||||
const validWarehouse = agencies.every(agency => agency.warehouseFk = warehouseId);
|
||||
|
||||
expect(agencies.length).toEqual(6);
|
||||
expect(validWarehouse).toBeTruthy();
|
||||
const tx = await app.models.Zone.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const agencies = await app.models.AgencyMode.byWarehouse({where}, options);
|
||||
const validWarehouse = agencies.every(agency => agency.warehouseFk = warehouseId);
|
||||
|
||||
expect(agencies.length).toEqual(6);
|
||||
expect(validWarehouse).toBeTruthy();
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -6,11 +6,13 @@ module.exports = Self => {
|
|||
arg: 'addressFk',
|
||||
type: 'number',
|
||||
required: true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
arg: 'landed',
|
||||
type: 'date',
|
||||
required: true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
arg: 'warehouseFk',
|
||||
type: 'number',
|
||||
required: true
|
||||
|
@ -26,9 +28,15 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.getAgenciesWithWarehouse = async(addressFk, landed, warehouseFk) => {
|
||||
let query = `CALL vn.zone_getWarehouse(?, ?, ?)`;
|
||||
let [result] = await Self.rawSql(query, [addressFk, landed, warehouseFk]);
|
||||
Self.getAgenciesWithWarehouse = async(addressFk, landed, warehouseFk, options) => {
|
||||
let myOptions = {};
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
const query = 'CALL vn.zone_getWarehouse(?, ?, ?)';
|
||||
const [result] = await Self.rawSql(query, [addressFk, landed, warehouseFk], myOptions);
|
||||
|
||||
return result;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -34,7 +34,12 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.getLanded = async(ctx, shipped, addressFk, agencyModeFk, warehouseFk) => {
|
||||
Self.getLanded = async(ctx, shipped, addressFk, agencyModeFk, warehouseFk, options) => {
|
||||
let myOptions = {};
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
const userId = ctx.req.accessToken.userId;
|
||||
const models = Self.app.models;
|
||||
const roles = await models.Account.getRoles(userId);
|
||||
|
@ -44,23 +49,24 @@ module.exports = Self => {
|
|||
let showExpired = false;
|
||||
if (canSeeExpired.length) showExpired = true;
|
||||
|
||||
let stmts = [];
|
||||
const stmts = [];
|
||||
stmts.push(new ParameterizedSQL(
|
||||
`CALL vn.zone_getLanded(?, ?, ?, ?, ?)`, [
|
||||
'CALL vn.zone_getLanded(?, ?, ?, ?, ?)', [
|
||||
shipped,
|
||||
addressFk,
|
||||
agencyModeFk,
|
||||
warehouseFk,
|
||||
showExpired
|
||||
]
|
||||
],
|
||||
myOptions
|
||||
));
|
||||
|
||||
let rsIndex = stmts.push(
|
||||
`SELECT * FROM tmp.zoneGetLanded`) - 1;
|
||||
stmts.push(`DROP TEMPORARY TABLE tmp.zoneGetLanded`);
|
||||
const rsIndex = stmts.push('SELECT * FROM tmp.zoneGetLanded') - 1;
|
||||
|
||||
let sql = ParameterizedSQL.join(stmts, ';');
|
||||
let landed = await Self.rawStmt(sql);
|
||||
stmts.push('DROP TEMPORARY TABLE tmp.zoneGetLanded');
|
||||
|
||||
const sql = ParameterizedSQL.join(stmts, ';');
|
||||
const landed = await Self.rawStmt(sql, myOptions);
|
||||
|
||||
return landed[rsIndex][0];
|
||||
};
|
||||
|
|
|
@ -40,7 +40,7 @@ module.exports = Self => {
|
|||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
let stmts = [];
|
||||
const stmts = [];
|
||||
stmts.push(new ParameterizedSQL(
|
||||
`CALL vn.zone_getShippedWarehouse(?, ?, ?)`, [
|
||||
landed,
|
||||
|
|
|
@ -22,13 +22,18 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.landsThatDay = async(addressFk, landed) => {
|
||||
Self.landsThatDay = async(addressFk, landed, options) => {
|
||||
let myOptions = {};
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
let query = `
|
||||
CALL vn.zone_getAgency(?, ?);
|
||||
SELECT * FROM tmp.zoneGetAgency;
|
||||
DROP TEMPORARY TABLE tmp.zoneGetAgency;
|
||||
`;
|
||||
let result = await Self.rawSql(query, [addressFk, landed]);
|
||||
const result = await Self.rawSql(query, [addressFk, landed], myOptions);
|
||||
|
||||
return result[1];
|
||||
};
|
||||
|
|
|
@ -3,17 +3,39 @@ const app = require('vn-loopback/server/server');
|
|||
describe('Agency getAgenciesWithWarehouse()', () => {
|
||||
const today = new Date();
|
||||
it('should return the agencies that can handle the given delivery request', async() => {
|
||||
let agencies = await app.models.Agency.getAgenciesWithWarehouse(101, today, 1);
|
||||
const tx = await app.models.Zone.beginTransaction({});
|
||||
|
||||
expect(agencies.length).toEqual(3);
|
||||
expect(agencies[0].agencyMode).toEqual('inhouse pickup');
|
||||
expect(agencies[1].agencyMode).toEqual('Other agency');
|
||||
expect(agencies[2].agencyMode).toEqual('Refund');
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const agencies = await app.models.Agency.getAgenciesWithWarehouse(101, today, 1, options);
|
||||
|
||||
expect(agencies.length).toEqual(3);
|
||||
expect(agencies[0].agencyMode).toEqual('inhouse pickup');
|
||||
expect(agencies[1].agencyMode).toEqual('Other agency');
|
||||
expect(agencies[2].agencyMode).toEqual('Refund');
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
it('should return no agencies if the date is incorrect', async() => {
|
||||
let agencies = await app.models.Agency.getAgenciesWithWarehouse(101, null, 1);
|
||||
const tx = await app.models.Zone.beginTransaction({});
|
||||
|
||||
expect(agencies.length).toEqual(0);
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const agencies = await app.models.Agency.getAgenciesWithWarehouse(101, null, 1, options);
|
||||
|
||||
expect(agencies.length).toEqual(0);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -8,8 +8,20 @@ describe('agency getLanded()', () => {
|
|||
const addressFk = 121;
|
||||
const agencyModeFk = 7;
|
||||
const warehouseFk = 1;
|
||||
let result = await app.models.Agency.getLanded(ctx, shipped, addressFk, agencyModeFk, warehouseFk);
|
||||
|
||||
expect(result.landed).toBeDefined();
|
||||
const tx = await app.models.Zone.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const result = await app.models.Agency.getLanded(ctx, shipped, addressFk, agencyModeFk, warehouseFk, options);
|
||||
|
||||
expect(result.landed).toBeDefined();
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,50 +2,49 @@ const app = require('vn-loopback/server/server');
|
|||
|
||||
describe('agency getShipped()', () => {
|
||||
it('should return a shipment date', async() => {
|
||||
const landed = new Date();
|
||||
landed.setDate(landed.getDate() + 1);
|
||||
const addressFk = 121;
|
||||
const agencyModeFk = 7;
|
||||
const warehouseFk = 1;
|
||||
|
||||
const tx = await app.models.Agency.beginTransaction({});
|
||||
let result;
|
||||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const landed = new Date();
|
||||
landed.setDate(landed.getDate() + 1);
|
||||
const addressFk = 121;
|
||||
const agencyModeFk = 7;
|
||||
const warehouseFk = 1;
|
||||
const result = await app.models.Agency.getShipped(landed, addressFk, agencyModeFk, warehouseFk, options);
|
||||
|
||||
result = await app.models.Agency.getShipped(landed, addressFk, agencyModeFk, warehouseFk, options);
|
||||
expect(result).toBeDefined();
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
|
||||
expect(result).toBeDefined();
|
||||
});
|
||||
|
||||
it('should not return a shipment date', async() => {
|
||||
const newDate = new Date();
|
||||
newDate.setMonth(newDate.getMonth() - 1);
|
||||
const landed = newDate;
|
||||
const addressFk = 121;
|
||||
const agencyModeFk = 7;
|
||||
const warehouseFk = 1;
|
||||
|
||||
const tx = await app.models.Agency.beginTransaction({});
|
||||
let result;
|
||||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
let newDate = new Date();
|
||||
newDate.setMonth(newDate.getMonth() - 1);
|
||||
const landed = newDate;
|
||||
const addressFk = 121;
|
||||
const agencyModeFk = 7;
|
||||
const warehouseFk = 1;
|
||||
|
||||
result = await app.models.Agency.getShipped(landed, addressFk, agencyModeFk, warehouseFk, options);
|
||||
const result = await app.models.Agency.getShipped(landed, addressFk, agencyModeFk, warehouseFk, options);
|
||||
|
||||
expect(result).toBeUndefined();
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -3,8 +3,19 @@ const app = require('vn-loopback/server/server');
|
|||
describe('Agency landsThatDay()', () => {
|
||||
const today = new Date();
|
||||
it('should return a list of agencies that can land a shipment on a day for an address', async() => {
|
||||
let agencies = await app.models.Agency.landsThatDay(101, today);
|
||||
const tx = await app.models.Agency.beginTransaction({});
|
||||
|
||||
expect(agencies.length).toBeGreaterThanOrEqual(3);
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const agencies = await app.models.Agency.landsThatDay(101, today, options);
|
||||
|
||||
expect(agencies.length).toBeGreaterThanOrEqual(3);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -11,7 +11,7 @@ module.exports = Self => {
|
|||
},
|
||||
returns: {
|
||||
root: true,
|
||||
type: 'Object'
|
||||
type: 'object'
|
||||
},
|
||||
http: {
|
||||
path: '/:id/clone',
|
||||
|
@ -19,13 +19,20 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.clone = async id => {
|
||||
Self.clone = async(id, options) => {
|
||||
const models = Self.app.models;
|
||||
const tx = await Self.beginTransaction({});
|
||||
let tx;
|
||||
let myOptions = {};
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
if (!myOptions.transaction) {
|
||||
tx = await Self.beginTransaction({});
|
||||
myOptions.transaction = tx;
|
||||
}
|
||||
|
||||
try {
|
||||
let options = {transaction: tx};
|
||||
|
||||
// Find original zone
|
||||
const zone = await models.Zone.findOne({
|
||||
fields: [
|
||||
|
@ -37,37 +44,37 @@ module.exports = Self => {
|
|||
'bonus',
|
||||
'isVolumetric'],
|
||||
where: {id}
|
||||
}, options);
|
||||
}, myOptions);
|
||||
|
||||
// Find all original included geolocations
|
||||
const includedGeo = await models.ZoneIncluded.find({
|
||||
fields: ['geoFk', 'isIncluded'],
|
||||
where: {zoneFk: id}
|
||||
}, options);
|
||||
}, myOptions);
|
||||
|
||||
// Find all original selected days
|
||||
const calendarDays = await models.ZoneEvent.find({
|
||||
fields: {id: false},
|
||||
where: {zoneFk: id}
|
||||
}, options);
|
||||
}, myOptions);
|
||||
|
||||
const newZone = await Self.create(zone, options);
|
||||
const newZone = await Self.create(zone, myOptions);
|
||||
const newIncludedGeo = includedGeo.map(included => {
|
||||
included.zoneFk = newZone.id;
|
||||
return included;
|
||||
});
|
||||
const newCalendayDays = calendarDays.map(day => {
|
||||
const newCalendarDays = calendarDays.map(day => {
|
||||
day.zoneFk = newZone.id;
|
||||
return day;
|
||||
});
|
||||
|
||||
await models.ZoneIncluded.create(newIncludedGeo, options);
|
||||
await models.ZoneEvent.create(newCalendayDays, options);
|
||||
await tx.commit();
|
||||
await models.ZoneIncluded.create(newIncludedGeo, myOptions);
|
||||
await models.ZoneEvent.create(newCalendarDays, myOptions);
|
||||
if (tx) await tx.commit();
|
||||
|
||||
return newZone;
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
if (tx) await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -4,12 +4,12 @@ module.exports = Self => {
|
|||
accessType: 'WRITE',
|
||||
accepts: {
|
||||
arg: 'id',
|
||||
type: 'Number',
|
||||
type: 'number',
|
||||
description: 'The zone id',
|
||||
http: {source: 'path'}
|
||||
},
|
||||
returns: {
|
||||
type: 'Object',
|
||||
type: 'object',
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
|
@ -18,15 +18,25 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.deleteZone = async(ctx, id) => {
|
||||
Self.deleteZone = async(ctx, id, options) => {
|
||||
const models = Self.app.models;
|
||||
const token = ctx.req.accessToken;
|
||||
const userId = token.userId;
|
||||
const today = new Date();
|
||||
today.setHours(0, 0, 0, 0);
|
||||
const tx = await Self.beginTransaction({});
|
||||
|
||||
let tx;
|
||||
let myOptions = {};
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
if (!myOptions.transaction) {
|
||||
tx = await Self.beginTransaction({});
|
||||
myOptions.transaction = tx;
|
||||
}
|
||||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
const filter = {
|
||||
where: {
|
||||
zoneFk: id,
|
||||
|
@ -41,13 +51,13 @@ module.exports = Self => {
|
|||
};
|
||||
const promises = [];
|
||||
|
||||
const ticketList = await models.Ticket.find(filter, options);
|
||||
const fixingState = await models.State.findOne({where: {code: 'FIXING'}}, options);
|
||||
const ticketList = await models.Ticket.find(filter, myOptions);
|
||||
const fixingState = await models.State.findOne({where: {code: 'FIXING'}}, myOptions);
|
||||
const worker = await models.Worker.findOne({
|
||||
where: {userFk: userId}
|
||||
}, options);
|
||||
}, myOptions);
|
||||
|
||||
await models.Ticket.rawSql('UPDATE ticket SET zoneFk = NULL WHERE zoneFk = ?', [id], options);
|
||||
await models.Ticket.rawSql('UPDATE ticket SET zoneFk = NULL WHERE zoneFk = ?', [id], myOptions);
|
||||
|
||||
for (ticket of ticketList) {
|
||||
if (ticket.ticketState().alertLevel == 0) {
|
||||
|
@ -55,16 +65,17 @@ module.exports = Self => {
|
|||
ticketFk: ticket.id,
|
||||
stateFk: fixingState.id,
|
||||
workerFk: worker.id
|
||||
}, options));
|
||||
}, myOptions));
|
||||
}
|
||||
}
|
||||
await Promise.all(promises);
|
||||
await models.Zone.destroyById(id, options);
|
||||
await tx.commit();
|
||||
await Promise.all(promises, myOptions);
|
||||
await models.Zone.destroyById(id, myOptions);
|
||||
|
||||
if (tx) await tx.commit();
|
||||
|
||||
return id;
|
||||
} catch (err) {
|
||||
await tx.rollback();
|
||||
if (tx) await tx.rollback();
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -5,17 +5,18 @@ module.exports = Self => {
|
|||
accepts: [
|
||||
{
|
||||
arg: 'geoFk',
|
||||
type: 'Number',
|
||||
type: 'number',
|
||||
description: 'The geo id'
|
||||
}, {
|
||||
},
|
||||
{
|
||||
arg: 'agencyModeFk',
|
||||
type: 'Number',
|
||||
type: 'number',
|
||||
description: 'The agency mode id'
|
||||
}
|
||||
|
||||
],
|
||||
returns: {
|
||||
type: 'Object',
|
||||
type: 'object',
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
|
@ -24,11 +25,14 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.getEvents = async(geoFk, agencyModeFk) => {
|
||||
let [events, exclusions] = await Self.rawSql(
|
||||
`CALL zone_getEvents(?, ?)`,
|
||||
[geoFk, agencyModeFk]
|
||||
);
|
||||
Self.getEvents = async(geoFk, agencyModeFk, options) => {
|
||||
let myOptions = {};
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
const [events, exclusions] = await Self.rawSql('CALL zone_getEvents(?, ?)', [geoFk, agencyModeFk], myOptions);
|
||||
|
||||
return {events, exclusions};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -5,22 +5,24 @@ module.exports = Self => {
|
|||
accepts: [
|
||||
{
|
||||
arg: 'id',
|
||||
type: 'Number',
|
||||
type: 'number',
|
||||
description: 'The zone id',
|
||||
http: {source: 'path'},
|
||||
required: true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
arg: 'parentId',
|
||||
type: 'Number',
|
||||
type: 'number',
|
||||
description: 'Get the children of the specified father',
|
||||
}, {
|
||||
},
|
||||
{
|
||||
arg: 'search',
|
||||
type: 'String',
|
||||
type: 'string',
|
||||
description: 'Filter nodes whose name starts with',
|
||||
}
|
||||
],
|
||||
returns: {
|
||||
type: ['Object'],
|
||||
type: ['object'],
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
|
@ -29,13 +31,19 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.getLeaves = async(id, parentId = null, search) => {
|
||||
let [res] = await Self.rawSql(
|
||||
Self.getLeaves = async(id, parentId = null, search, options) => {
|
||||
let myOptions = {};
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
const [res] = await Self.rawSql(
|
||||
`CALL zone_getLeaves(?, ?, ?)`,
|
||||
[id, parentId, search]
|
||||
[id, parentId, search],
|
||||
myOptions
|
||||
);
|
||||
|
||||
let map = new Map();
|
||||
const map = new Map();
|
||||
for (let node of res) {
|
||||
if (!map.has(node.parentFk))
|
||||
map.set(node.parentFk, []);
|
||||
|
@ -50,7 +58,7 @@ module.exports = Self => {
|
|||
}
|
||||
}
|
||||
|
||||
let leaves = map.get(parentId);
|
||||
const leaves = map.get(parentId);
|
||||
setLeaves(leaves);
|
||||
|
||||
return leaves || [];
|
||||
|
|
|
@ -4,7 +4,7 @@ module.exports = Self => {
|
|||
accessType: 'READ',
|
||||
accepts: [],
|
||||
returns: {
|
||||
type: ['Object'],
|
||||
type: ['object'],
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
|
@ -13,8 +13,13 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.getUpcomingDeliveries = async() => {
|
||||
const [zones] = await Self.rawSql(`CALL vn.zone_upcomingDeliveries()`);
|
||||
Self.getUpcomingDeliveries = async options => {
|
||||
let myOptions = {};
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
const [zones] = await Self.rawSql('CALL vn.zone_upcomingDeliveries()', null, myOptions);
|
||||
|
||||
const details = [];
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
||||
const mergeFilters = require('vn-loopback/util/filter').mergeFilters;
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('includingExpired', {
|
||||
|
@ -19,7 +18,12 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.includingExpired = async(ctx, filter) => {
|
||||
Self.includingExpired = async(ctx, filter, options) => {
|
||||
let myOptions = {};
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
const userId = ctx.req.accessToken.userId;
|
||||
const conn = Self.dataSource.connector;
|
||||
const models = Self.app.models;
|
||||
|
@ -32,7 +36,7 @@ module.exports = Self => {
|
|||
&& where.agencyModeFk && where.warehouseFk;
|
||||
|
||||
if (filterByAvailability) {
|
||||
const roles = await models.Account.getRoles(userId);
|
||||
const roles = await models.Account.getRoles(userId, myOptions);
|
||||
const canSeeExpired = roles.filter(role =>
|
||||
role == 'productionBoss' || role == 'administrative'
|
||||
);
|
||||
|
@ -44,7 +48,10 @@ module.exports = Self => {
|
|||
where.addressFk,
|
||||
where.agencyModeFk,
|
||||
where.warehouseFk,
|
||||
showExpired]);
|
||||
showExpired
|
||||
],
|
||||
myOptions);
|
||||
|
||||
stmts.push(stmt);
|
||||
}
|
||||
|
||||
|
@ -54,7 +61,7 @@ module.exports = Self => {
|
|||
|
||||
stmt = new ParameterizedSQL(
|
||||
`SELECT id, name, agencyModeFk
|
||||
FROM vn.zone z`);
|
||||
FROM vn.zone z`, null, myOptions);
|
||||
|
||||
if (filterByAvailability)
|
||||
stmt.merge(`JOIN tmp.zoneGetLanded zgl ON zgl.zoneFk = z.id`);
|
||||
|
@ -67,7 +74,7 @@ module.exports = Self => {
|
|||
else stmts.push(stmt);
|
||||
|
||||
const sql = ParameterizedSQL.join(stmts, ';');
|
||||
const result = await conn.executeStmt(sql);
|
||||
const result = await conn.executeStmt(sql, myOptions);
|
||||
|
||||
return index ? result[index] : result;
|
||||
};
|
||||
|
|
|
@ -1,17 +1,20 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
|
||||
describe('agency clone()', () => {
|
||||
let newZone;
|
||||
|
||||
afterAll(async done => {
|
||||
await app.models.Zone.destroyById(newZone.id);
|
||||
done();
|
||||
});
|
||||
|
||||
it('should clone a zone', async() => {
|
||||
newZone = await app.models.Zone.clone(1);
|
||||
const tx = await app.models.Zone.beginTransaction({});
|
||||
|
||||
expect(newZone.name).toEqual('Zone pickup A');
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
const newZone = await app.models.Zone.clone(1, options);
|
||||
|
||||
expect(newZone.name).toEqual('Zone pickup A');
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -7,30 +7,21 @@ describe('zone deletezone()', () => {
|
|||
accessToken: {userId: userId},
|
||||
};
|
||||
const ctx = {req: activeCtx};
|
||||
let zoneId = 9;
|
||||
let originalZone;
|
||||
let originalZoneWarehouses;
|
||||
let originalTickets;
|
||||
const zoneId = 9;
|
||||
let ticketIDs;
|
||||
let originalZoneIncluded;
|
||||
let originalTicketStates;
|
||||
let originalRoutes;
|
||||
|
||||
beforeAll(async done => {
|
||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||
active: activeCtx
|
||||
});
|
||||
try {
|
||||
originalZone = await app.models.Zone.findById(zoneId);
|
||||
originalZoneWarehouses = await app.models.ZoneWarehouse.findById(zoneId);
|
||||
originalTickets = await app.models.Ticket.find({
|
||||
const originalTickets = await app.models.Ticket.find({
|
||||
where: {
|
||||
zoneFk: zoneId
|
||||
}
|
||||
});
|
||||
originalRoutes = await app.models.Route.find({where: {zoneFk: zoneId}});
|
||||
ticketIDs = originalTickets.map(ticket => ticket.id);
|
||||
originalZoneIncluded = await app.models.ZoneIncluded.find({where: {zoneFk: zoneId}});
|
||||
originalTicketStates = await app.models.TicketState.find({where: {
|
||||
ticketFk: {inq: ticketIDs},
|
||||
code: 'FIXING'}});
|
||||
|
@ -41,46 +32,31 @@ describe('zone deletezone()', () => {
|
|||
done();
|
||||
});
|
||||
|
||||
afterAll(async done => {
|
||||
try {
|
||||
await originalZone.save();
|
||||
await app.models.ZoneWarehouse.create(originalZoneWarehouses);
|
||||
|
||||
for (route of originalRoutes)
|
||||
await route.updateAttributes({zoneFk: zoneId});
|
||||
|
||||
for (ticket of originalTickets)
|
||||
await ticket.updateAttributes({zoneFk: zoneId});
|
||||
|
||||
for (zoneIncluded of originalZoneIncluded)
|
||||
await zoneIncluded.save();
|
||||
|
||||
const fixingStateId = 1;
|
||||
const trackings = await app.models.TicketTracking.find({where: {
|
||||
ticketFk: {inq: ticketIDs},
|
||||
stateFk: fixingStateId}});
|
||||
|
||||
for (let tracking of trackings)
|
||||
await app.models.TicketTracking.destroyById(tracking.id);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should delete a zone and update their tickets', async() => {
|
||||
await app.models.Zone.deleteZone(ctx, zoneId);
|
||||
const tx = await app.models.Zone.beginTransaction({});
|
||||
|
||||
const updatedZone = await app.models.Zone.findById(zoneId);
|
||||
const anUpdatedTicket = await app.models.Ticket.findById(ticketIDs[0]);
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
await app.models.Zone.deleteZone(ctx, zoneId, options);
|
||||
|
||||
const updatedTicketStates = await app.models.TicketState.find({where: {
|
||||
ticketFk: {inq: ticketIDs},
|
||||
code: 'FIXING'}});
|
||||
const updatedZone = await app.models.Zone.findById(zoneId, null, options);
|
||||
const anUpdatedTicket = await app.models.Ticket.findById(ticketIDs[0], null, options);
|
||||
|
||||
expect(updatedZone).toBeNull();
|
||||
expect(anUpdatedTicket.zoneFk).toBeNull();
|
||||
expect(updatedTicketStates.length).toBeGreaterThan(originalTicketStates.length);
|
||||
const updatedTicketStates = await app.models.TicketState.find({
|
||||
where: {
|
||||
ticketFk: {inq: ticketIDs},
|
||||
code: 'FIXING'
|
||||
}
|
||||
}, options);
|
||||
|
||||
expect(updatedZone).toBeNull();
|
||||
expect(anUpdatedTicket.zoneFk).toBeNull();
|
||||
expect(updatedTicketStates.length).toBeGreaterThan(originalTicketStates.length);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
|
||||
describe('zone getEvents()', () => {
|
||||
it('should return all events for the specified geo and agency mode', async() => {
|
||||
const tx = await app.models.Zone.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
let result = await app.models.Zone.getEvents(20, 1, options);
|
||||
|
||||
expect(result.events.length).toEqual(10);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
});
|
|
@ -0,0 +1,20 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
|
||||
describe('zone getLeaves()', () => {
|
||||
it('should return the country and the childs containing the search value', async() => {
|
||||
const tx = await app.models.Zone.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
let result = await app.models.Zone.getLeaves(1, null, '46000', options);
|
||||
|
||||
expect(result.length).toEqual(1);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
});
|
|
@ -2,15 +2,25 @@ const app = require('vn-loopback/server/server');
|
|||
|
||||
describe('zone getUpcomingDeliveries()', () => {
|
||||
it('should check returns data', async() => {
|
||||
let result = await app.models.Zone.getUpcomingDeliveries();
|
||||
const tx = await app.models.Zone.beginTransaction({});
|
||||
|
||||
const firstResultLines = result[0].lines;
|
||||
const secondResultLines = result[1].lines;
|
||||
const thirdResultLines = result[2].lines;
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
let result = await app.models.Zone.getUpcomingDeliveries(options);
|
||||
|
||||
expect(result.length).toEqual(8);
|
||||
expect(firstResultLines.length).toEqual(1);
|
||||
expect(secondResultLines.length).toEqual(1);
|
||||
expect(thirdResultLines.length).toEqual(1);
|
||||
const firstResultLines = result[0].lines;
|
||||
const secondResultLines = result[1].lines;
|
||||
const thirdResultLines = result[2].lines;
|
||||
|
||||
expect(result.length).toEqual(8);
|
||||
expect(firstResultLines.length).toEqual(1);
|
||||
expect(secondResultLines.length).toEqual(1);
|
||||
expect(thirdResultLines.length).toEqual(1);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -6,22 +6,45 @@ describe('zone includingExpired()', () => {
|
|||
const warehouseId = 1;
|
||||
|
||||
it('should return an array containing all zones', async() => {
|
||||
const tx = await app.models.Zone.beginTransaction({});
|
||||
const ctx = {req: {accessToken: {userId: 1}}};
|
||||
const where = {};
|
||||
const result = await app.models.Zone.includingExpired(ctx, {where});
|
||||
|
||||
expect(result.length).toBeGreaterThan(2);
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const result = await app.models.Zone.includingExpired(ctx, {where}, options);
|
||||
|
||||
expect(result.length).toBeGreaterThan(2);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
it('should return an array containing zones from the agencyMode "Inhouse pickup"', async() => {
|
||||
const ctx = {req: {accessToken: {userId: 1}}};
|
||||
const where = {agencyModeFk: inhousePickupId};
|
||||
const result = await app.models.Zone.includingExpired(ctx, {where});
|
||||
|
||||
const validAgency = result.every(zone => zone.agencyModeFk = inhousePickupId);
|
||||
const tx = await app.models.Zone.beginTransaction({});
|
||||
|
||||
expect(result.length).toEqual(3);
|
||||
expect(validAgency).toBeTruthy();
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const result = await app.models.Zone.includingExpired(ctx, {where}, options);
|
||||
|
||||
const validAgency = result.every(zone => zone.agencyModeFk = inhousePickupId);
|
||||
|
||||
expect(result.length).toEqual(3);
|
||||
expect(validAgency).toBeTruthy();
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
it('should return an array containing available zones', async() => {
|
||||
|
@ -32,9 +55,21 @@ describe('zone includingExpired()', () => {
|
|||
agencyModeFk: inhousePickupId,
|
||||
warehouseFk: warehouseId
|
||||
};
|
||||
const result = await app.models.Zone.includingExpired(ctx, {where});
|
||||
const firstZone = result[0];
|
||||
|
||||
expect(firstZone.name).toEqual('Zone pickup A');
|
||||
const tx = await app.models.Zone.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const result = await app.models.Zone.includingExpired(ctx, {where}, options);
|
||||
const firstZone = result[0];
|
||||
|
||||
expect(firstZone.name).toEqual('Zone pickup A');
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
|
||||
describe('zone toggleIsIncluded()', () => {
|
||||
it('should return the created location with isIncluded true', async() => {
|
||||
const tx = await app.models.Zone.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
let result = await app.models.Zone.toggleIsIncluded(1, 20, true, options);
|
||||
|
||||
expect(result.isIncluded).toBeTrue();
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
it('should return the created location with isIncluded false', async() => {
|
||||
const tx = await app.models.Zone.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
let result = await app.models.Zone.toggleIsIncluded(1, 20, false, options);
|
||||
|
||||
expect(result.isIncluded).toBeFalse();
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
it('should return the amount of deleted locations', async() => {
|
||||
const tx = await app.models.Zone.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
await app.models.Zone.toggleIsIncluded(1, 20, false, options);
|
||||
|
||||
let result = await app.models.Zone.toggleIsIncluded(1, 20, undefined, options);
|
||||
|
||||
expect(result).toEqual({count: 1});
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
});
|
|
@ -7,11 +7,13 @@ module.exports = Self => {
|
|||
description: 'The zone id',
|
||||
http: {source: 'path'},
|
||||
required: true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
arg: 'geoId',
|
||||
type: 'Number',
|
||||
required: true
|
||||
}, {
|
||||
},
|
||||
{
|
||||
arg: 'isIncluded',
|
||||
type: 'Boolean'
|
||||
}],
|
||||
|
@ -25,17 +27,21 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.toggleIsIncluded = async(id, geoId, isIncluded) => {
|
||||
Self.toggleIsIncluded = async(id, geoId, isIncluded, options) => {
|
||||
const models = Self.app.models;
|
||||
let myOptions = {};
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
if (isIncluded === undefined)
|
||||
return models.ZoneIncluded.destroyAll({zoneFk: id, geoFk: geoId});
|
||||
return models.ZoneIncluded.destroyAll({zoneFk: id, geoFk: geoId}, myOptions);
|
||||
else {
|
||||
return models.ZoneIncluded.upsert({
|
||||
zoneFk: id,
|
||||
geoFk: geoId,
|
||||
isIncluded: isIncluded
|
||||
});
|
||||
}, myOptions);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue