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.
		
		
		
		
		
			
		
			
				
					
					
						
							109 lines
						
					
					
						
							5.2 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							109 lines
						
					
					
						
							5.2 KiB
						
					
					
				
								# -*- coding: utf-8 -*-
							 | 
						|
								###################################################################################
							 | 
						|
								#    A part of OpenHrms Project <https://www.openhrms.com>
							 | 
						|
								#
							 | 
						|
								#    Cybrosys Technologies Pvt. Ltd.
							 | 
						|
								#    Copyright (C) 2018-TODAY Cybrosys Technologies (<https://www.cybrosys.com>).
							 | 
						|
								#    Author: Saritha Sahadevan (<https://www.cybrosys.com>)
							 | 
						|
								#
							 | 
						|
								#    This program is free software: you can modify
							 | 
						|
								#    it under the terms of the GNU Affero General Public License (AGPL) 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 <https://www.gnu.org/licenses/>.
							 | 
						|
								#
							 | 
						|
								###################################################################################
							 | 
						|
								from datetime import datetime, timedelta
							 | 
						|
								from odoo import models, fields, api, _, tools
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								class HrPayroll(models.Model):
							 | 
						|
								    _inherit = 'hr.payslip'
							 | 
						|
								
							 | 
						|
								    @api.model
							 | 
						|
								    def get_worked_day_lines(self, contract_ids, date_from, date_to):
							 | 
						|
								        """
							 | 
						|
								        @param contract_ids: list of contract id
							 | 
						|
								        @return: returns a list of dict containing the input that should be applied for the given contract between date_from and date_to
							 | 
						|
								        """
							 | 
						|
								
							 | 
						|
								        def was_on_leave_interval(employee_id, date_from, date_to):
							 | 
						|
								            date_from = fields.Datetime.to_string(date_from)
							 | 
						|
								            date_to = fields.Datetime.to_string(date_to)
							 | 
						|
								            return self.env['hr.holidays'].search([
							 | 
						|
								                ('state', '=', 'validate'),
							 | 
						|
								                ('employee_id', '=', employee_id),
							 | 
						|
								                ('type', '=', 'remove'),
							 | 
						|
								                ('date_from', '<=', date_from),
							 | 
						|
								                ('date_to', '>=', date_to)
							 | 
						|
								            ], limit=1)
							 | 
						|
								
							 | 
						|
								        res = []
							 | 
						|
								        # fill only if the contract as a working schedule linked
							 | 
						|
								        uom_day = self.env.ref('product.product_uom_day', raise_if_not_found=False)
							 | 
						|
								        for contract in self.env['hr.contract'].browse(contract_ids).filtered(lambda contract: contract):
							 | 
						|
								            uom_hour = contract.employee_id.resource_id.calendar_id.uom_id or self.env.ref('product.product_uom_hour',
							 | 
						|
								                                                                                           raise_if_not_found=False)
							 | 
						|
								            interval_data = []
							 | 
						|
								            holidays = self.env['hr.holidays']
							 | 
						|
								            attendances = {
							 | 
						|
								                'name': _("Normal Working Days paid at 100%"),
							 | 
						|
								                'sequence': 1,
							 | 
						|
								                'code': 'WORK100',
							 | 
						|
								                'number_of_days': 0.0,
							 | 
						|
								                'number_of_hours': 0.0,
							 | 
						|
								                'contract_id': contract.id,
							 | 
						|
								            }
							 | 
						|
								            leaves = {}
							 | 
						|
								
							 | 
						|
								            # Gather all intervals and holidays
							 | 
						|
								            for days in contract.shift_schedule:
							 | 
						|
								                start_date = datetime.strptime(days.start_date, tools.DEFAULT_SERVER_DATE_FORMAT)
							 | 
						|
								                end_date = datetime.strptime(days.end_date, tools.DEFAULT_SERVER_DATE_FORMAT)
							 | 
						|
								
							 | 
						|
								                nb_of_days = (end_date - start_date).days + 1
							 | 
						|
								                for day in range(0, nb_of_days):
							 | 
						|
								
							 | 
						|
								                    working_intervals_on_day = days.hr_shift.get_working_intervals_of_day(
							 | 
						|
								                        start_dt=start_date + timedelta(days=day))
							 | 
						|
								                    for interval in working_intervals_on_day:
							 | 
						|
								                        interval_data.append(
							 | 
						|
								                            (interval, was_on_leave_interval(contract.employee_id.id, interval[0], interval[1])))
							 | 
						|
								
							 | 
						|
								            # Extract information from previous data. A working interval is considered:
							 | 
						|
								            # - as a leave if a hr.holiday completely covers the period
							 | 
						|
								            # - as a working period instead
							 | 
						|
								            for interval, holiday in interval_data:
							 | 
						|
								                holidays |= holiday
							 | 
						|
								                hours = (interval[1] - interval[0]).total_seconds() / 3600.0
							 | 
						|
								                if holiday:
							 | 
						|
								                    # if he was on leave, fill the leaves dict
							 | 
						|
								                    if holiday.holiday_status_id.name in leaves:
							 | 
						|
								                        leaves[holiday.holiday_status_id.name]['number_of_hours'] += hours
							 | 
						|
								                    else:
							 | 
						|
								                        leaves[holiday.holiday_status_id.name] = {
							 | 
						|
								                            'name': holiday.holiday_status_id.name,
							 | 
						|
								                            'sequence': 5,
							 | 
						|
								                            'code': holiday.holiday_status_id.name,
							 | 
						|
								                            'number_of_days': 0.0,
							 | 
						|
								                            'number_of_hours': hours,
							 | 
						|
								                            'contract_id': contract.id,
							 | 
						|
								                        }
							 | 
						|
								                else:
							 | 
						|
								                    # add the input vals to tmp (increment if existing)
							 | 
						|
								                    attendances['number_of_hours'] += hours
							 | 
						|
								            # Clean-up the results
							 | 
						|
								            leaves = [value for key, value in leaves.items()]
							 | 
						|
								            for data in [attendances] + leaves:
							 | 
						|
								                data['number_of_days'] = uom_hour._compute_quantity(data['number_of_hours'], uom_day) \
							 | 
						|
								                    if uom_day and uom_hour \
							 | 
						|
								                    else data['number_of_hours'] / 8.0
							 | 
						|
								                res.append(data)
							 | 
						|
								        return res
							 |