This commit is contained in:
Carlos Jimenez Ruiz 2019-06-03 12:00:58 +02:00
commit d06d5cd9c8
27 changed files with 687 additions and 193 deletions

View File

@ -0,0 +1,15 @@
CREATE TABLE `vn`.`device` (
`id` INT NOT NULL,
`sn` VARCHAR(50) NULL,
`model` VARCHAR(50) NULL,
`userFk` INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (`id`),
INDEX `device_fk1_idx` (`userFk` ASC),
CONSTRAINT `device_fk1`
FOREIGN KEY (`userFk`)
REFERENCES `account`.`user` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION);
ALTER TABLE `vn`.`device`
CHANGE COLUMN `id` `id` INT(11) NOT NULL AUTO_INCREMENT ;

View File

@ -1468,4 +1468,6 @@ INSERT INTO `vn`.`ticketDms`(`ticketFk`, `dmsFk`)
INSERT INTO `vn`.`clientDms`(`clientFk`, `dmsFk`)
VALUES
(101, 2),
(101, 3);
(101, 3);
INSERT INTO `vn`.`device` (`sn`, `model`, `userFk`) VALUES ('aaa', 'android', '9');

View File

@ -4,11 +4,24 @@ module.exports = Self => {
Self.remoteMethod('new', {
description: 'Create a new order and returns the new ID',
accessType: 'WRITE',
accepts: [{
arg: 'params',
type: 'object',
http: {source: 'body'}
}],
accepts: [
{
arg: 'landed',
description: 'The landed for the order',
type: 'date',
required: true
}, {
arg: 'addressId',
description: 'The address for the order',
type: 'number',
required: true
}, {
arg: 'agencyModeId',
description: 'The agencyMode for the order',
type: 'number',
required: true
}
],
returns: {
type: 'number',
root: true
@ -19,9 +32,9 @@ module.exports = Self => {
}
});
Self.new = async params => {
Self.new = async(landed, addressId, agencyModeId) => {
let address = await Self.app.models.Address.findOne({
where: {id: params.addressFk},
where: {id: addressId},
fields: ['clientFk'],
include: [
{relation: 'client',
@ -44,9 +57,9 @@ module.exports = Self => {
query = `CALL vn.orderListCreate(?, ?, ?, ?);`;
[result] = await Self.rawSql(query, [
params.landed,
params.agencyModeFk,
params.addressFk,
landed,
agencyModeId,
addressId,
'SALIX'
]);

View File

@ -23,11 +23,11 @@ module.exports = Self => {
where: {id: ticketFk}
});
let orderID = await Self.app.models.Order.new({
addressFk: ticket.addressFk,
landed: ticket.landed,
agencyModeFk: ticket.agencyModeFk
});
let landed = ticket.landed;
let addressFk = ticket.addressFk;
let agencyModeFk = ticket.agencyModeFk;
let orderID = await Self.app.models.Order.new(landed, addressFk, agencyModeFk);
return orderID;
};

View File

@ -12,9 +12,11 @@ describe('order new()', () => {
it('should throw an error if the client is frozen', async() => {
let error;
let params = {addressFk: 121};
let landed = new Date();
let addressFk = 121;
let agencyModeFk = 1;
await app.models.Order.new(params)
await app.models.Order.new(landed, addressFk, agencyModeFk)
.catch(e => {
error = e;
});
@ -24,9 +26,11 @@ describe('order new()', () => {
it('should throw an error if the client isnt frozen and isnt active', async() => {
let error;
let params = {addressFk: 6};
let landed = new Date();
let addressFk = 6;
let agencyModeFk = 1;
await app.models.Order.new(params)
await app.models.Order.new(landed, addressFk, agencyModeFk)
.catch(e => {
error = e;
});
@ -35,13 +39,11 @@ describe('order new()', () => {
});
it('should create a new order for the user with id 105 when all conditions are met', async() => {
let params = {
landed: new Date(),
agencyModeFk: 1,
addressFk: 125
};
let landed = new Date();
let addressFk = 125;
let agencyModeFk = 1;
orderId = await app.models.Order.new(params);
orderId = await app.models.Order.new(landed, addressFk, agencyModeFk);
let highestOrderIdInFixtures = 3;

View File

@ -31,5 +31,6 @@
label="Agency"
show-field="agency"
value-field="id"
rule="Order.agencyModeFk"
field="$ctrl.order.agencyModeFk">
</vn-autocomplete>

View File

@ -96,8 +96,8 @@ class Controller {
createOrder() {
let params = {
landed: this.order.landed,
addressFk: this.order.addressFk,
agencyModeFk: this.order.agencyModeFk
addressId: this.order.addressFk,
agencyModeId: this.order.agencyModeFk
};
this.$http.post(`order/api/Orders/new`, params).then(res => {
this.vnApp.showSuccess(this.translate.instant('Data saved!'));

View File

@ -1,121 +1,73 @@
const app = require('vn-loopback/server/server');
// #1489 updatePrice backTest
xdescribe('sale updatePrice()', () => {
it('should set price to 0 if the params price is undefined', async() => {
let params = {
price: undefined,
id: 13,
ticketFk: 8
};
await app.models.Sale.updatePrice(params);
let saleUpdated = await app.models.Sale.findById(params.id);
describe('sale updatePrice()', () => {
let originalSale;
let originalSalesPersonMana;
let createdSaleComponent;
let saleId = 13;
expect(saleUpdated.price).toEqual(0);
afterAll(async done => {
originalSale.save();
createdSaleComponent.destroy();
originalSalesPersonMana.save();
done();
});
it('should set price as a decimal number', async() => {
let params = {
price: 5.5,
id: 13,
ticketFk: 8
};
await app.models.Sale.updatePrice(params);
let saleUpdated = await app.models.Sale.findById(params.id);
beforeAll(async done => {
originalSale = await app.models.Sale.findById(saleId);
originalSalesPersonMana = await app.models.WorkerMana.findById(18);
expect(saleUpdated.price).toEqual(5.5);
done();
});
it('should now set price as a decimal number in a string', async() => {
let params = {
price: '5.5',
id: 13,
ticketFk: 8
};
await app.models.Sale.updatePrice(params);
let saleUpdated = await app.models.Sale.findById(params.id);
it('should throw an error if the ticket is not editable', async() => {
let immutableSaleId = 1;
let price = 5;
expect(saleUpdated.price).toEqual(5.5);
await app.models.Sale.updatePrice(immutableSaleId, price)
.catch(response => {
expect(response).toEqual(new Error(`The sales of this ticket can't be modified`));
error = response;
});
expect(error).toBeDefined();
});
it('should return 0 if the price is an empty string', async() => {
let params = {
price: '',
id: 13,
ticketFk: 8
};
await app.models.Sale.updatePrice(params);
let saleUpdated = await app.models.Sale.findById(params.id);
let price = '';
await app.models.Sale.updatePrice(saleId, price);
let saleUpdated = await app.models.Sale.findById(saleId);
expect(saleUpdated.price).toEqual(0);
});
it('should now set price as a decimal number in a string', async() => {
let price = '8';
it('should este crea mana', async() => {
let params = {
price: 5.5,
id: 13,
ticketFk: 8
};
await app.models.Sale.updatePrice(params);
let saleUpdated = await app.models.Sale.findById(params.id);
await app.models.Sale.updatePrice(saleId, price);
let saleUpdated = await app.models.Sale.findById(saleId);
expect(saleUpdated.price).toEqual(5.5);
expect(saleUpdated.price).toEqual(8);
});
it('should este no crea el mana', async() => {
let params = {
price: 5.5,
id: 13,
ticketFk: 8
};
let todosLosComponentes = await app.models.SaleComponent.find({where: {saleFk: 13}});
it('should set price as a decimal number and check the sale has the mana component', async() => {
let price = 5.5;
let manaComponentId = 37;
expect(todosLosComponentes[0].value).toEqual('');
expect(todosLosComponentes[1].value).toEqual('');
expect(todosLosComponentes[2].value).toEqual('');
expect(todosLosComponentes[3].value).toEqual('');
expect(todosLosComponentes[4].value).toEqual('');
await app.models.Sale.updatePrice(params);
todosLosComponentes = await app.models.SaleComponent.find({where: {saleFk: 13}});
let saleUpdated = await app.models.Sale.findById(params.id);
await app.models.Sale.updatePrice(saleId, price);
let saleUpdated = await app.models.Sale.findById(saleId);
createdSaleComponent = await app.models.SaleComponent.findOne({where: {saleFk: saleId, componentFk: manaComponentId}});
expect(saleUpdated.price).toEqual(5.5);
expect(todosLosComponentes[0].value).toEqual('');
expect(todosLosComponentes[1].value).toEqual('');
expect(todosLosComponentes[2].value).toEqual('');
expect(todosLosComponentes[3].value).toEqual('');
expect(todosLosComponentes[4].value).toEqual('');
expect(createdSaleComponent.value).toEqual(4.200);
});
// 2 let componentToUse;
// if (usesMana)
// componentToUse = 37;
// 3else
// componentToUse = 34;
// 4 if (saleComponent)
// saleComponent.updateAttributes({value: saleComponent.value + value});
// 5 else {
// await Self.app.models.SaleComponent.create({
// saleFk: params.id,
// componentFk: componentToUse,
// value: value
// });
// }
it('should check that the mana of salesPerson changed', async() => {
let updatedSalesPersonMana = await app.models.WorkerMana.findById(18);
// it(`should throw an error if the price is undefined`, async() => {
// let error;
// let params = {ticketFk: 1, price: undefined};
// await app.models.Sale.updatePrice(params)
// .catch(response => {
// expect(response).toEqual(new Error('The value should be a number'));
// error = response;
// });
// expect(error).toBeDefined();
// });
expect(updatedSalesPersonMana.amount).not.toEqual(originalSalesPersonMana.amount);
});
});

View File

@ -2,84 +2,94 @@ let UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
Self.remoteMethod('updatePrice', {
description: 'Changes the discount of a sale',
description: 'Changes the price of a sale',
accessType: 'WRITE',
accepts: [{
arg: 'params',
type: 'object',
required: true,
description: 'sale ID, newPrice, ticketFk',
http: {source: 'body'}
}],
accepts: [
{
arg: 'id',
description: 'The sale id',
type: 'number',
required: true,
http: {source: 'path'}
}, {
arg: 'newPrice',
description: 'The new price',
type: 'number',
required: true
}
],
returns: {
type: 'string',
root: true
},
http: {
path: `/updatePrice`,
path: `/:id/updatePrice`,
verb: 'post'
}
});
Self.updatePrice = async params => {
if (!params.price) params.price = 0;
Self.updatePrice = async(id, newPrice) => {
let $ = Self.app.models;
let transaction = await Self.beginTransaction({});
let options = {transaction};
let model = Self.app.models;
let manaDiscount;
let buyerDiscount = await model.ComponentRate.findOne({where: {code: 'buyerDiscount'}});
let ticket = await getTicket(params);
let usesMana = await model.WorkerMana.findOne({where: {workerFk: ticket[0].client().salesPersonFk}, fields: 'amount'});
let currentLine = await Self.app.models.Sale.findOne({where: {id: params.id}});
let componentId = buyerDiscount.id;
if (usesMana) {
manaDiscount = await model.ComponentRate.findOne({where: {code: 'mana'}});
componentId = manaDiscount.id;
}
let value = (params.price - currentLine.price);
let saleComponent = await Self.app.models.SaleComponent.findOne({
where: {
componentFk: componentId,
saleFk: params.id
}
});
if (saleComponent) {
saleComponent.updateAttributes({value: saleComponent.value + value}).catch(() => {
throw new UserError(`Enter a valid number`);
});
} else {
await Self.app.models.SaleComponent.create({
saleFk: params.id,
componentFk: componentId,
value: value
});
}
await currentLine.updateAttributes({price: params.price});
query = `call vn.manaSpellersRequery(?)`;
await Self.rawSql(query, [ticket[0].client().salesPersonFk]);
};
async function getTicket(params) {
let model = Self.app.models;
let thisTicketIsEditable = await model.Ticket.isEditable(params.ticketFk);
if (!thisTicketIsEditable)
throw new UserError(`The sales of this ticket can't be modified`);
return await model.Ticket.find({
where: {
id: params.ticketFk
},
include: [{
relation: 'client',
scope: {
fields: ['salesPersonFk']
try {
let filter = {
fields: ['id', 'ticketFk', 'price'],
include: {
relation: 'ticket',
scope: {
include: {
relation: 'client',
scope: {
fields: ['salesPersonFk']
}
},
fields: ['id', 'clientFk']
}
}
}],
fields: ['id', 'clientFk']
});
}
};
let sale = await $.Sale.findById(id, filter, options);
let isEditable = await $.Ticket.isEditable(sale.ticketFk);
if (!isEditable)
throw new UserError(`The sales of this ticket can't be modified`);
let salesPerson = sale.ticket().client().salesPersonFk;
let usesMana = await $.WorkerMana.findOne({where: {workerFk: salesPerson}, fields: 'amount'}, options);
let componentCode = usesMana ? 'mana' : 'buyerDiscount';
let discount = await $.ComponentRate.findOne({where: {code: componentCode}}, options);
let componentId = discount.id;
let componentValue = newPrice - sale.price;
let where = {
componentFk: componentId,
saleFk: id
};
let saleComponent = await $.SaleComponent.findOne({where}, options);
if (saleComponent) {
await $.SaleComponent.updateAll(where, {
value: saleComponent.value + componentValue
}, options);
} else {
await $.SaleComponent.create({
saleFk: id,
componentFk: componentId,
value: componentValue
}, options);
}
await sale.updateAttributes({price: newPrice}, options);
query = `call vn.manaSpellersRequery(?)`;
await Self.rawSql(query, [salesPerson], options);
await transaction.commit();
} catch (error) {
await transaction.rollback();
throw error;
}
};
};

View File

@ -4,7 +4,7 @@ describe('ticket getSalesPersonMana()', () => {
it('should get the mana of a salesperson of a given ticket', async() => {
let mana = await app.models.Ticket.getSalesPersonMana(1);
expect(mana).toEqual(221);
expect(mana).toEqual(222);
});
it('should return 0 if the given ticket does not exists', async() => {

View File

@ -11,7 +11,12 @@
"type": "Number"
},
"saleFk": {
"id": true
"type": "Number",
"id": 2
},
"componentFk": {
"type": "Number",
"id": 1
}
},
"relations": {

View File

@ -260,7 +260,7 @@ class Controller {
updatePrice() {
if (this.editedPrice != this.sale.price) {
this.$http.post(`/api/Sales/updatePrice`, {id: this.edit.id, price: this.editedPrice, ticketFk: this.ticket.id}).then(() => {
this.$http.post(`/api/Sales/${this.edit.id}/updatePrice`, {newPrice: this.editedPrice}).then(() => {
this.sale.price = this.edit.price;
this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
this.$scope.model.refresh();

View File

@ -0,0 +1,61 @@
/*
Author : Enrique Blasco BLanquer
Date: 27 de mayo de 2019
*/
module.exports = Self => {
Self.remoteMethodCtx('checkUuid', {
description: 'Check UUID from user',
accessType: 'WRITE',
accepts: [{
arg: 'data',
type: 'object',
required: true,
description: 'uuid,model',
http: {source: 'body'}
}],
returns: [{
type: 'Object',
root: true
}],
http: {
path: `/checkUuid`,
verb: 'POST'
}
});
Self.checkUuid = async(ctx, data) => {
const myUserId = ctx.req.accessToken.userId;
// 1 Check is a registered user with a uuid
let deviceUser = await Self.findOne({where: {userFk: myUserId, sn: data.uuid}});
if (deviceUser != null)
return {'state': true, 'mng': ''};
else {
// 2 If it does not exist it can be for two reasons:
// 2.1 It is the first time that the application enters so we have to register a new user associated with the user
// 2.2 Has the user associated with a different uuid, so we deny access.
let device = await Self.findOne({where: {userFk: myUserId}});
if (device != null) {
// The device is already registered by another user, access is denied
return {'state': false, 'mng': 'Ya estas regisgtrado en otro dispositivo, contacta con los dioses de informática.'};
} else {
// Check that the device is free
let aDevice = await Self.findOne({where: {sn: data.uuid}});
if (aDevice != null)
return {'state': false, 'mng': 'El dispositivo esta siendo usado por otro usuario'};
else {
// It's the first time you access the application, insert
/* await Self.rawSql('INSERT INTO vn2008.device (sn, model) VALUES (?,?);', [data.uuid, data.model]);*/
await Self.create({
sn: data.uuid,
model: data.model,
userFk: myUserId
});
return {'state': true, 'mng': 'Nuevo dispositivo registrado'};
}
}
}
};
};

View File

@ -0,0 +1,11 @@
const app = require('vn-loopback/server/server');
describe('device checkUuid()', () => {
it('should return an state equal to false', async() => {
let ctx = {req: {accessToken: {userId: 9}}};
let data = {'uuid': '123', 'model': 'ihpne kike molon'};
let result = await app.models.Device.checkUuid(ctx, data);
expect(result.name).toBeFalsy();
});
});

View File

@ -4,7 +4,7 @@ describe('workerMana getCurrentWorkerMana()', () => {
it('should get the mana of the logged worker', async() => {
let mana = await app.models.WorkerMana.getCurrentWorkerMana({req: {accessToken: {userId: 18}}});
expect(mana).toEqual(221);
expect(mana).toEqual(222);
});
it('should return 0 if the user doesnt uses mana', async() => {

View File

@ -0,0 +1,48 @@
/*
Author : Enrique Blasco BLanquer
Date: 27 de mayo de 2019
*/
module.exports = Self => {
Self.remoteMethodCtx('addAutoTime', {
description: 'Adds a new hour registry by app in manual 0',
accessType: 'WRITE',
accepts: [{
arg: 'data',
type: 'object',
required: true,
description: 'timed',
http: {source: 'body'}
}],
returns: [{
type: 'Object',
root: true
}],
http: {
path: `/addAutoTime`,
verb: 'POST'
}
});
Self.addAutoTime = async(ctx, data) => {
const myUserId = ctx.req.accessToken.userId;
// get all worked time control, needed to calculate order
let hours = await Self.rawSql(`SELECT * FROM vn.workerTimeControl
WHERE userFk = ?
AND DATE(timed) = CURDATE()
ORDER BY timed DESC LIMIT 1`, [myUserId]);
// 1 get next order
let order = 0;
if (hours.length > 0)
order = hours[hours.length - 1].order;
// 2 create element in db
return Self.create({
userFk: myUserId,
timed: data.timed,
order: order + 1,
manual: 0
});
};
};

View File

@ -0,0 +1,121 @@
/*
Author : Enrique Blasco BLanquer
Date: 28 de mayo de 2019
*/
module.exports = Self => {
Self.remoteMethodCtx('getHoursWorked', {
description: 'Get worked hours in current week, month and year',
accessType: 'WRITE',
returns: [{
type: 'Object',
root: true
}],
http: {
path: `/getHoursWorked`,
verb: 'GET'
}
});
Self.getHoursWorked = async(ctx, data) => {
let totalHours = 0; // total hours worked in one year
let totalMinutes = 0; // total minutes worked in one year
let totalHoursMonth = 0; // total hours worked in one month
let totalMinutesMonth = 0; // total minutes worked in one month
let totalHoursWeek = 0; // total hours worked in one week
let totalMinutesWeek = 0; // total minutes worked in one week
const myUserId = ctx.req.accessToken.userId; // user id
let today = new Date(); // needed to calculate total hours worked to current date
let fromDate = today.getFullYear() + '-01-01'; // from date, current year
let toDate = today.getFullYear() + '-12-31'; // to date, current year
// 1 hours worked in a year
let hoursYear = await Self.rawSql(`SELECT wtc.userFk, DATE(wtc.timed) dated,
UNIX_TIMESTAMP(MIN(timed))timedStart,
SEC_TO_TIME(SUM(if( mod(wtc.order,2)=1,
UNIX_TIMESTAMP(timed) *-1,
UNIX_TIMESTAMP(timed)))) timeWorkDay
FROM vn.workerTimeControl wtc
WHERE wtc.timed BETWEEN ? AND ? AND userFk = ?
GROUP BY wtc.userFk,dated ORDER BY dated DESC`, [fromDate, toDate, myUserId]);
// 2 Get days of week
let week = [];
// Starting Monday not Sunday
let current = new Date();
current.setDate((current.getDate() - current.getDay() + 1));
for (let i = 0; i < 7; i++) {
week.push(
new Date(current)
);
current.setDate(current.getDate() + 1);
}
// 3 I have all timed control for one year... NOW I CALCULATE TOTAL HOURS IN YEAR, MONTH, WEEK, Let's GO!
for (hour of hoursYear) {
if (parseInt(hour.timeWorkDay.split(':')[0]) > 0) {
// YEAR
totalHours += parseInt(hour.timeWorkDay.split(':')[0]);
totalMinutes += parseInt(hour.timeWorkDay.split(':')[1]);
// If it exceeds 5 hours we add 20 minutes of breakfast.
if (parseInt(hour.timeWorkDay.split(':')[0]) >= 5)
totalMinutes += 20;
// MONTH
if ((new Date(hour.dated)).getMonth() == today.getMonth()) {
totalHoursMonth += parseInt(hour.timeWorkDay.split(':')[0]);
totalMinutesMonth += parseInt(hour.timeWorkDay.split(':')[1]);
// If it exceeds 5 hours we add 20 minutes of breakfast.
if (parseInt(hour.timeWorkDay.split(':')[0]) >= 5)
totalMinutesMonth += 20;
}
// WEEK
for (day of week) {
let dayOfWeek = new Date(day);
let dayOfCurrentWeek = new Date(hour.dated);
if (dayOfWeek.getMonth() == dayOfCurrentWeek.getMonth() && dayOfWeek.getDate() == dayOfCurrentWeek.getDate()) {
totalHoursWeek += parseInt(hour.timeWorkDay.split(':')[0]);
totalMinutesWeek += parseInt(hour.timeWorkDay.split(':')[1]);
// If it exceeds 5 hours we add 20 minutes of breakfast.
if (parseInt(hour.timeWorkDay.split(':')[0]) >= 5)
totalMinutesWeek += 20;
break;
}
}
}
}
// TOTAL WORKED HOURS IN THE YEAR
totalHours += totalMinutes / 60;
totalHours = decimalToHour(totalHours);
// TOTAL WORKED HOURS IN THE MONTH
totalHoursMonth += totalMinutesMonth / 60;
totalHoursMonth = decimalToHour(totalHoursMonth);
// TOTAL WORKED HOURS IN THE WEEK
totalHoursWeek += totalMinutesWeek / 60;
totalHoursWeek = decimalToHour(totalHoursWeek);
return {
'totalWorekdYear': totalHours,
'totalWorekdMonth': totalHoursMonth,
'totalWorkedWeek': totalHoursWeek
};
};
};
/*
function to calculate hours and minutes from decimal value
*/
function decimalToHour(value) {
let decimalTime = parseFloat(value);
decimalTime = decimalTime * 60 * 60;
let hoursDay = Math.floor((decimalTime / (60 * 60)));
decimalTime = decimalTime - (hoursDay * 60 * 60);
let minutesDay = Math.floor((decimalTime / 60));
return hoursDay + ':' + minutesDay;
}

View File

@ -0,0 +1,78 @@
/*
Author : Enrique Blasco BLanquer
Date: 29 de mayo de 2019
*/
module.exports = Self => {
Self.remoteMethodCtx('getWorkedWeek', {
description: 'get worked week info',
accessType: 'WRITE',
returns: [{
type: 'Object',
root: true
}],
http: {
path: `/getWorkedWeek`,
verb: 'GET'
}
});
Self.getWorkedWeek = async(ctx, data) => {
const myUserId = ctx.req.accessToken.userId; // user id
let lastDate = new Date('1986-09-24'); // reference date
let diff = 0; // difference of value between two dates
let total = 0; // total hours
// 1 Get days of week
let week = [];
// 2 Starting Monday not Sunday
let current = new Date();
current.setDate((current.getDate() - current.getDay() + 1));
for (let i = 0; i < 7; i++) {
week.push(
new Date(current)
);
current.setDate(current.getDate() + 1);
}
let fromDate = week[0].getFullYear() + '-' + (week[0].getMonth() + 1) + '-' + week[0].getDate();
let toDate = week[week.length - 1].getFullYear() + '-' + (week[week.length - 1].getMonth() + 1) + '-' + week[week.length - 1].getDate();
// 3 hours worked in a current week
let hoursWeek = await Self.rawSql(`SELECT wtc.timed ,wtc.order
FROM vn.workerTimeControl wtc
WHERE userFk = ?
AND DATE(timed) BETWEEN ? AND ? ORDER BY timed DESC;`, [myUserId, fromDate, toDate]);
// 4 treat data
let isFirst = true;
for (let i = hoursWeek.length - 1; i >= 0; i--) {
let d = new Date(hoursWeek[i].timed);
if (isFirst) {
lastDate = d;
isFirst = false;
} else {
if (lastDate.getDate() === d.getDate()) {
diff += Math.abs(d.getTime() - lastDate.getTime());
lastDate = d;
} else {
total += diff;
diff = 0;
lastDate = d;
}
}
}
total += diff;
// 5 calculate hours and minutes
let decimalTime = total / 1000 / 3600;
decimalTime = decimalTime * 60 * 60;
let hours = Math.floor((decimalTime / (60 * 60)));
decimalTime = decimalTime - (hours * 60 * 60);
let minutes = Math.floor((decimalTime / 60));
return {'timeds': hoursWeek, 'totalWorked': hours + ':' + minutes};
};
};

View File

@ -0,0 +1,11 @@
const app = require('vn-loopback/server/server');
describe('workerTimeControl addAutoTime()', () => {
it('should return an undefined value', async() => {
let ctx = {req: {accessToken: {userId: 9}}};
let data = {'timed': new Date()};
let result = await app.models.WorkerTimeControl.addAutoTime(ctx, data);
expect(result).toBeUndefined();
});
});

View File

@ -0,0 +1,10 @@
const app = require('vn-loopback/server/server');
describe('workerTimeControl getHoursWorked()', () => {
it('should return an totalWorkedYear to be defined', async() => {
let ctx = {req: {accessToken: {userId: 9}}};
let result = await app.models.WorkerTimeControl.getHoursWorked(ctx, null);
expect(result.totalWorekdYear).toBeDefined();
});
});

View File

@ -0,0 +1,10 @@
const app = require('vn-loopback/server/server');
describe('workerTimeControl getWorkedWeek()', () => {
it('should return an timeds to be defined', async() => {
let ctx = {req: {accessToken: {userId: 9}}};
let result = await app.models.WorkerTimeControl.getWorkedWeek(ctx, null);
expect(result.timeds).toBeDefined();
});
});

View File

@ -0,0 +1,98 @@
/*
Author : Enrique Blasco BLanquer
Date: 28 de mayo de 2019
*/
module.exports = Self => {
Self.remoteMethodCtx('getWorkerInfo', {
description: 'Get worker info (name, isWorking, total worked hours ...)',
accessType: 'WRITE',
returns: [{
type: 'Object',
root: true
}],
http: {
path: `/getWorkerInfo`,
verb: 'GET'
}
});
Self.getWorkerInfo = async(ctx, data) => {
let prevHour = new Date(); // default value to start work
let diff = 0; // difference of value between two dates
let isOdd = true; // determine if timed is odd or not in db
const myUserId = ctx.req.accessToken.userId; // get user id
// 1 get name and photo for the user
let [user] = await Self.rawSql(`SELECT u.name, t.Foto FROM vn.user u INNER JOIN vn2008.Trabajadores t ON u.id = t.user_id WHERE id = ?;`, [myUserId]);
// 2 get all jornaly work time registered
let workedHours = await Self.rawSql(`SELECT * FROM vn.workerTimeControl WHERE userFk = ? AND DATE(timed) = CURDATE() ORDER BY timed ASC;`, [myUserId]);
let today = new Date();
// 3 get the number of hours to work in one day
let date = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate();
let [hoursForDay] = await Self.rawSql(`SELECT cl.hours_week AS hoursWeek,
GROUP_CONCAT(DISTINCT LEFT(j.start,2) ORDER BY j.start ASC SEPARATOR '-') start ,
GROUP_CONCAT(DISTINCT LEFT(j.end,2) ORDER BY j.end ASC SEPARATOR '-') end,
CAST(IFNULL((SUM(TIME_TO_SEC(j.end))-SUM(TIME_TO_SEC(j.start)))/3600,if(cl.hours_week=40
AND DAYOFWEEK(t.dated) IN(2,3,4,5,6),8,0)) AS DECIMAL(10,2)) workingHours
FROM vn.time t
LEFT JOIN postgresql.business b ON t.dated BETWEEN b.date_start AND ifnull(b.date_end,? )
LEFT JOIN postgresql.profile AS pr ON b.client_id = pr.profile_id
LEFT JOIN postgresql.person AS p ON pr.person_id = p.person_id
LEFT JOIN vn.worker AS w ON p.id_trabajador = w.id
LEFT JOIN postgresql.business_labour AS bl ON b.business_id = bl.business_id
LEFT JOIN postgresql.calendar_labour_type AS cl ON bl.calendar_labour_type_id = cl.calendar_labour_type_id
LEFT JOIN postgresql.journey AS j ON j.business_id = b.business_id and j.day_id=WEEKDAY(t.dated)+1
WHERE t.dated BETWEEN ? AND ? AND userFk = ?
GROUP BY w.userFk,dated`, [date, date, date, myUserId]);
// 4 Add all the hours and see the total worked
for (hour of workedHours) {
if (!isOdd)
diff += Math.abs((new Date(hour.timed)).getTime() - prevHour.getTime());
else
prevHour = new Date(hour.timed);
isOdd = !isOdd;
}
// 5 calculate hours and minutes from a number value
let decimalTime = diff / 1000 / 3600;
decimalTime = decimalTime * 60 * 60;
let hours = Math.floor((decimalTime / (60 * 60)));
decimalTime = decimalTime - (hours * 60 * 60);
let minutes = Math.floor((decimalTime / 60));
// 6 default total hours
let totalHours = '7:40';
let hoursWeek = 40;
// 7 Get the hours you have to work today and the hours to work in a week
if (hoursForDay != null) {
// If it exceeds 5 hours we take 20 minutes of breakfast.
if (hoursForDay.workingHours > 5)
hoursForDay.workingHours -= 20 * 0.016666;
let decimalTime = parseFloat(hoursForDay.workingHours);
decimalTime = decimalTime * 60 * 60;
let hoursDay = Math.floor((decimalTime / (60 * 60)));
decimalTime = decimalTime - (hoursDay * 60 * 60);
let minutesDay = Math.floor((decimalTime / 60));
totalHours = hoursDay + ':' + minutesDay;
}
// 8 return value
if (hoursForDay != null)
hoursWeek = hoursForDay.hoursWeek;
return {
'name': user.name,
'hours': hours,
'minutes': minutes,
'today': today,
'isWorking': !isOdd,
'lastDate': prevHour,
'totalHours': totalHours,
'hoursWeek': hoursWeek
};
};
};

View File

@ -46,5 +46,8 @@
},
"WorkerTimeControl": {
"dataSource": "vn"
},
"Device": {
"dataSource": "vn"
}
}

View File

@ -0,0 +1,11 @@
const UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
require('../methods/device/checkUuid')(Self);
Self.rewriteDbError(function(err) {
if (err.code === 'ER_DUP_ENTRY')
return new UserError(``);
return err;
});
};

View File

@ -0,0 +1,28 @@
{
"name": "Device",
"base": "VnModel",
"options": {
"mysql": {
"table": "device"
}
},
"properties": {
"id": {
"id": true,
"type": "Number"
},
"sn": {
"type": "String"
},
"model": {
"type": "String"
}
},
"relations": {
"user": {
"type": "belongsTo",
"model": "Account",
"foreignKey": "userFk"
}
}
}

View File

@ -3,6 +3,9 @@ const UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
require('../methods/worker-time-control/filter')(Self);
require('../methods/worker-time-control/addTime')(Self);
require('../methods/worker-time-control/addAutoTime')(Self);
require('../methods/worker-time-control/getHoursWorked')(Self);
require('../methods/worker-time-control/getWorkedWeek')(Self);
Self.rewriteDbError(function(err) {
if (err.code === 'ER_DUP_ENTRY')

View File

@ -2,4 +2,5 @@ module.exports = Self => {
require('../methods/worker/filter')(Self);
require('../methods/worker/mySubordinates')(Self);
require('../methods/worker/isSubordinate')(Self);
require('../methods/worker/getWorkerInfo')(Self);
};