You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							126 lines
						
					
					
						
							5.3 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							126 lines
						
					
					
						
							5.3 KiB
						
					
					
				| # -*- coding: utf-8 -*- | |
| 
 | |
| import itertools | |
| from odoo import models, fields, api | |
| 
 | |
| 
 | |
| class PayrollStructure(models.Model): | |
|     _inherit = 'hr.payroll.structure' | |
| 
 | |
|     timesheet_structure = fields.Boolean(string='Timesheet Based Structure', default=False, | |
|                                          help='Flag Which says the Structure is based on Timesheets submitted by employee') | |
| 
 | |
| 
 | |
| class HrContract(models.Model): | |
|     _inherit = 'hr.contract' | |
| 
 | |
|     timesheet_payroll = fields.Boolean(string='Timesheet Based Payroll', default=False, | |
|                                        help='Flag Which says the payroll is based on Timesheets submitted by employee') | |
| 
 | |
|     @api.onchange('timesheet_payroll') | |
|     def onchange_timesheet_payroll(self): | |
|         if self.timesheet_payroll: | |
|             self.struct_id = False | |
|             return { | |
|                 'domain': { | |
|                     'struct_id': [('timesheet_structure', '=', True)] | |
|                 }, | |
|             } | |
|         else: | |
|             return { | |
|                 'domain': {'struct_id': []}, | |
|             } | |
| 
 | |
| 
 | |
| class HrPayslip(models.Model): | |
|     _inherit = 'hr.payslip' | |
| 
 | |
|     timesheet_hours = fields.Integer(string='Timesheet Hours',  states={'done': [('readonly', True)]}, | |
|                                      help='Total Timesheet hours approved for employee.') | |
|     total_hours = fields.Integer(string='Total Hours', states={'done': [('readonly', True)]}, | |
|                                  help='Total Hours By Working schedule') | |
|     timesheet_payroll = fields.Boolean(related='contract_id.timesheet_payroll') | |
| 
 | |
|     def compute_timesheet_hours(self, contract_id, date_from, date_to): | |
|         """ | |
|         Function which computes total hours, timesheethours, attendances, timehseet difference, | |
|         :param employee_id: | |
|         :param date_from: | |
|         :param date_to: | |
|         :return:  computed total timesheet hours within duration, total hours by working schedule | |
|         """ | |
|         if not contract_id: | |
|             return {} | |
|         env = self.env | |
|         employee_id = contract_id.employee_id | |
|         timesheet_object = env['hr_timesheet_sheet.sheet'] | |
|         total_hours = 0.0 | |
|         timesheet_hours = timesheet_attendance = timesheet_difference = 0.0 | |
|         for line in self.worked_days_line_ids: | |
|             total_hours += line.number_of_hours if line.code == 'WORK100' else 0.0 | |
|         sheets = timesheet_object.search([ | |
|             ('employee_id', '=', employee_id.id), | |
|             ('date_from', '>=', date_from), | |
|             ('date_to', '<=', date_to), | |
|             ('state', '=', 'done') | |
| 
 | |
|         ]) | |
|         period_ids = [] | |
|         period_ids += [sheet.period_ids.ids for sheet in sheets] | |
|         period_ids = list(itertools.chain.from_iterable(period_ids)) | |
|         if len(period_ids): | |
|             self.env.cr.execute(""" | |
|                         SELECT | |
|                                sum(total_attendance) as total_attendance, | |
|                                sum(total_timesheet) as total_timesheet, | |
|                                sum(total_difference) as  total_difference | |
|                         FROM hr_timesheet_sheet_sheet_day | |
|                         WHERE id IN %s | |
|                     """, (tuple(period_ids),)) | |
|             data = self.env.cr.dictfetchall() | |
|             for x in data: | |
|                 timesheet_hours = x.pop('total_timesheet') | |
|                 timesheet_attendance = x.pop('total_attendance') | |
|                 timesheet_difference = x.pop('total_difference') | |
| 
 | |
|         return { | |
|             'timesheet_hours': timesheet_hours, | |
|             'timesheet_attendance': timesheet_attendance, | |
|             'timesheet_difference': timesheet_difference, | |
|             'total_hours': total_hours, | |
|         } | |
| 
 | |
|     @api.onchange('employee_id', 'date_from') | |
|     def onchange_employee(self): | |
|         super(HrPayslip, self).onchange_employee() | |
|         if self.contract_id.timesheet_payroll: | |
|             datas = self.compute_timesheet_hours(self.contract_id, self.date_from, self.date_to) | |
|             self.timesheet_hours = datas.get('timesheet_hours') or 0.0 | |
|             self.total_hours = datas.get('total_hours') or 0.0 | |
|         return | |
| 
 | |
|     @api.model | |
|     def get_payslip_lines(self, contract_ids, payslip_id): | |
|         class BrowsableObject(object): | |
|             def __init__(self, employee_id, dict): | |
|                 self.employee_id = employee_id | |
|                 self.dict = dict | |
| 
 | |
|             def __getattr__(self, attr): | |
|                 return attr in self.dict and self.dict.__getitem__(attr) or 0.0 | |
|         class Payslips(BrowsableObject): | |
|             """a class that will be used into the python code, mainly for usability purposes""" | |
| 
 | |
|             def sum(self, code, from_date, to_date=None): | |
|                 if to_date is None: | |
|                     to_date = fields.Date.today() | |
|                 self.env.cr.execute("""SELECT sum(case when hp.credit_note = False then (pl.total) else (-pl.total) end) | |
|                                 FROM hr_payslip as hp, hr_payslip_line as pl | |
|                                 WHERE hp.employee_id = %s AND hp.state = 'done' | |
|                                 AND hp.date_from >= %s AND hp.date_to <= %s AND hp.id = pl.slip_id AND pl.code = %s""", | |
|                                     (self.employee_id, from_date, to_date, code)) | |
|                 res = self.env.cr.fetchone() | |
|                 return res and res[0] or 0.0 | |
|             timesheet_hours = self.timesheet_hours | |
|             total_hours = self.total_hours | |
|         return super(HrPayslip, self).get_payslip_lines(contract_ids, payslip_id) |