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)
							 |