3598-feat(worker): absences can return all absences of worker #886

Merged
carlosjr merged 6 commits from 3598-worker_calendar_absences into dev 2022-03-02 09:46:40 +00:00
11 changed files with 72 additions and 58 deletions

View File

@ -1851,6 +1851,15 @@ INSERT INTO `postgresql`.`business_labour`(`business_id`, `notes`, `department_i
SELECT b.business_id, NULL, 23, 1, 0, 1, 1, 1, 1 SELECT b.business_id, NULL, 23, 1, 0, 1, 1, 1, 1
FROM `postgresql`.`business` `b`; FROM `postgresql`.`business` `b`;
INSERT INTO `postgresql`.`business` (`client_id`, `provider_id`, `date_start`, `date_end`, `workerBusiness`, `reasonEndFk`)
SELECT p.profile_id, 1000, CONCAT(YEAR(DATE_ADD(CURDATE(), INTERVAL -2 YEAR)), '-12-25'), CONCAT(YEAR(DATE_ADD(CURDATE(), INTERVAL -1 YEAR)), '-12-24'), CONCAT('E-46-',RPAD(CONCAT(p.profile_id,9),8,p.profile_id)), NULL
FROM `postgresql`.`profile` `p`
WHERE `p`.`profile_id` = 1109;
INSERT INTO `postgresql`.`business_labour` (`business_id`, `notes`, `department_id`, `professional_category_id`, `incentivo`, `calendar_labour_type_id`, `porhoras`, `labour_agreement_id`, `workcenter_id`)
VALUES
(1111, NULL, 23, 1, 0.0, 1, 1, 1, 1);
UPDATE `postgresql`.`business_labour` bl UPDATE `postgresql`.`business_labour` bl
JOIN `postgresql`.`business` b ON b.business_id = bl.business_id JOIN `postgresql`.`business` b ON b.business_id = bl.business_id
JOIN `postgresql`.`profile` pr ON pr.profile_id = b.client_id JOIN `postgresql`.`profile` pr ON pr.profile_id = b.client_id

View File

@ -305,12 +305,12 @@ export default {
anyCreditInsuranceLine: 'vn-client-credit-insurance-insurance-index vn-tbody > vn-tr', anyCreditInsuranceLine: 'vn-client-credit-insurance-insurance-index vn-tbody > vn-tr',
}, },
clientDefaulter: { clientDefaulter: {
anyClient: 'vn-client-defaulter-index tbody > tr', anyClient: 'vn-client-defaulter tbody > tr',
firstClientName: 'vn-client-defaulter-index tbody > tr:nth-child(1) > td:nth-child(2) > span', firstClientName: 'vn-client-defaulter tbody > tr:nth-child(1) > td:nth-child(2) > span',
firstSalesPersonName: 'vn-client-defaulter-index tbody > tr:nth-child(1) > td:nth-child(3) > span', firstSalesPersonName: 'vn-client-defaulter tbody > tr:nth-child(1) > td:nth-child(3) > span',
firstObservation: 'vn-client-defaulter-index tbody > tr:nth-child(1) > td:nth-child(6) > vn-textarea[ng-model="defaulter.observation"]', firstObservation: 'vn-client-defaulter tbody > tr:nth-child(1) > td:nth-child(6) > vn-textarea[ng-model="defaulter.observation"]',
allDefaulterCheckbox: 'vn-client-defaulter-index thead vn-multi-check', allDefaulterCheckbox: 'vn-client-defaulter thead vn-multi-check',
addObservationButton: 'vn-client-defaulter-index vn-button[icon="icon-notes"]', addObservationButton: 'vn-client-defaulter vn-button[icon="icon-notes"]',
observation: '.vn-dialog.shown vn-textarea[ng-model="$ctrl.defaulter.observation"]', observation: '.vn-dialog.shown vn-textarea[ng-model="$ctrl.defaulter.observation"]',
saveButton: 'button[response="accept"]' saveButton: 'button[response="accept"]'
}, },

View File

@ -9,7 +9,7 @@ describe('Client defaulter path', () => {
browser = await getBrowser(); browser = await getBrowser();
page = browser.page; page = browser.page;
await page.loginAndModule('insurance', 'client'); await page.loginAndModule('insurance', 'client');
await page.accessToSection('client.defaulter.index'); await page.accessToSection('client.defaulter');
}); });
afterAll(async() => { afterAll(async() => {
@ -52,7 +52,7 @@ describe('Client defaulter path', () => {
it('shoul checked all defaulters', async() => { it('shoul checked all defaulters', async() => {
await page.loginAndModule('insurance', 'client'); await page.loginAndModule('insurance', 'client');
await page.accessToSection('client.defaulter.index'); await page.accessToSection('client.defaulter');
await page.waitToClick(selectors.clientDefaulter.allDefaulterCheckbox); await page.waitToClick(selectors.clientDefaulter.allDefaulterCheckbox);
}); });

View File

@ -122,7 +122,7 @@ export default class Controller extends Section {
} }
} }
ngModule.vnComponent('vnClientDefaulterIndex', { ngModule.vnComponent('vnClientDefaulter', {
template: require('./index.html'), template: require('./index.html'),
controller: Controller controller: Controller
}); });

View File

@ -2,7 +2,7 @@ import './index';
import crudModel from 'core/mocks/crud-model'; import crudModel from 'core/mocks/crud-model';
describe('client defaulter', () => { describe('client defaulter', () => {
describe('Component vnClientDefaulterIndex', () => { describe('Component vnClientDefaulter', () => {
let controller; let controller;
let $httpBackend; let $httpBackend;
@ -11,7 +11,7 @@ describe('client defaulter', () => {
beforeEach(inject(($componentController, _$httpBackend_) => { beforeEach(inject(($componentController, _$httpBackend_) => {
$httpBackend = _$httpBackend_; $httpBackend = _$httpBackend_;
const $element = angular.element('<vn-client-defaulter></vn-client-defaulter>'); const $element = angular.element('<vn-client-defaulter></vn-client-defaulter>');
controller = $componentController('vnClientDefaulterIndex', {$element}); controller = $componentController('vnClientDefaulter', {$element});
controller.$.model = crudModel; controller.$.model = crudModel;
controller.$.model.data = [ controller.$.model.data = [
{clientFk: 1101, amount: 125}, {clientFk: 1101, amount: 125},

View File

@ -8,7 +8,7 @@
"main": [ "main": [
{"state": "client.index", "icon": "person"}, {"state": "client.index", "icon": "person"},
{"state": "client.notification", "icon": "campaign"}, {"state": "client.notification", "icon": "campaign"},
{"state": "client.defaulter.index", "icon": "icon-defaulter"} {"state": "client.defaulter", "icon": "icon-defaulter"}
], ],
"card": [ "card": [
{"state": "client.card.basicData", "icon": "settings"}, {"state": "client.card.basicData", "icon": "settings"},
@ -366,13 +366,7 @@
{ {
"url": "/defaulter", "url": "/defaulter",
"state": "client.defaulter", "state": "client.defaulter",
"component": "ui-view", "component": "vn-client-defaulter",
"description": "Defaulter"
},
{
"url": "/index?q",
"state": "client.defaulter.index",
"component": "vn-client-defaulter-index",
"description": "Defaulter" "description": "Defaulter"
}, },
{ {

View File

@ -4,14 +4,24 @@ module.exports = Self => {
Self.remoteMethodCtx('absences', { Self.remoteMethodCtx('absences', {
description: 'Returns an array of absences from an specified contract', description: 'Returns an array of absences from an specified contract',
accepts: [{ accepts: [{
arg: 'businessFk', arg: 'workerFk',
type: 'number', type: 'number',
required: true, required: true,
}, },
{
arg: 'businessFk',
type: 'number',
required: false,
},
{ {
arg: 'year', arg: 'year',
type: 'date', type: 'date',
required: true, required: true,
},
{
arg: 'all',
type: 'boolean',
required: false,
}], }],
returns: [{ returns: [{
arg: 'absences', arg: 'absences',
@ -27,7 +37,7 @@ module.exports = Self => {
} }
}); });
Self.absences = async(ctx, businessFk, year, options) => { Self.absences = async(ctx, workerFk, businessFk, year, options) => {
const models = Self.app.models; const models = Self.app.models;
const started = new Date(); const started = new Date();
@ -45,7 +55,17 @@ module.exports = Self => {
if (typeof options == 'object') if (typeof options == 'object')
Object.assign(myOptions, options); Object.assign(myOptions, options);
const contract = await models.WorkerLabour.findOne({ let condition = {
and: [
{workerFk: workerFk},
{businessFk: businessFk}
]
};
if (businessFk)
condition.and.push({workerFk: workerFk});
const contracts = await models.WorkerLabour.find({
include: [{ include: [{
relation: 'holidays', relation: 'holidays',
scope: { scope: {
@ -82,16 +102,19 @@ module.exports = Self => {
} }
} }
}], }],
where: {businessFk} where: condition
}, myOptions); }, myOptions);
if (!contract) return; if (!contracts) return;
const isSubordinate = await models.Worker.isSubordinate(ctx, contract.workerFk, myOptions); const isSubordinate = await models.Worker.isSubordinate(ctx, workerFk, myOptions);
if (!isSubordinate) if (!isSubordinate)
throw new UserError(`You don't have enough privileges`); throw new UserError(`You don't have enough privileges`);
const absences = []; const absences = [];
const holidays = [];
for (let contract of contracts) {
for (let absence of contract.absences()) { for (let absence of contract.absences()) {
absence.dated = new Date(absence.dated); absence.dated = new Date(absence.dated);
absence.dated.setHours(0, 0, 0, 0); absence.dated.setHours(0, 0, 0, 0);
@ -99,15 +122,13 @@ module.exports = Self => {
absences.push(absence); absences.push(absence);
} }
// Workcenter holidays for (let day of contract.workCenter().holidays()) {
const holidays = [];
const holidayList = contract.workCenter().holidays();
for (let day of holidayList) {
day.dated = new Date(day.dated); day.dated = new Date(day.dated);
day.dated.setHours(0, 0, 0, 0); day.dated.setHours(0, 0, 0, 0);
holidays.push(day); holidays.push(day);
} }
}
return [absences, holidays]; return [absences, holidays];
}; };

View File

@ -3,12 +3,13 @@ const app = require('vn-loopback/server/server');
describe('Worker absences()', () => { describe('Worker absences()', () => {
it('should get the absence calendar for a full year contract', async() => { it('should get the absence calendar for a full year contract', async() => {
const ctx = {req: {accessToken: {userId: 1106}}}; const ctx = {req: {accessToken: {userId: 1106}}};
const workerId = 1106;
const businessId = 1106; const businessId = 1106;
const now = new Date(); const now = new Date();
const year = now.getFullYear(); const year = now.getFullYear();
const [absences] = await app.models.Calendar.absences(ctx, businessId, year); const [absences] = await app.models.Calendar.absences(ctx, workerId, businessId, year);
const firstType = absences[0].absenceType().name; const firstType = absences[0].absenceType().name;
const sixthType = absences[5].absenceType().name; const sixthType = absences[5].absenceType().name;
@ -35,7 +36,7 @@ describe('Worker absences()', () => {
`UPDATE postgresql.business SET date_end = ? WHERE business_id = ?`, `UPDATE postgresql.business SET date_end = ? WHERE business_id = ?`,
[null, worker.businessFk], options); [null, worker.businessFk], options);
const [absences] = await app.models.Calendar.absences(ctx, businessId, year, options); const [absences] = await app.models.Calendar.absences(ctx, worker.id, businessId, year, options);
let firstType = absences[0].absenceType().name; let firstType = absences[0].absenceType().name;
let sixthType = absences[5].absenceType().name; let sixthType = absences[5].absenceType().name;
@ -51,6 +52,8 @@ describe('Worker absences()', () => {
it('should give the same holidays as worked days since the holidays amount matches the amount of days in a year', async() => { it('should give the same holidays as worked days since the holidays amount matches the amount of days in a year', async() => {
const businessId = 1106; const businessId = 1106;
const workerId = 1106;
const userId = 1106; const userId = 1106;
const today = new Date(); const today = new Date();
@ -101,7 +104,7 @@ describe('Worker absences()', () => {
const ctx = {req: {accessToken: {userId: userId}}}; const ctx = {req: {accessToken: {userId: userId}}};
const [absences] = await app.models.Calendar.absences(ctx, businessId, currentYear); const [absences] = await app.models.Calendar.absences(ctx, workerId, businessId, currentYear);
const firstType = absences[0].absenceType().name; const firstType = absences[0].absenceType().name;
const sixthType = absences[5].absenceType().name; const sixthType = absences[5].absenceType().name;

View File

@ -282,6 +282,7 @@ class Controller extends Section {
refresh() { refresh() {
const params = { const params = {
workerFk: this.$params.id,
businessFk: this.businessId, businessFk: this.businessId,
year: this.year year: this.year
}; };

View File

@ -328,7 +328,7 @@ describe('Worker', () => {
jest.spyOn(controller, 'onData').mockReturnThis(); jest.spyOn(controller, 'onData').mockReturnThis();
const expecteResponse = [{id: 1}]; const expecteResponse = [{id: 1}];
const expectedParams = {year: year}; const expectedParams = {workerFk: controller.worker.id, year: year};
const serializedParams = $httpParamSerializer(expectedParams); const serializedParams = $httpParamSerializer(expectedParams);
$httpBackend.expect('GET', `Calendars/absences?${serializedParams}`).respond(200, expecteResponse); $httpBackend.expect('GET', `Calendars/absences?${serializedParams}`).respond(200, expecteResponse);
controller.refresh(); controller.refresh();

View File

@ -32,11 +32,6 @@ class Controller extends Section {
set worker(value) { set worker(value) {
this._worker = value; this._worker = value;
if (value) {
this.getActiveContract()
.then(() => this.getAbsences());
}
} }
/** /**
@ -96,14 +91,6 @@ class Controller extends Section {
} }
} }
getActiveContract() {
return this.$http.get(`Workers/${this.worker.id}/activeContract`)
.then(res => {
if (res.data)
this.businessId = res.data.businessFk;
});
}
fetchHours() { fetchHours() {
const params = {workerFk: this.$params.id}; const params = {workerFk: this.$params.id};
const filter = { const filter = {
@ -123,11 +110,10 @@ class Controller extends Section {
} }
getAbsences() { getAbsences() {
if (!this.businessId) return;
const fullYear = this.started.getFullYear(); const fullYear = this.started.getFullYear();
let params = { let params = {
businessFk: this.businessId, workerFk: this.$params.id,
businessFk: null,
year: fullYear year: fullYear
}; };