Skip to content

Commit dae1d04

Browse files
authored
Merge pull request #1125 from civicrm/PCHR-854-fix-actual-hours
PCHR-854: Fix actual hours
2 parents af71899 + c3b34e6 commit dae1d04

File tree

2 files changed

+186
-1
lines changed

2 files changed

+186
-1
lines changed
Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,86 @@
1-
define([ 'job-contract/vendor/fraction', 'job-contract/controllers/controllers'], function (Fraction, controllers) { 'use strict'; controllers.controller('FormHourCtrl',['$scope', '$rootScope', '$filter', '$log', function ($scope, $rootScope, $filter, $log) { $log.debug('Controller: FormHourCtrl'); var entityHour = $scope.entity.hour, utilsHoursLocation = $scope.utils.hoursLocation, locStandHrs = {}; $scope.hrsTypeDefined = false; entityHour.location_standard_hours = entityHour.location_standard_hours || "1"; locStandHrs = $filter('getObjById')(utilsHoursLocation, entityHour.location_standard_hours); function updateHours(locStandHrs, hrsTypeId) { $scope.hrsTypeDefined = typeof entityHour.hours_type !== 'undefined' && entityHour.hours_type != null && entityHour.hours_type != ''; if ($scope.hrsTypeDefined) { entityHour.hours_unit = locStandHrs.periodicity; switch(+hrsTypeId) { case 8: entityHour.hours_amount = locStandHrs.standard_hours; break; case 4: entityHour.hours_amount = !!entityHour.hours_amount ? entityHour.hours_amount : Math.round(locStandHrs.standard_hours / 2); break; case 0: entityHour.hours_amount = !!entityHour.hours_amount ? entityHour.hours_amount : 0; break; default: entityHour.hours_amount = ''; } return } entityHour.hours_unit = ''; entityHour.hours_amount = ''; } function updateFTE(hrsStandard, hrsAmount){ hrsAmount = parseFloat(hrsAmount) || 0, hrsStandard = parseFloat(hrsStandard) || 0; var fteFraction = new Fraction(hrsAmount, hrsStandard); entityHour.fte_num = String(+entityHour.hours_type ? fteFraction.numerator : 0); entityHour.fte_denom = String(+entityHour.hours_type ? fteFraction.denominator : 0); entityHour.hours_fte = String(parseFloat(((entityHour.fte_num/entityHour.fte_denom) || 0).toFixed(2))); $scope.fteFraction = entityHour.fte_num + '/' + entityHour.fte_denom; } $scope.$watch('entity.hour.location_standard_hours', function(locStandHrsId){ locStandHrs = $filter('getObjById')(utilsHoursLocation, locStandHrsId); updateHours(locStandHrs, entityHour.hours_type); updateFTE(locStandHrs.standard_hours, entityHour.hours_amount); }); $scope.$watch('entity.hour.hours_type', function(hrsTypeId, hrsTypeIdPrev){ if (hrsTypeId != hrsTypeIdPrev) { updateHours(locStandHrs, hrsTypeId); updateFTE(locStandHrs.standard_hours, entityHour.hours_amount); } }); $scope.$watch('entity.hour.hours_amount', function(hrsAmount, hrsAmountPrev){ if (hrsAmount != hrsAmountPrev) { updateFTE(locStandHrs.standard_hours, hrsAmount); } }); $scope.$watch('entity.hour.hours_unit', function(hrsUnit, hrsUnitPrev){ if (hrsUnit != hrsUnitPrev) { updateFTE(locStandHrs.standard_hours, entityHour.hours_amount); } }); }]);});
1+
define([
2+
'job-contract/vendor/fraction',
3+
'job-contract/controllers/controllers'
4+
], function (Fraction, controllers) {
5+
'use strict';
6+
7+
controllers.controller('FormHourCtrl',['$scope', '$rootScope', '$filter', '$log',
8+
function ($scope, $rootScope, $filter, $log) {
9+
$log.debug('Controller: FormHourCtrl');
10+
11+
var entityHour = $scope.entity.hour,
12+
utilsHoursLocation = $scope.utils.hoursLocation,
13+
locStandHrs = {};
14+
15+
$scope.hrsTypeDefined = false;
16+
entityHour.location_standard_hours = entityHour.location_standard_hours || "1";
17+
locStandHrs = $filter('getObjById')(utilsHoursLocation, entityHour.location_standard_hours);
18+
19+
function updateHours(locStandHrs, hrsTypeId) {
20+
$scope.hrsTypeDefined = typeof entityHour.hours_type !== 'undefined' && entityHour.hours_type != null && entityHour.hours_type != '';
21+
22+
if ($scope.hrsTypeDefined) {
23+
entityHour.hours_unit = locStandHrs.periodicity;
24+
25+
switch(+hrsTypeId) {
26+
case 8:
27+
entityHour.hours_amount = locStandHrs.standard_hours;
28+
break;
29+
case 4:
30+
entityHour.hours_amount = Math.round(locStandHrs.standard_hours / 2);
31+
break;
32+
case 0:
33+
entityHour.hours_amount = 0;
34+
break;
35+
default:
36+
entityHour.hours_amount = '';
37+
}
38+
39+
return
40+
}
41+
42+
entityHour.hours_unit = '';
43+
entityHour.hours_amount = '';
44+
}
45+
46+
function updateFTE(hrsStandard, hrsAmount){
47+
48+
hrsAmount = parseFloat(hrsAmount) || 0,
49+
hrsStandard = parseFloat(hrsStandard) || 0;
50+
51+
var fteFraction = new Fraction(hrsAmount, hrsStandard);
52+
53+
entityHour.fte_num = String(+entityHour.hours_type ? fteFraction.numerator : 0);
54+
entityHour.fte_denom = String(+entityHour.hours_type ? fteFraction.denominator : 0);
55+
entityHour.hours_fte = String(parseFloat(((entityHour.fte_num/entityHour.fte_denom) || 0).toFixed(2)));
56+
57+
$scope.fteFraction = entityHour.fte_num + '/' + entityHour.fte_denom;
58+
}
59+
60+
$scope.$watch('entity.hour.location_standard_hours', function(locStandHrsId){
61+
locStandHrs = $filter('getObjById')(utilsHoursLocation, locStandHrsId);
62+
updateHours(locStandHrs, entityHour.hours_type);
63+
updateFTE(locStandHrs.standard_hours, entityHour.hours_amount);
64+
});
65+
66+
$scope.$watch('entity.hour.hours_type', function(hrsTypeId, hrsTypeIdPrev){
67+
if (hrsTypeId != hrsTypeIdPrev) {
68+
updateHours(locStandHrs, hrsTypeId);
69+
updateFTE(locStandHrs.standard_hours, entityHour.hours_amount);
70+
}
71+
});
72+
73+
$scope.$watch('entity.hour.hours_amount', function(hrsAmount, hrsAmountPrev){
74+
if (hrsAmount != hrsAmountPrev) {
75+
updateFTE(locStandHrs.standard_hours, hrsAmount);
76+
}
77+
});
78+
79+
$scope.$watch('entity.hour.hours_unit', function(hrsUnit, hrsUnitPrev){
80+
if (hrsUnit != hrsUnitPrev) {
81+
updateFTE(locStandHrs.standard_hours, entityHour.hours_amount);
82+
}
83+
});
84+
}
85+
]);
86+
});
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
define([
2+
'common/angularMocks',
3+
'job-contract/app'
4+
], function (angular) {
5+
'use strict';
6+
7+
describe('FormHourCtrl', function () {
8+
var ctrl, $controller, $rootScope, $scope;
9+
10+
beforeEach(module('hrjc'));
11+
beforeEach(function () {
12+
inject(function (_$controller_, _$rootScope_) {
13+
$controller = _$controller_;
14+
$rootScope = _$rootScope_;
15+
});
16+
initController();
17+
});
18+
19+
describe('FormHourCtrl', function() {
20+
describe('updateHours', function() {
21+
it('should always change the hours_amount based on hours_type', function() {
22+
expect($scope.entity.hour.hours_amount).toBe('');
23+
24+
$scope.entity.hour.hours_type = '8';
25+
$scope.$digest();
26+
expect($scope.entity.hour.hours_amount).toBe('40.00');
27+
28+
$scope.entity.hour.hours_type = '4';
29+
$scope.$digest();
30+
expect($scope.entity.hour.hours_amount).toBe(20);
31+
32+
$scope.entity.hour.hours_type = '8';
33+
$scope.$digest();
34+
expect($scope.entity.hour.hours_amount).toBe('40.00');
35+
36+
$scope.entity.hour.hours_type = '0';
37+
$scope.$digest();
38+
expect($scope.entity.hour.hours_amount).toBe(0);
39+
40+
$scope.entity.hour.hours_type = '4';
41+
$scope.$digest();
42+
expect($scope.entity.hour.hours_amount).toBe(20);
43+
44+
$scope.entity.hour.hours_type = '0';
45+
$scope.$digest();
46+
expect($scope.entity.hour.hours_amount).toBe(0);
47+
});
48+
});
49+
});
50+
51+
/**
52+
* Initializes the form controller
53+
*
54+
* @param {Object} scopeData additional data to put in the entity details
55+
*/
56+
function initController(scopeData) {
57+
$scope = $rootScope.$new();
58+
$scope.entity = {
59+
hour: {
60+
'id': '1',
61+
'location_standard_hours': '1',
62+
'hours_type': '',
63+
'hours_amount': '',
64+
'hours_unit': '',
65+
'hours_fte': '0',
66+
'fte_num': '0',
67+
'fte_denom': '0',
68+
'jobcontract_revision_id': '1'
69+
}
70+
};
71+
$scope.utils = {
72+
hoursLocation: [
73+
{
74+
'id':'1',
75+
'location': 'Head office',
76+
'standard_hours': '40.00',
77+
'periodicity': 'Week',
78+
'is_active': '1'
79+
},
80+
{
81+
'id':'2',
82+
'location': 'Other office',
83+
'standard_hours': '8.00',
84+
'periodicity': 'Day',
85+
'is_active': '1'
86+
},
87+
{
88+
'id':'3',
89+
'location': 'Small office',
90+
'standard_hours': '36.00',
91+
'periodicity': 'Week',
92+
'is_active': '1'
93+
}
94+
]
95+
};
96+
97+
ctrl = $controller('FormHourCtrl', { $scope: $scope });
98+
}
99+
});
100+
});

0 commit comments

Comments
 (0)