# -*- coding: utf-8 -*-
##############################################################################
#
# TicTac allows several HR functionalities. This program bases on Odoo v. 8. Copyright
# (C) 2018 ITIS www.itis.de commissioned by Wikimedia Deutschland e.V.
#
# This program is free software: you can redistribute it and/or modify it under the
# terms of the GNU Affero General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License along with
# this program. If not, see
Hallo """+str(employee_brw.name) +""",
Sie wurden automatisch von TicTac abgemeldet. Bitte passen Sie ihr Timesheet an.
Vielen Dank ihr HR Team.
""" email_vals['email_from'] = employee_brw.company_id and employee_brw.company_id.email or 'info@yourcompany.example.com' email_vals['email_to'] = email_to email_vals['subject'] = 'Automatic Sign Out' email_vals['body_html'] = body_html # if active_outgoing_mail_server: # email_vals['mail_server_id'] = active_outgoing_mail_server.id mail = self.env['mail.mail'].create(email_vals) mail.send() logger.info("--Sign out email send.") @api.multi def action_set_to_draft(self): res = super(HRTimesheetSheet, self).action_set_to_draft() #newovertime overtime_count = self.employee_id.employee_overtime_id.emp_overtime_count - self.time_diff self.employee_id.employee_overtime_id.write({'emp_overtime_count': overtime_count}) # overtime_count = self.employee_id.overtime_count - self.time_diff # self.employee_id.write({'overtime_count': overtime_count}) return res @api.one def action_cancel(self): #newovertime overtime_count = self.employee_id.employee_overtime_id.emp_overtime_count - self.time_diff self.employee_id.employee_overtime_id.write({'emp_overtime_count': overtime_count}) # overtime_count = self.employee_id.overtime_count - self.time_diff # self.employee_id.write({'overtime_count': overtime_count}) self.write({'state': 'draft'}) return True @api.multi def button_confirm(self): res = super(HRTimesheetSheet, self).button_confirm() #newovertime new_overtime = self.employee_id.employee_overtime_id.emp_overtime_count + self.time_diff self.employee_id.employee_overtime_id.write({'emp_overtime_count': new_overtime}) # new_overtime = self.employee_id.overtime_count + self.time_diff # self.pool.get('hr.employee').write(self._cr,SUPERUSER_ID,self.employee_id.id,{'overtime_count': new_overtime}) #self.employee_id.write({'overtime_count': new_overtime}) self.write({'state': 'confirm'}) return res @api.model def create(self, values): #cr, uid, context = self.env.cr, self.env.uid, self.env.context res_users_obj = self.env["res.users"] ir_model_obj = self.env["ir.model.data"] res_user_data = res_users_obj.browse([self.env.uid]) xml_list = [] group_ids = [] for group in res_user_data.groups_id: group_ids.append(group.id) model_data = ir_model_obj.search([['model','=','res.groups'],['res_id','in',group_ids]]) #model_data = ir_model_obj.browse(cr,uid,model_ids,context) for value in model_data: xml_list.append(value.name) if "group_hr_manager" in xml_list or "group_hr_payroll_manager" in xml_list or "group_hr_user" in xml_list or self.env.uid == 1: if 'date_from' in values and 'date_to' in values and values['date_from'] != values['date_to']: raise Warning(_("Start date and end date have to be the same day.")) if 'date_from' in values and 'date_to' in values and 'employee_id' in values and self.search([('employee_id','=',values['employee_id']),('date_from','<=',values['date_from']),('date_to','>=',values['date_from'])]): raise Warning(_("You can only create one timesheet each day.")) res = super(HRTimesheetSheet, self).create(values) res.calc_planned_hours() res.calc_leave_hours() return res else: raise Warning(_("You do not have pemission to create timesheets!")) @api.one def cal_tot_cont_time(self): total_duration = 0.0 for pln_hrs in self.planned_ids: total_duration += pln_hrs.duration self.total_contract_time = total_duration self.time_diff = self.total_timesheet - self.total_contract_time return True @api.one def cal_total_hours(self): total_duration = 0.0 for pln_hrs in self.planned_ids: total_duration += pln_hrs.duration self.total_timesheet_hours = self.total_timesheet self.total_planned_hours = total_duration self.overtime_hours = self.total_timesheet_hours - self.total_planned_hours @api.multi def fetch_holiday_list(self): res = [] for hld in self.env["itis.holiday"].search([]): res.append(hld.date) return res @api.model def close_timesheet(self): for timesheet in self.search([('date_to','<',datetime.today().date().replace(day=1)),('state','=','draft')]): timesheet.button_confirm() return @api.one def calc_planned_hours(self): res = {} hld_list = self.fetch_holiday_list() date_from = datetime.strptime(self.date_from, DEFAULT_SERVER_DATE_FORMAT) date_to = datetime.strptime(self.date_to, DEFAULT_SERVER_DATE_FORMAT) temp_date = date_from while temp_date <= date_to: weekday = temp_date.weekday() day_hours = 0.0 if datetime.strftime(temp_date, DEFAULT_SERVER_DATE_FORMAT) in hld_list: res.update({temp_date:day_hours}) temp_date += timedelta(days=1) continue # contract_ids = self.pool.get('hr.contract').search(self._cr, SUPERUSER_ID, [('employee_id','=',self.id)]) # contract_ids = self.pool.get('hr.contract').browse(self._cr, SUPERUSER_ID,contract_ids) # for contract in contract_ids: for contract in self.employee_id.contract_ids: cont_start_date = datetime.strptime(contract.date_start, DEFAULT_SERVER_DATE_FORMAT) cont_end_date = False if not contract.date_end: if cont_start_date <= temp_date: day_hours += self.get_hours(weekday, contract.working_hours.attendance_ids) else: cont_end_date = datetime.strptime(contract.date_end, DEFAULT_SERVER_DATE_FORMAT) if cont_start_date <= temp_date and cont_end_date >= temp_date: day_hours += self.get_hours(weekday, contract.working_hours.attendance_ids) res.update({temp_date:day_hours}) temp_date += timedelta(days=1) plan_hr_obj = self.env['planned.hours'] dts = res.keys() for plan_hrs in self.planned_ids: sheet_date = datetime.strptime(plan_hrs.sheet_date, DEFAULT_SERVER_DATE_FORMAT) if sheet_date not in dts: sheet_date.unlink() for dt, hrs in res.iteritems(): dt_exist = False for plan_hrs in self.planned_ids: sheet_date = datetime.strptime(plan_hrs.sheet_date, DEFAULT_SERVER_DATE_FORMAT) if sheet_date == dt: dt_exist = True if plan_hrs.duration != hrs: plan_hrs.write({'duration': hrs}) if not dt_exist: vals = { 'sheet_date': datetime.strftime(dt, DEFAULT_SERVER_DATE_FORMAT), 'duration': hrs, 'sheet_id': self.id, } plan_hr_obj.create(vals) def get_hours(self, weekday, atten_ids): res = 0.0 for atten in atten_ids: if int(atten.dayofweek) == weekday: res += atten.hour_to - atten.hour_from return res @api.depends("timesheet_ids.unit_amount") @api.one def calc_actual_ot(self): if self.state not in ['new', 'draft']: # self.actual_ot = self.employee_id.overtime_count # newovertime self.actual_ot = self.employee_id.employee_overtime_id.emp_overtime_count return True act_wk_dict = {} act_working = 0.0 for timesheet in self.timesheet_ids: tm = act_wk_dict.get(timesheet.date, 0.0) + timesheet.unit_amount act_wk_dict.update({timesheet.date: tm}) act_working += timesheet.unit_amount wk_dts = act_wk_dict.keys() pln_wk_dict = {} pl_working = 0.0 for pln_hr in self.planned_ids: pln_wk_dict.update({pln_hr.sheet_date: pln_hr.duration}) is_cur_sheet = False cur_date = datetime.today() date_from = datetime.strptime(self.date_from, DEFAULT_SERVER_DATE_FORMAT) date_to = datetime.strptime(self.date_to, DEFAULT_SERVER_DATE_FORMAT) if date_from <= cur_date and date_to >= cur_date: is_cur_sheet = True tot_time = 0.0 while date_from <= date_to: if is_cur_sheet and date_from > cur_date: date_from += timedelta(days=1) continue dt_str = datetime.strftime(date_from, DEFAULT_SERVER_DATE_FORMAT) tot_time += act_wk_dict.get(dt_str, 0.0) - pln_wk_dict.get(dt_str, 0.0) date_from += timedelta(days=1) # print"emp overtime----",self.employee_id.overtime_count # print"tot_time--------",tot_time # add a logic to add all the overtime hr for the current month date_from = datetime.strptime(self.date_from, DEFAULT_SERVER_DATE_FORMAT) first_date = (date_from + relativedelta(months=-1)).replace(day=1) monthly_overtime = 0.0 while first_date <= date_from: timesheet_record = self.search([('date_from','=',first_date),('employee_id','=',self.employee_id.id),('state','in',['new','draft'])],limit=1) if timesheet_record: # print"timesheet_record.time_diff----",timesheet_record.time_diff monthly_overtime += timesheet_record.time_diff first_date += timedelta(days=1) # print"monthly_overtime-----",monthly_overtime # self.actual_ot = self.employee_id.overtime_count + monthly_overtime # newovertime self.actual_ot = self.employee_id.employee_overtime_id.emp_overtime_count + monthly_overtime return True total_contract_time = fields.Float(_("Total Planned Hours"), compute="cal_tot_cont_time", multi="cal_tot_cont_time") time_diff = fields.Float(_("Time Diffrence"), compute="cal_tot_cont_time", multi="cal_tot_cont_time") planned_ids = fields.One2many("planned.hours", "sheet_id", _("Planned Hours")) actual_ot = fields.Float(_("Actual Overttime Count"), compute="calc_actual_ot") timesheet_ids2 = fields.One2many("hr.analytic.timesheet","sheet_id",string="Timesheet") total_planned_hours = fields.Float(_("Planned Hours"), compute="cal_total_hours", multi="total_hours") total_timesheet_hours =fields.Float(_("Total Hours"), compute="cal_total_hours", multi="total_hours") overtime_hours =fields.Float(_("Overtime Hours"), compute="cal_total_hours", multi="total_hours") class PlannedHours(models.Model): _name = 'planned.hours' sheet_date = fields.Date("Date") duration = fields.Float("Hours") sheet_id = fields.Many2one("hr_timesheet_sheet.sheet", 'Sheet') class ServiceDescription(models.Model): _name = 'service.description' name = fields.Char("Service Description") # sheet_id = fields.Many2one("hr_timesheet_sheet.sheet", 'Sheet')