Skip to content

Commit

Permalink
[DEV] wip: utility dashboard; cleaned calendar
Browse files Browse the repository at this point in the history
  • Loading branch information
mymage committed Jun 20, 2020
1 parent db4da9f commit 0831b07
Show file tree
Hide file tree
Showing 10 changed files with 278 additions and 41 deletions.
8 changes: 3 additions & 5 deletions hr_duty_planner/TODO.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ ToDo list
**Models**
* service template
* DEV limit to 1 Container Service for off_duty type service
* DEV management of working/holiday calendar
* DEV management of working/holiday calendar on generation
* service allocate
* DEV method to update all employees name list
* DEV activate _compute_emply_name method to update all employees name list
* service rule
* DEV complete rule method management
* DEV management of errors: log/popup
Expand All @@ -16,13 +16,12 @@ ToDo list
**Views**
* service template form
* FIX custom css loading
* FIX on deploy off_duty set to readonly
* FIX on deploy set off_duty to readonly
* FIX layout
* service allocate tree
* FIX check rule button position
* service allocate calendar
* DEV text format
* DEV lock action on empty cells
* DEV check/alert template expected fulfillment
* FIX employee name display (newline separated)
* FIX element dedicated color (web_calendar)
Expand All @@ -32,7 +31,6 @@ ToDo list
* DEV check/alert template expected fulfillment
* FIX element dedicated color (web_timeline)
* service rule
* DEV add profile reference to employee, equipment, vehicle
* FIX on deploy lock edit option
* FIX optimize double_assign method
* service profile
Expand Down
1 change: 1 addition & 0 deletions hr_duty_planner/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
'views/service_container_view.xml',
'views/service_expected_view.xml',
'views/service_template_view.xml',
'views/service_utility_view.xml',
'views/employee_profile.xml',
'views/vehicle_profile.xml',
'views/equipment_profile.xml',
Expand Down
1 change: 1 addition & 0 deletions hr_duty_planner/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
expected_equipment, expected_vehicle, expected_skill, \
service_aggregator, \
service_rule, service_rule_field, service_profile, service_profile_parameter, \
service_utility, \
employee_profile, vehicle_profile, equipment_profile
57 changes: 46 additions & 11 deletions hr_duty_planner/models/service_allocate.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,16 @@ class ServiceAllocate(models.Model):
# employee names
employee_names = fields.Text('Employees', compute='_compute_emply_name', store=True)
# message for skills check
employee_check = fields.Text('Skills coverage', default='', store=True)
employee_check = fields.Text('Skills coverage', default='Not checked', store=True)
# assigned equipment
equipment_ids = fields.Many2many('maintenance.equipment', string='Equipment')
# message for equipments check
equipment_check = fields.Text('Equipments coverage', default='', store=True)
equipment_check = fields.Text('Equipments coverage', default='Not checked',
store=True)
# assigned vehicles
vehicle_ids = fields.Many2many('fleet.vehicle', string='Vehicles')
# message for vehicles check
vehicle_check = fields.Text('Vehicles coverage', default='', store=True)
vehicle_check = fields.Text('Vehicles coverage', default='Not checked', store=True)

# locality reference
locality = fields.Char('Locality')
Expand Down Expand Up @@ -135,9 +136,10 @@ def _compute_emply_name(self):
for service in self:
service.employee_names = ''
for employee in service.employee_ids:
service.employee_names += employee.name + '\n'
service.employee_names += employee.name + ', \n'
return

@api.onchange('service_template_id')
def check_skill_request(self):
"""
Check if all required skills are covered by employees
Expand All @@ -146,7 +148,9 @@ def check_skill_request(self):
# get requested skills by template
skill_request = service.service_template_id.exp_empl_skill_ids
# set error message
self.employee_check = '' if skill_request else 'Not checked'
self.employee_check = ''
if skill_request or service.off_duty \
else 'Not checked'
# for each request counts available employees
for request in skill_request:
available_qty = 0
Expand All @@ -172,6 +176,7 @@ def check_skill_request(self):
self._compute_emply_name()
return

@api.onchange('service_template_id')
def check_equipment_request(self):
"""
Check if all required categories are covered by equipments
Expand All @@ -180,7 +185,9 @@ def check_equipment_request(self):
# get requested categoryies by template
category_request = service.service_template_id.exp_eqpmt_category_ids
# set error message
self.equipment_check = '' if category_request else 'Not checked'
self.equipment_check = ''
if category_request or service.off_duty \
else 'Not checked'
# for each request counts available categories
for request in category_request:
available_qty = 0
Expand All @@ -205,6 +212,7 @@ def check_equipment_request(self):
self.equipment_check = 'All covered'
return

@api.onchange('service_template_id')
def check_vehicle_request(self):
"""
Check if all required type are covered by vehicles
Expand All @@ -213,7 +221,9 @@ def check_vehicle_request(self):
# get requested categoryies by template
vehicle_request = service.service_template_id.exp_vhcl_type_ids
# set error message
self.vehicle_check = '' if vehicle_request else 'Not checked'
self.vehicle_check = ''
if vehicle_request or service.off_duty \
else 'Not checked'
# for each request counts available types
for request in vehicle_request:
available_qty = 0
Expand Down Expand Up @@ -254,7 +264,9 @@ def _get_template_container(self):

def double_assign(self, parameters):
"""
_TODO_ _FIX_ direct call to service.rule.double_assign on the button
Call rule for double assignment check
@param resource_type string: all | employee | equipment | vehicle
@param srv_id int: service id
"""
result = self.env['service.rule'].double_assign(parameters['resource_type'],
parameters['srv_id'])
Expand All @@ -280,6 +292,11 @@ def check_resource_rule(self, parameters):
"""
Check rules for each resource associated to the service
@param srv_id int: id of the service
_todo_
disassemble method per resource type;
pass resource id
pass period limits
"""

# get employee of the service
Expand All @@ -300,12 +317,24 @@ def check_resource_rule(self, parameters):
# _todo_ remove log
_logger.info(employee.name+' '+json.dumps(rule_method))
# execute the memorized rules
employee_result = {'message': '',
'result': True,
'data': {},
}
for method in rule_method:
self.rule_call({'rule_name': method,
result = self.rule_call({
'rule_name': method,
'param': json.dumps(rule_method[method]),
'srv_id': employee.id,
'res_obj': employee,
})
result['data'].update(employee_result['data'])
employee_result = {
'message': employee_result['message'] +
employee.name + ' ' + result['message'] + '\n',
'result': True * result['result'],
'data': result['data'],
}

# get vehicle of the service
for vehicle in self.env['service.allocate'] \
Expand Down Expand Up @@ -343,7 +372,8 @@ def check_resource_rule(self, parameters):
# _todo_ activate check logic on method
_logger.info(equipment.name+' '+json.dumps(rule_method))

return
# _todo_ complete with equipment vehicle
return employee_result

@api.model
def create(self, values):
Expand All @@ -356,7 +386,6 @@ def create(self, values):
if not new_service.generation_id:
new_service.generation_id = datetime.datetime.now(). \
strftime("M %Y-%m-%d-%H-%M-%S")

new_service.check_skill_request()
new_service.check_equipment_request()
new_service.check_vehicle_request()
Expand All @@ -377,6 +406,12 @@ def create(self, values):
"parent_service_id" : new_service.id,
"generation_id" : new_service.generation_id,
}
# clear checks for off duty services
if new_service.service_template_id.next_template_id.off_duty:
new_service_data["employee_check"] = ''
new_service_data["equipment_check"] = ''
new_service_data["vehicle_check"] = ''

new_service_nxt = super(ServiceAllocate, self).create(new_service_data)
# save child reference
new_service.next_service_id = new_service_nxt
Expand Down
74 changes: 65 additions & 9 deletions hr_duty_planner/models/service_rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from odoo import fields, models, _
from odoo.exceptions import UserError
import json
import datetime
import logging

_logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -37,10 +38,9 @@ def double_assign(self, resource_type, obj_id):
"""
Check if a resource has more than one shift assigned at same time
@param resource_type string: type of the resource
[all, employee, vehicle, equipment]
[all | employee | vehicle | equipment]
@param obj_id int: id of the service; -1 to check all services
"""
# _TODO_ optimize

rule_result = True
rule_msg = ''
Expand Down Expand Up @@ -158,9 +158,12 @@ def double_assign(self, resource_type, obj_id):
service_double.id,
vehicle.name))

if not rule_result:
if obj_id > 0 and not rule_result:
raise UserError(_('Elements with overlapped shift:')+'\n'+rule_msg)
return rule_result
return {'message': _('Elements with overlapped shift:')+'\n'+rule_msg,
'result': rule_result,
'data': {}
}

def rule_call(self, rule, param, srv_id, res_obj):
"""
Expand All @@ -173,7 +176,7 @@ def rule_call(self, rule, param, srv_id, res_obj):
@return dict: rule elaboration
"""

# _TODO_ check if in rule_id
# _TODO_ check if rule is in rule_id
rule_name = rule
# Get the method from 'self'. Default to a lambda.
method = getattr(self, rule_name, "_invalid_rule")
Expand Down Expand Up @@ -218,6 +221,52 @@ def _rule_method_template(self, param, srv_id, res_obj):
"""
return {'message': 'Template', 'result': True, 'data': {}}

def hour_active_periond(self, parameters):
"""
Calculate the total of active hours of a resource in a period of time.
Active hours are on no off-duty services.
@param parameters dict:
@param period dict:{'date_start':, 'date_stop': } period limit
@param srv_id int: service to analyze
@param res_obj obj: resourse object to analyze
_todo_ manage on call shift
"""
total_time = 0
date_start = parameters['period']['date_star'] \
if parameters['period'] and parameters['period']['date_star'] \
else datetime.datetime(datetime.datetime.now().year, 1, 1)
date_stop = parameters['period']['date_stop'] \
if parameters['period'] and parameters['period']['date_stop'] \
else datetime.datetime(datetime.datetime.now().year, 12, 31)

# extract employees of the service
for employee in (self.env['service.allocate']
.search([('id', '=', parameters['srv_id'])]).employee_ids):
# get services where employee is assigned
# _todo_ manage real start/stop date
sql = ('SELECT service_allocate_id '
'FROM service_allocate '
'INNER JOIN hr_employee_service_allocate_rel '
'on service_allocate.id=service_allocate_id '
'WHERE '
'scheduled_start >= %s '
'and scheduled_stop <= %s '
'and hr_employee_id = %s ')
self.env.cr.execute(sql, (date_start, date_stop, str(employee.id),))
# get duration of each service
# _todo_ manage real duration
for fetch_srv_id in self.env.cr.fetchall():
total_time += self.env['service.allocate'] \
.search([('id', 'in', fetch_srv_id)]) \
.service_template_id.duration
# _todo_
# raise UserError(_('Totale ore uomo %s') % (total_time))
return {'message': _('Totale ore uomo %s') % (total_time),
'result': True,
'data': {'hours': total_time}
}

def hour_active_week(self, param, srv_id, res_obj):
"""
Calculate the total of active hours of a resource in a week.
Expand All @@ -241,8 +290,12 @@ def hour_active_week(self, param, srv_id, res_obj):
total_time += self.env['service.allocate'] \
.search([('id', 'in', fetch_srv_id)]) \
.service_template_id.duration
raise UserError(_('Totale ore uomo %s') % (total_time))
# return total_time
# _todo_
# raise UserError(_('Totale ore uomo setimana %s') % (total_time))
return {'message': _('Totale ore uomo settimana %s') % (total_time),
'result': True,
'data': {'hours': total_time}
}

def hour_rest_week(self, param, srv_id, res_obj):
"""
Expand Down Expand Up @@ -274,7 +327,10 @@ def hour_active_month(self, param, srv_id, res_obj):
.service_template_id.duration
empl_name = self.env['hr.employee'].search([('id', '=', res_obj.id)]).name
param_dict = json.loads(param)
# raise UserError
# _todo_ remove log
_logger.info(_('Totale ore (mese) %s: %s [limite %s]')
% (empl_name, total_time, param_dict['h_max']))
# return total_time
return {'message': _('Total hours month: %s') % (total_time),
'result': True,
'data': {'hours': total_time}
}
Loading

0 comments on commit 0831b07

Please sign in to comment.