refs #6276 feat:newWarehouse

This commit is contained in:
Sergio De la torre 2024-03-20 13:26:27 +01:00
parent aa27eb1922
commit 99689917f5
6 changed files with 332 additions and 326 deletions

View File

@ -1,31 +1,32 @@
const UserError = require('vn-loopback/util/user-error'); const UserError = require('vn-loopback/util/user-error');
module.exports = Self => { module.exports = Self => {
Self.remoteMethodCtx('assign', { Self.remoteMethodCtx('assign', {
description: 'Assign a collection', description: 'Assign a collection',
accessType: 'WRITE', accessType: 'WRITE',
http: { http: {
path: `/assign`, path: `/assign`,
verb: 'POST' verb: 'POST'
}, },
returns: { returns: {
type: ['object'], type: ['object'],
root: true root: true
}, },
}); });
Self.assign = async(ctx, options) => { Self.assign = async(ctx, options) => {
const userId = ctx.req.accessToken.userId; const userId = ctx.req.accessToken.userId;
const myOptions = {userId}; const myOptions = {userId};
if (typeof options == 'object') if (typeof options == 'object')
Object.assign(myOptions, options); Object.assign(myOptions, options);
const [,, {collectionFk}] = await Self.rawSql('CALL vn.collection_assign(?, @vCollectionFk); SELECT @vCollectionFk collectionFk', const [, , [{collectionFk}]] =
[userId], myOptions); await Self.rawSql('CALL vn.collection_assign(?, @vCollectionFk); SELECT @vCollectionFk collectionFk',
[userId], myOptions);
if (!collectionFk) throw new UserError('There are not picking tickets');
await Self.rawSql('CALL vn.collection_printSticker(?, NULL)', [collectionFk], myOptions); if (!collectionFk) throw new UserError('There are not picking tickets');
await Self.rawSql('CALL vn.collection_printSticker(?, NULL)', [collectionFk], myOptions);
return collectionFk;
}; return collectionFk;
}; };
};

View File

@ -1,132 +1,132 @@
const {models} = require('vn-loopback/server/server'); const {models} = require('vn-loopback/server/server');
describe('machineWorker updateInTime()', () => { describe('machineWorker updateInTime()', () => {
const itBoss = 104; const itBoss = 104;
const davidCharles = 1106; const davidCharles = 1106;
beforeAll(async() => { beforeAll(async() => {
ctx = { ctx = {
req: { req: {
accessToken: {}, accessToken: {},
headers: {origin: 'http://localhost'}, headers: {origin: 'http://localhost'},
__: value => value __: value => value
} }
}; };
}); });
it('should throw an error if the plate does not exist', async() => { it('should throw an error if the plate does not exist', async() => {
const tx = await models.MachineWorker.beginTransaction({}); const tx = await models.MachineWorker.beginTransaction({});
const options = {transaction: tx}; const options = {transaction: tx};
const plate = 'RE-123'; const plate = 'RE-123';
ctx.req.accessToken.userId = 1106; ctx.req.accessToken.userId = 1106;
try { try {
await models.MachineWorker.updateInTime(ctx, plate, options); await models.MachineWorker.updateInTime(ctx, plate, options);
await tx.rollback(); await tx.rollback();
} catch (e) { } catch (e) {
const error = e; const error = e;
expect(error.message).toContain('the plate does not exist'); expect(error.message).toContain('the plate does not exist');
await tx.rollback(); await tx.rollback();
} }
}); });
it('should grab a machine where is not in use', async() => { it('should grab a machine where is not in use', async() => {
const tx = await models.MachineWorker.beginTransaction({}); const tx = await models.MachineWorker.beginTransaction({});
const options = {transaction: tx}; const options = {transaction: tx};
const plate = 'RE-003'; const plate = 'RE-003';
ctx.req.accessToken.userId = 1107; ctx.req.accessToken.userId = 1107;
try { try {
const totalBefore = await models.MachineWorker.find(null, options); const totalBefore = await models.MachineWorker.find(null, options);
await models.MachineWorker.updateInTime(ctx, plate, options); await models.MachineWorker.updateInTime(ctx, plate, options);
const totalAfter = await models.MachineWorker.find(null, options); const totalAfter = await models.MachineWorker.find(null, options);
expect(totalAfter.length).toEqual(totalBefore.length + 1); expect(totalAfter.length).toEqual(totalBefore.length + 1);
await tx.rollback(); await tx.rollback();
} catch (e) { } catch (e) {
await tx.rollback(); await tx.rollback();
} }
}); });
describe('less than 12h', () => { describe('less than 12h', () => {
const plate = 'RE-001'; const plate = 'RE-001';
it('should trow an error if it is not himself', async() => { it('should trow an error if it is not himself', async() => {
const tx = await models.MachineWorker.beginTransaction({}); const tx = await models.MachineWorker.beginTransaction({});
const options = {transaction: tx}; const options = {transaction: tx};
ctx.req.accessToken.userId = davidCharles; ctx.req.accessToken.userId = davidCharles;
try { try {
await models.MachineWorker.updateInTime(ctx, plate, options); await models.MachineWorker.updateInTime(ctx, plate, options);
await tx.rollback(); await tx.rollback();
} catch (e) { } catch (e) {
const error = e; const error = e;
expect(error.message).toContain('This machine is already in use'); expect(error.message).toContain('This machine is already in use');
await tx.rollback(); await tx.rollback();
} }
}); });
it('should throw an error if it is himself with a different machine', async() => { it('should throw an error if it is himself with a different machine', async() => {
const tx = await models.MachineWorker.beginTransaction({}); const tx = await models.MachineWorker.beginTransaction({});
const options = {transaction: tx}; const options = {transaction: tx};
ctx.req.accessToken.userId = itBoss; ctx.req.accessToken.userId = itBoss;
const plate = 'RE-003'; const plate = 'RE-003';
try { try {
await models.MachineWorker.updateInTime(ctx, plate, options); await models.MachineWorker.updateInTime(ctx, plate, options);
await tx.rollback(); await tx.rollback();
} catch (e) { } catch (e) {
const error = e; const error = e;
expect(error.message).toEqual('You are already using a machine'); expect(error.message).toEqual('You are already using a machine');
await tx.rollback(); await tx.rollback();
} }
}); });
it('should set the out time if it is himself', async() => { it('should set the out time if it is himself', async() => {
const tx = await models.MachineWorker.beginTransaction({}); const tx = await models.MachineWorker.beginTransaction({});
const options = {transaction: tx}; const options = {transaction: tx};
ctx.req.accessToken.userId = itBoss; ctx.req.accessToken.userId = itBoss;
try { try {
const isNotParked = await models.MachineWorker.findOne({ const isNotParked = await models.MachineWorker.findOne({
where: {workerFk: itBoss} where: {workerFk: itBoss}
}, options); }, options);
await models.MachineWorker.updateInTime(ctx, plate, options); await models.MachineWorker.updateInTime(ctx, plate, options);
const isParked = await models.MachineWorker.findOne({ const isParked = await models.MachineWorker.findOne({
where: {workerFk: itBoss} where: {workerFk: itBoss}
}, options); }, options);
expect(isNotParked.outTime).toBeNull(); expect(isNotParked.outTime).toBeNull();
expect(isParked.outTime).toBeDefined(); expect(isParked.outTime).toBeDefined();
await tx.rollback(); await tx.rollback();
} catch (e) { } catch (e) {
await tx.rollback(); await tx.rollback();
} }
}); });
}); });
describe('equal or more than 12h', () => { describe('equal or more than 12h', () => {
const plate = 'RE-002'; const plate = 'RE-002';
it('should set the out time and grab the machine', async() => { it('should set the out time and grab the machine', async() => {
const tx = await models.MachineWorker.beginTransaction({}); const tx = await models.MachineWorker.beginTransaction({});
const options = {transaction: tx}; const options = {transaction: tx};
ctx.req.accessToken.userId = davidCharles; ctx.req.accessToken.userId = davidCharles;
const filter = { const filter = {
where: {workerFk: davidCharles, machineFk: 2} where: {workerFk: davidCharles, machineFk: 2}
}; };
try { try {
const isNotParked = await models.MachineWorker.findOne(filter, options); const isNotParked = await models.MachineWorker.findOne(filter, options);
const totalBefore = await models.MachineWorker.find(null, options); const totalBefore = await models.MachineWorker.find(null, options);
await models.MachineWorker.updateInTime(ctx, plate, options); await models.MachineWorker.updateInTime(ctx, plate, options);
const isParked = await models.MachineWorker.findOne(filter, options); const isParked = await models.MachineWorker.findOne(filter, options);
const totalAfter = await models.MachineWorker.find(null, options); const totalAfter = await models.MachineWorker.find(null, options);
expect(isNotParked.outTime).toBeNull(); expect(isNotParked.outTime).toBeNull();
expect(isParked.outTime).toBeDefined(); expect(isParked.outTime).toBeDefined();
expect(totalAfter.length).toEqual(totalBefore.length + 1); expect(totalAfter.length).toEqual(totalBefore.length);
await tx.rollback(); await tx.rollback();
} catch (e) { } catch (e) {
await tx.rollback(); await tx.rollback();
} }
}); });
}); });
}); });

View File

@ -1,77 +1,77 @@
const UserError = require('vn-loopback/util/user-error'); const UserError = require('vn-loopback/util/user-error');
module.exports = Self => { module.exports = Self => {
Self.remoteMethodCtx('updateInTime', { Self.remoteMethodCtx('updateInTime', {
description: 'Updates the corresponding registry if the worker has been registered in the last few hours', description: 'Updates the corresponding registry if the worker has been registered in the last few hours',
accessType: 'WRITE', accessType: 'WRITE',
accepts: [ accepts: [
{ {
arg: 'plate', arg: 'plate',
type: 'string', type: 'string',
} }
], ],
http: { http: {
path: `/updateInTime`, path: `/updateInTime`,
verb: 'POST' verb: 'POST'
} }
}); });
Self.updateInTime = async(ctx, plate, options) => { Self.updateInTime = async(ctx, plate, options) => {
const models = Self.app.models; const models = Self.app.models;
const userId = ctx.req.accessToken.userId; const userId = ctx.req.accessToken.userId;
const $t = ctx.req.__; const $t = ctx.req.__;
let tx; let tx;
const myOptions = {}; const myOptions = {};
if (typeof options == 'object') if (typeof options == 'object')
Object.assign(myOptions, options); Object.assign(myOptions, options);
if (!myOptions.transaction) { if (!myOptions.transaction) {
tx = await Self.beginTransaction({}); tx = await Self.beginTransaction({});
myOptions.transaction = tx; myOptions.transaction = tx;
} }
try { try {
const machine = await models.Machine.findOne({ const machine = await models.Machine.findOne({
fields: ['id', 'plate'], fields: ['id', 'plate'],
where: {plate} where: {plate}
}, myOptions); }, myOptions);
if (!machine) if (!machine)
throw new Error($t('the plate does not exist', {plate})); throw new Error($t('the plate does not exist', {plate}));
const machineWorker = await Self.findOne({ const machineWorker = await Self.findOne({
where: { where: {
or: [{machineFk: machine.id}, {workerFk: userId}], or: [{machineFk: machine.id}, {workerFk: userId}],
outTime: null, outTime: null,
} }
}, myOptions); }, myOptions);
const {maxHours} = await models.MachineWorkerConfig.findOne({fields: ['maxHours']}, myOptions); const {maxHours} = await models.MachineWorkerConfig.findOne({fields: ['maxHours']}, myOptions);
const hoursDifference = (Date.vnNow() - machineWorker.inTime.getTime()) / (60 * 60 * 1000); const hoursDifference = (Date.vnNow() - machineWorker?.inTimed?.getTime() ?? 0) / (60 * 60 * 1000);
if (machineWorker) { if (machineWorker) {
const isHimself = userId == machineWorker.workerFk; const isHimself = userId == machineWorker.workerFk;
const isSameMachine = machine.id == machineWorker.machineFk; const isSameMachine = machine.id == machineWorker.machineFk;
if (hoursDifference < maxHours && !isHimself) if (hoursDifference < maxHours && !isHimself)
throw new UserError($t('This machine is already in use.')); throw new UserError($t('This machine is already in use.'));
if (hoursDifference < maxHours && isHimself && !isSameMachine) if (hoursDifference < maxHours && isHimself && !isSameMachine)
throw new UserError($t('You are already using a machine')); throw new UserError($t('You are already using a machine'));
await machineWorker.updateAttributes({ await machineWorker.updateAttributes({
outTime: Date.vnNew() outTime: Date.vnNew()
}, myOptions); }, myOptions);
} }
if (!machineWorker || hoursDifference >= maxHours) if (!machineWorker || hoursDifference >= maxHours)
await models.MachineWorker.create({machineFk: machine.id, workerFk: userId}, myOptions); await models.MachineWorker.create({machineFk: machine.id, workerFk: userId}, myOptions);
if (tx) await tx.commit(); if (tx) await tx.commit();
} catch (e) { } catch (e) {
if (tx) await tx.rollback(); if (tx) await tx.rollback();
throw e; throw e;
} }
}; };
}; };

View File

@ -1,45 +1,50 @@
module.exports = Self => { module.exports = Self => {
Self.remoteMethodCtx('getVersion', { Self.remoteMethodCtx('getVersion', {
description: 'gets app version data', description: 'gets app version data',
accessType: 'READ', accessType: 'READ',
accepts: [{ accepts: [{
arg: 'app', arg: 'app',
type: 'string', type: 'string',
required: true required: true
}], }],
returns: { returns: {
type: ['object'], type: ['object'],
root: true root: true
}, },
http: { http: {
path: `/getVersion`, path: `/getVersion`,
verb: 'GET' verb: 'GET'
} }
}); });
Self.getVersion = async(ctx, app) => { Self.getVersion = async(ctx, app) => {
const {models} = Self.app; const {models} = Self.app;
const userId = ctx.req.accessToken.userId; const userId = ctx.req.accessToken.userId;
const workerFk = await models.WorkerAppTester.findOne({ const workerFk = await models.WorkerAppTester.findOne({
where: { where: {
workerFk: userId workerFk: userId
} }
}); });
let fields = ['id', 'appName']; let fields = ['id', 'appName'];
if (workerFk) if (workerFk)
fields = fields.concat(['isVersionBetaCritical', 'versionBeta', 'urlBeta']); fields = fields.concat(['isVersionBetaCritical', 'versionBeta', 'urlBeta']);
else else
fields = fields.concat(['isVersionCritical', 'version', 'urlProduction']); fields = fields.concat(['isVersionCritical', 'version', 'urlProduction']);
const filter = { const filter = {
where: { where: {
appName: app appName: app
}, },
fields, fields,
}; };
return Self.findOne(filter); const result = await Self.findOne(filter);
}; return {
}; isVersionCritical: result?.isVersionBetaCritical ?? result?.isVersionCritical,
version: result?.versionBeta ?? result?.version,
url: result?.urlBeta ?? result?.urlProduction
};
};
};

View File

@ -1,29 +1,29 @@
const {models} = require('vn-loopback/server/server'); const {models} = require('vn-loopback/server/server');
describe('mobileAppVersionControl getVersion()', () => { describe('mobileAppVersionControl getVersion()', () => {
const appName = 'delivery'; const appName = 'delivery';
beforeAll(async() => { const appNameVersion = '9.2';
ctx = { const appNameVersionBeta = '9.7';
req: { beforeAll(async() => {
accessToken: {}, ctx = {
headers: {origin: 'http://localhost'}, req: {
} accessToken: {},
}; headers: {origin: 'http://localhost'},
}); }
};
it('should get the version app', async() => { });
ctx.req.accessToken.userId = 9;
const {version, versionBeta} = await models.MobileAppVersionControl.getVersion(ctx, appName); it('should get the version app', async() => {
ctx.req.accessToken.userId = 9;
expect(version).toEqual('9.2'); const {version} = await models.MobileAppVersionControl.getVersion(ctx, appName);
expect(versionBeta).toBeUndefined();
}); expect(version).toEqual(appNameVersion);
});
it('should get the beta version app', async() => {
ctx.req.accessToken.userId = 66; it('should get the beta version app', async() => {
const {version, versionBeta} = await models.MobileAppVersionControl.getVersion(ctx, appName); ctx.req.accessToken.userId = 66;
const {version} = await models.MobileAppVersionControl.getVersion(ctx, appName);
expect(versionBeta).toBeDefined();
expect(version).toBeUndefined(); expect(version).toEqual(appNameVersionBeta);
}); });
}); });

View File

@ -1,12 +1,12 @@
INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId)
VALUES VALUES
('Collection', 'assign', 'WRITE', 'ALLOW', 'ROLE', 'production'), ('Collection', 'assign', 'WRITE', 'ALLOW', 'ROLE', 'production'),
('ExpeditionPallet', 'getPallet', 'READ', 'ALLOW', 'ROLE', 'production'), ('MachineWorker','updateInTime','WRITE','ALLOW','ROLE','production'),
('MachineWorker','updateInTime','WRITE','ALLOW','ROLE','production'), ('MobileAppVersionControl','getVersion','READ','ALLOW','ROLE','production'),
('MobileAppVersionControl','getVersion','READ','ALLOW','ROLE','production'), ('SaleTracking','delete','WRITE','ALLOW','ROLE','production'),
('SaleTracking','delete','WRITE','ALLOW','ROLE','production'), ('SaleTracking','updateTracking','WRITE','ALLOW','ROLE','production'),
('SaleTracking','updateTracking','WRITE','ALLOW','ROLE','production'), ('SaleTracking','setPicked','WRITE','ALLOW','ROLE','production'),
('SaleTracking','setPicked','WRITE','ALLOW','ROLE','production'), ('ExpeditionPallet', '*', 'READ', 'ALLOW', 'ROLE', 'production'),
('ExpeditionPallet', '*', 'READ', 'ALLOW', 'ROLE', 'production'), ('Sale', 'getFromSectorCollection', 'READ', 'ALLOW', 'ROLE', 'production'),
('Sale', 'getFromSectorCollection', 'READ', 'ALLOW', 'ROLE', 'production'), ('ItemBarcode', 'delete', 'WRITE', 'ALLOW', 'ROLE', 'production'),
('ItemBarcode', 'delete', 'WRITE', 'ALLOW', 'ROLE', 'production'); ('Ticket', 'addSaleByCode', 'WRITE', 'ALLOW', 'ROLE', 'production');