odex30_standard/exp_payroll_custom/models/hr_advance_payslip.py

3574 lines
240 KiB
Python

# -*- coding: utf-8 -*-
import itertools as it
import time
from datetime import datetime, timedelta
from operator import itemgetter
import babel
from dateutil.relativedelta import relativedelta
from odoo import api, fields, models, tools, _
from odoo.exceptions import UserError
# solve Python uses "round half to even" by default
from decimal import Decimal, ROUND_HALF_UP
# New object for loans lines in payslip
class PayslipLoans(models.Model):
_name = 'payslip.loans'
name = fields.Char(string='Name')
code = fields.Char(string='Code')
amount = fields.Float(string='Amount')
date = fields.Date(string='Installment Date')
paid = fields.Boolean()
# Relational field
payslip_loan = fields.Many2one('hr.payslip', ondelete='cascade')
account_id = fields.Many2one('account.account')
class SalaryRuleInput(models.Model):
_inherit = 'hr.payslip'
total_allowances = fields.Float(string='Total Allowance', compute='compute_totals')
total_deductions = fields.Float(string='Total Deduction', compute='compute_totals')
total_loans = fields.Float(string='Total Loans', compute='compute_totals')
total_sum = fields.Float(string='Total Net', compute='compute_totals')
state = fields.Selection(selection_add=[('computed', 'Computed'), ('confirmed', 'Confirmed'),
('transfered', 'Transfer'), ('close', 'Close')], tracking=True)
level_id = fields.Many2one('hr.payroll.structure', string='Level', readonly=True)
group_id = fields.Many2one('hr.payroll.structure', string='Group', readonly=True)
degree_id = fields.Many2one('hr.payroll.structure', string='Degree', readonly=True)
# Relational fields
allowance_ids = fields.One2many('hr.payslip.line', 'payslip_allowance', string='Allowances', index=True)
deduction_ids = fields.One2many('hr.payslip.line', 'payslip_deduction', string='Deductions', index=True)
loan_ids = fields.One2many('payslip.loans', 'payslip_loan', string='Loans', index=True)
employee_id = fields.Many2one('hr.employee', string='Employee', required=True, readonly=False,
domain="[('state','=','open')]", index=True)
# TODO: Add readonly logic in XML view: readonly="state != 'draft'"
contract_id = fields.Many2one('hr.contract', string='Contract', readonly=True, related='employee_id.contract_id')
struct_id = fields.Many2one('hr.payroll.structure', string='Structure', readonly=True,
related='employee_id.contract_id.salary_scale',
help='Defines the rules that have to be applied to this payslip, accordingly '
'to the contract chosen. If you let empty the field contract, this field isn\'t '
'mandatory anymore and thus the rules applied will be all the rules set on the '
'structure of all contracts of the employee valid for the chosen period')
percentage = fields.Float(string='Percentage', default=100)
move_id = fields.Many2one('account.move', string="Move Number")
# bank_id = fields.Many2one(related='employee_id.bank_account_id.bank_id')
basic_allowances = fields.Float(string='Basic Salary', compute='compute_allowances_')
house_allowances = fields.Float(string='House Allowance', compute='compute_allowances_')
trans_allowances = fields.Float(string='Transport Allowance', compute='compute_allowances_')
other_allowances = fields.Float(string='Others Allowance', compute='compute_allowances_')
employee_insurnce = fields.Float(string='Employee Insurnce', compute='compute_allowances_')
company_insurnce = fields.Float(string='Company Insurnce', compute='compute_allowances_')
employee_no = fields.Char(related='employee_id.emp_no', readonly=True,string='Employee Number', store=True)
holiday_start_date = fields.Date(string="Holiday Start Date")
holiday_end_date = fields.Date(string="Holiday End Date")
def compute_allowances_(self):
for item in self:
item.basic_allowances = item.house_allowances = item.trans_allowances = item.employee_insurnce = item.company_insurnce = 0.0
for line in item.allowance_ids:
if line.salary_rule_id.rules_type == 'salary':
item.basic_allowances = line.total
elif line.salary_rule_id.rules_type == 'house':
item.house_allowances = line.total
elif line.salary_rule_id.rules_type == 'transport':
item.trans_allowances = line.total
item.other_allowances = item.total_allowances - (
item.basic_allowances + item.house_allowances + item.trans_allowances)
for line in item.deduction_ids:
if line.salary_rule_id.rules_type == 'insurnce':
item.employee_insurnce = line.total
# TO Dooo
'''if item.employee_insurnce and line.employee_id.contract_id.is_gosi_deducted=='yes':
total_insurnce = item.employee_insurnce*100/10
item.company_insurnce = total_insurnce*12/100
else:
item.company_insurnce = (item.basic_allowances + item.house_allowances)*2/100'''
def confirm(self):
self.write({'state': 'confirmed'})
def payslip_close(self):
self.write({'state': 'close'})
def withdraw(self):
payslip = self.env['hr.payslip'].search([('number', '=', self.number)])
if 'hr.loan.salary.advance' in self.env:
loans = self.env['hr.loan.salary.advance'].search([('employee_id', '=', self.employee_id.id)])
if self.number == payslip.number:
if self.loan_ids:
for loan in self.loan_ids:
loan.paid = False
if loans:
for i in loans:
if i.id == loan.loan_id.id:
for l in i.deduction_lines:
if loan.date == l.installment_date and loan.paid is False:
l.paid = False
#i.remaining_loan_amount += l.installment_amount
i.get_remaining_loan_amount()
# check remaining loan and change state to pay
if i.state == 'closed' and i.remaining_loan_amount > 0.0:
i.state = 'pay'
elif i.remaining_loan_amount == 0.0 and i.gm_propos_amount > 0.0:
i.state = 'closed'
for line in payslip.worked_days_line_ids:
if line.name != 'Working days for this month':
line.unlink()
self.write({'allowance_ids': [fields.Command.clear()], 'deduction_ids': [fields.Command.clear()], 'loan_ids': [fields.Command.clear()]})
self.write({'state': 'draft'})
def return_button(self):
if self.contract_id.advantages:
for advantage_rule in self.contract_id.advantages:
advantage_rule.write({'done': False})
if self.move_id:
if self.move_id.state == 'posted':
raise UserError(_('You can not Return account move %s in state not draft') % self.move_id.name)
else:
self.move_id.unlink()
self.move_id = False
if self.payslip_run_id:
if self.payslip_run_id.move_id:
raise UserError(
_('You can not Return Payslips Patch Has account move %s') % self.payslip_run_id.move_id.name)
self.write({'state': 'computed'})
def transfer(self):
total_list = []
amount, amount1, amount2 = 0.0, 0.0, 0.0
total_allow, total_ded, total_loan = 0.0, 0.0, 0.0
#if self.struct_id.transfer_type == 'one_by_one':
if self.struct_id.transfer_type == 'one_by_one' or self.struct_id.transfer_type == 'all' :
for l in self.allowance_ids:
amount_allow = l.total
account = l.salary_rule_id.rule_debit_account_id
total_list.append({
'name': l.name,
'account_id': account.id,
'debit': amount_allow,
'partner_id': self.employee_id.user_id.partner_id.id,
'analytic_account_id': self.employee_id.contract_id.analytic_account_id.id,
})
amount += amount_allow
total_allow += amount
for ded in self.deduction_ids:
amount_ded = -ded.total
account = ded.salary_rule_id.rule_credit_account_id
total_list.append({
'name': ded.name,
'account_id': account.id,
'credit': amount_ded,
'partner_id': self.employee_id.user_id.partner_id.id
})
amount1 += amount_ded
total_ded += amount1
for lo in self.loan_ids:
amount_loans = -lo.amount
total_list.append({
'name': lo.name + ' (' + lo.code + ')',
'account_id': lo.account_id.id,
'credit': amount_loans,
'partner_id': self.employee_id.user_id.partner_id.id
})
amount2 += amount_loans
total_loan += amount2
# create line for total of all allowance, deduction, loans of one employee
total = total_allow - total_ded - total_loan
total_list.append({
'name': self.name,
'account_id': self.contract_id.journal_id.default_account_id.id,
'partner_id': self.employee_id.user_id.partner_id.id,
'credit': total,
})
if not self.contract_id.journal_id.id:
raise UserError(
_("Please be sure that the employee is linked to contract and contract linked with journal"))
move = self.env['account.move'].create({
'journal_id': self.contract_id.journal_id.id,
'date': self.date_to,
'ref': self.name,
'line_ids': [(0, 0, item) for item in total_list]
})
self.move_id = move.id
else:
if self.employee_id.payment_method == 'bank':
journal = self.env['account.journal'].search([('type', '=', self.employee_id.payment_method)], limit=1)
if not journal:
raise UserError( ' There is no journal For that Bank..'
' Please define a sale journal')
else:
journal = self.contract_id.journal_id
for l in self.allowance_ids:
amount_allow = l.total
account = l.salary_rule_id.rule_debit_account_id
total_list.append({
'name': l.name,
'account_id': account.id,
'debit': amount_allow,
'partner_id': self.employee_id.user_id.partner_id.id
})
amount += amount_allow
total_allow += amount
for ded in self.deduction_ids:
amount_ded = -ded.total
account = ded.salary_rule_id.rule_credit_account_id
total_list.append({
'name': ded.name,
'account_id': account.id,
'credit': amount_ded,
'partner_id': self.employee_id.user_id.partner_id.id
})
amount1 += amount_ded
total_ded += amount1
for lo in self.loan_ids:
amount_loans = -lo.amount
total_list.append({
'name': lo.name + ' (' + lo.code + ')',
'account_id': lo.account_id.id,
'credit': amount_loans,
'partner_id': self.employee_id.user_id.partner_id.id
})
total_loan += amount_loans
# create line for total of all allowance, deduction, loans of one employee
total = total_allow - total_ded - total_loan
total_list.append({
'name': "Total",
'account_id': journal.id,
'partner_id': self.employee_id.user_id.partner_id.id,
'credit': total,
})
if not self.move_id:
move = self.env['account.move'].create({
'journal_id': journal.id,
# 'date': fields.Date.context_today(self),
'date': self.date_to,
'ref': self.name,
'line_ids': [(0, 0, item) for item in total_list]
})
self.move_id = move.id
self.write({'state': 'transfered'})
def compute_totals(self):
for item in self:
item.total_allowances = item.total_deductions = item.total_loans = 0.0
for line in item.allowance_ids:
allow_tot = line.total
item.total_allowances += allow_tot
for line in item.deduction_ids:
ded_tot = line.total
item.total_deductions += ded_tot
for line in item.loan_ids:
item.total_loans += line.amount
item.total_sum = item.total_allowances + item.total_deductions + item.total_loans
def get_inputs(self, contract_ids, date_from, date_to):
"""This Compute the other inputs to employee payslip."""
res = super(SalaryRuleInput, self).get_inputs(contract_ids, date_from, date_to)
contract_obj = self.env['hr.contract']
emp_id = contract_obj.browse(contract_ids[0].id).employee_id
adv_salary = self.env['salary.advance'].search([('employee_id', '=', emp_id.id)])
for adv_obj in adv_salary:
current_date = datetime.strptime(str(date_from), '%Y-%m-%d').date().month
date = adv_obj.date
existing_date = datetime.strptime(str(date), '%Y-%m-%d').date().month
if current_date == existing_date:
state = adv_obj.state
amount = adv_obj.advance
for result in res:
if state == 'approve' and amount != 0 and result.get('code') == 'SAR':
result['amount'] = amount
return res
# Override function compute sheet in employee payslips
def compute_sheet(self):
for payslip in self:
payslip_loans = []
amount = 0
flag = False
number = payslip.number or self.env['ir.sequence'].next_by_code('salary.slip')
# delete old payslip lines
payslip.line_ids.unlink()
# set the list of contract for which the rules have to be applied
# if we don't give the contract, then the rules to apply should be for all current contracts of the employee
contract_ids = payslip.contract_id.ids or \
self.get_contract(payslip.employee_id, payslip.date_from, payslip.date_to)
# lines = [(0, 0, line) for line in self._get_payslip_lines(contract_ids, payslip.id)]
# Holidays #
holidays = self.env['hr.holidays'].search([('employee_id', '=', payslip.employee_id.id),
('state', '=', 'validate1')]).filtered(
lambda item: item.employee_id.state == 'open')
contract = self.env['hr.contract'].search([('employee_id', '=', payslip.employee_id.id)])
localdict = dict(employee=payslip.employee_id.id, contract=contract)
number_of_days = 0
for line in payslip.worked_days_line_ids:
if line.name == 'Unpaid Holidays For this month':
line.unlink()
elif line.name == 'Paid Holidays By percentage':
line.unlink()
elif line.name == 'Additional Paid Holidays':
line.unlink()
elif line.name == 'Exclusion or Reconcile Paid Holidays':
line.unlink()
for holiday in holidays:
if holiday.date_from and holiday.date_to:
holiday_date_from = datetime.strptime(str(holiday.date_from), '%Y-%m-%d %H:%M:%S').strftime('%Y-%m-%d')
holiday_date_to = datetime.strptime(str(holiday.date_to), '%Y-%m-%d %H:%M:%S').strftime('%Y-%m-%d')
payslip_date_from = str(payslip.date_from)
payslip_date_to = str(payslip.date_to)
if payslip.holiday_start_date and payslip.holiday_end_date:
payslip_date_from = str(payslip.holiday_start_date)
payslip_date_to = str(payslip.holiday_end_date)
if holiday.holiday_status_id.payslip_type == 'unpaid':
if payslip_date_to >= holiday_date_to and holiday_date_from >= payslip_date_from:
payroll_start = datetime.strptime(payslip_date_from, "%Y-%m-%d").date()
pyroll_end = datetime.strptime(payslip_date_to, "%Y-%m-%d").date()
pyroll_days = relativedelta(pyroll_end, payroll_start).days + 1
number_of_days = holiday.number_of_days_temp
if number_of_days >=28:
if pyroll_days ==28:
number_of_days= number_of_days + 2
if pyroll_days ==29:
number_of_days= number_of_days + 1
if pyroll_days ==31:
number_of_days= number_of_days - 1
if holiday.number_of_days_temp >= 0: # if holiday.number_of_days_temp <= 0:
payslip.worked_days_line_ids = [fields.Command.create({
'name': "Unpaid Holidays For this month",
'sequence': 1,
'payslip_id': payslip.id,
'code': 'unpaid',
'number_of_days': number_of_days,
'number_of_hours': 0.0,
'contract_id': payslip.contract_id.id})]
elif holiday_date_from >= payslip_date_from and payslip_date_to <= holiday_date_to and holiday_date_from <= payslip_date_to:
payroll_start = datetime.strptime(payslip_date_from, "%Y-%m-%d").date()
pyroll_end = datetime.strptime(payslip_date_to, "%Y-%m-%d").date()
pyroll_days = relativedelta(pyroll_end, payroll_start).days + 1
start_date = datetime.strptime(str(holiday.date_from), "%Y-%m-%d").date()
end_date = datetime.strptime(str(payslip.date_to), "%Y-%m-%d").date()
number_of_days = relativedelta(end_date, start_date).days + 1
#if number_of_days >=28:
if pyroll_days ==28:
number_of_days= number_of_days + 2
if pyroll_days ==29:
number_of_days= number_of_days + 1
if pyroll_days ==31:
number_of_days= number_of_days - 1
if number_of_days >= 0: # number_of_days <= 0
payslip.worked_days_line_ids = [fields.Command.create({
'name': "Unpaid Holidays For this month",
'sequence': 1,
'payslip_id': payslip.id,
'code': 'unpaid',
'number_of_days': number_of_days,
'number_of_hours': 0.0,
'contract_id': payslip.contract_id.id})]
elif payslip_date_from >= holiday_date_from and payslip_date_to >= holiday_date_to and holiday_date_to >= payslip_date_from :
payroll_start = datetime.strptime(payslip_date_from, "%Y-%m-%d").date()
pyroll_end = datetime.strptime(payslip_date_to, "%Y-%m-%d").date()
pyroll_days = relativedelta(pyroll_end, payroll_start).days + 1
start_date = datetime.strptime(payslip_date_from, "%Y-%m-%d").date()
end_date = datetime.strptime(str(holiday.date_to), "%Y-%m-%d").date()
number_of_days = relativedelta(end_date, start_date).days +1
if number_of_days >=28:
if pyroll_days ==28:
number_of_days= number_of_days + 2
if pyroll_days ==29:
number_of_days= number_of_days + 1
if pyroll_days ==31:
number_of_days= number_of_days - 1
if number_of_days >= 0: # number_of_days <= 0
payslip.worked_days_line_ids = [fields.Command.create({
'name': "Unpaid Holidays For this month",
'sequence': 1,
'payslip_id': payslip.id,
'code': 'unpaid',
'number_of_days': number_of_days,
'number_of_hours': 0.0,
'contract_id': payslip.contract_id.id
})]
else:
if payslip_date_to <= holiday_date_to and holiday_date_from <= payslip_date_from:
#if payslip_date_to <= holiday_date_to:
start_date = datetime.strptime(str(payslip.date_from), "%Y-%m-%d").date()
end_date = datetime.strptime(str(payslip.date_to), "%Y-%m-%d").date()
number_of_days = relativedelta(end_date, start_date).days + 1
if number_of_days ==28:
number_of_days= number_of_days + 2
if number_of_days ==29:
number_of_days= number_of_days + 1
if number_of_days ==31:
number_of_days= number_of_days - 1
if number_of_days >= 0: # number_of_days <= 0
payslip.worked_days_line_ids = [fields.Command.create({
'name': "Unpaid Holidays For this month",
'sequence': 1,
'payslip_id': payslip.id,
'code': 'unpaid',
'number_of_days': number_of_days,
'number_of_hours': 0.0,
'contract_id': payslip.contract_id.id})]
elif holiday.holiday_status_id.payslip_type == 'percentage':
#if payslip.date_from >= holiday.date_from and payslip.date_to >= holiday.date_to:
if payslip_date_from >= holiday_date_from and payslip_date_to >= holiday_date_to:
start_date = datetime.strptime(payslip_date_from, "%Y-%m-%d").date()
end_date = datetime.strptime(holiday_date_to, "%Y-%m-%d").date() + timedelta(
days=1)
number_of_days = relativedelta(end_date, start_date).days
if number_of_days >= 0: # number_of_days <= 0
payslip.worked_days_line_ids = [fields.Command.create({
'name': "Paid Holidays By percentage",
'sequence': 1,
'payslip_id': payslip.id,
'code': 'percentage',
'number_of_days': number_of_days,
'number_of_hours': holiday.holiday_status_id.percentage,
'contract_id': payslip.contract_id.id})]
elif payslip_date_to >= holiday_date_to and holiday_date_from >= payslip_date_from:
if holiday.number_of_days_temp >= 0: # holiday.number_of_days_temp <= 0
payslip.worked_days_line_ids = [fields.Command.create({
'name': "Paid Holidays By percentage",
'sequence': 1,
'payslip_id': payslip.id,
'code': 'percentage',
'number_of_days': holiday.number_of_days_temp,
'number_of_hours': holiday.holiday_status_id.percentage,
'contract_id': payslip.contract_id.id})]
elif holiday_date_from >= payslip_date_from and payslip_date_to <= holiday_date_to:
start_date = datetime.strptime(holiday_date_from, "%Y-%m-%d").date()
end_date = datetime.strptime(payslip_date_to, "%Y-%m-%d").date()
number_of_days = relativedelta(end_date, start_date).days + 1
if number_of_days >= 0: # number_of_days <= 0
payslip.worked_days_line_ids = [fields.Command.create({
'name': "Paid Holidays By percentage",
'sequence': 1,
'payslip_id': payslip.id,
'code': 'percentage',
'number_of_days': number_of_days,
'number_of_hours': holiday.holiday_status_id.percentage,
'contract_id': payslip.contract_id.id})]
else:
if payslip_date_to <= holiday_date_to:
start_date = datetime.strptime(payslip_date_from, "%Y-%m-%d").date()
end_date = datetime.strptime(payslip_date_to, "%Y-%m-%d").date() + timedelta(
days=1)
number_of_days = relativedelta(end_date, start_date).days
if number_of_days >= 0: # number_of_days <= 0
payslip.worked_days_line_ids = [fields.Command.create({
'name': "Paid Holidays By percentage",
'sequence': 1,
'payslip_id': payslip.id,
'code': 'percentage',
'number_of_days': number_of_days,
'number_of_hours': holiday.holiday_status_id.percentage,
'contract_id': payslip.contract_id.id})]
elif holiday.holiday_status_id.payslip_type == 'addition':
if payslip_date_to >= holiday_date_to and holiday_date_from >= payslip_date_from:
payroll_start = datetime.strptime(payslip_date_from, "%Y-%m-%d").date()
pyroll_end = datetime.strptime(payslip_date_to, "%Y-%m-%d").date()
pyroll_days = relativedelta(pyroll_end, payroll_start).days + 1
number_of_days = holiday.number_of_days_temp
if number_of_days >= 28:
if pyroll_days == 28:
number_of_days = number_of_days + 2
if pyroll_days == 29:
number_of_days = number_of_days + 1
if pyroll_days == 31:
number_of_days = number_of_days - 1
if holiday.number_of_days_temp >= 0: # if holiday.number_of_days_temp <= 0:
payslip.worked_days_line_ids = [fields.Command.create({
'name': "Additional Paid Holidays",
'sequence': 1,
'payslip_id': payslip.id,
'code': 'addition',
'number_of_days': number_of_days,
'number_of_hours': 0.0,
'contract_id': payslip.contract_id.id})]
elif holiday_date_from >= payslip_date_from and payslip_date_to <= holiday_date_to and holiday_date_from <= payslip_date_to:
payroll_start = datetime.strptime(payslip_date_from, "%Y-%m-%d").date()
pyroll_end = datetime.strptime(payslip_date_to, "%Y-%m-%d").date()
pyroll_days = relativedelta(pyroll_end, payroll_start).days + 1
start_date = datetime.strptime(str(holiday.date_from), "%Y-%m-%d").date()
end_date = datetime.strptime(str(payslip.date_to), "%Y-%m-%d").date()
number_of_days = relativedelta(end_date, start_date).days + 1
# if number_of_days >=28:
if pyroll_days == 28:
number_of_days = number_of_days + 2
if pyroll_days == 29:
number_of_days = number_of_days + 1
if pyroll_days == 31:
number_of_days = number_of_days - 1
if number_of_days >= 0: # number_of_days <= 0
payslip.worked_days_line_ids = [fields.Command.create({
'name': "Additional Paid Holidays",
'sequence': 1,
'payslip_id': payslip.id,
'code': 'addition',
'number_of_days': number_of_days,
'number_of_hours': 0.0,
'contract_id': payslip.contract_id.id})]
elif payslip_date_from >= holiday_date_from and payslip_date_to >= holiday_date_to and holiday_date_to >= payslip_date_from:
payroll_start = datetime.strptime(payslip_date_from, "%Y-%m-%d").date()
pyroll_end = datetime.strptime(payslip_date_to, "%Y-%m-%d").date()
pyroll_days = relativedelta(pyroll_end, payroll_start).days + 1
start_date = datetime.strptime(payslip_date_from, "%Y-%m-%d").date()
end_date = datetime.strptime(str(holiday.date_to), "%Y-%m-%d %H:%M:%S").date()
number_of_days = relativedelta(end_date, start_date).days + 1
if number_of_days >= 28:
if pyroll_days == 28:
number_of_days = number_of_days + 2
if pyroll_days == 29:
number_of_days = number_of_days + 1
if pyroll_days == 31:
number_of_days = number_of_days - 1
if number_of_days >= 0: # number_of_days <= 0
payslip.worked_days_line_ids = [fields.Command.create({
'name': "Additional Paid Holidays",
'sequence': 1,
'payslip_id': payslip.id,
'code': 'addition',
'number_of_days': number_of_days,
'number_of_hours': 0.0,
'contract_id': payslip.contract_id.id
})]
else:
if payslip_date_to <= holiday_date_to and holiday_date_from <= payslip_date_from:
# if payslip_date_to <= holiday_date_to:
start_date = datetime.strptime(str(payslip.date_from), "%Y-%m-%d").date()
end_date = datetime.strptime(str(payslip.date_to), "%Y-%m-%d").date()
number_of_days = relativedelta(end_date, start_date).days + 1
if number_of_days == 28:
number_of_days = number_of_days + 2
if number_of_days == 29:
number_of_days = number_of_days + 1
if number_of_days == 31:
number_of_days = number_of_days - 1
if number_of_days >= 0: # number_of_days <= 0
payslip.worked_days_line_ids = [fields.Command.create({
'name': "Additional Paid Holidays",
'sequence': 1,
'payslip_id': payslip.id,
'code': 'addition',
'number_of_days': number_of_days,
'number_of_hours': 0.0,
'contract_id': payslip.contract_id.id})]
if payslip.worked_days_line_ids:
if number_of_days < 0 or holiday.number_of_days_temp < 0:
pass
else:
for line in holiday.holiday_status_id.salary_rules_ids:
if line.amount_select == 'fix':
for allowance in payslip.allowance_ids:
if line.name == allowance.name:
if line._compute_rule(localdict)[0] != allowance.amount:
amount = allowance.amount
else:
amount = line._compute_rule(localdict)[0]
else:
amount = line._compute_rule(localdict)[0]
for deduction in payslip.deduction_ids:
if line.name == deduction.name:
if line._compute_rule(localdict)[0] != deduction.amount:
amount = (-deduction.amount)
else:
amount = line._compute_rule(localdict)[0]
elif line.amount_select == 'percentage':
if line.related_benefits_discounts:
for li in line.related_benefits_discounts:
for allowance in payslip.allowance_ids:
if line.name == allowance.name:
if li._compute_rule(localdict)[0] != allowance.amount:
amount = allowance.amount
else:
amount = li._compute_rule(localdict)[0]
for deduction in payslip.deduction_ids:
if line.name == deduction.name:
if li._compute_rule(localdict)[0] != deduction.amount:
amount = (-deduction.amount)
else:
amount = li._compute_rule(localdict)[0]
else:
for allowance in payslip.allowance_ids:
if line.name == allowance.name:
if line._compute_rule(localdict)[0] != allowance.amount:
amount = allowance.amount
else:
amount = line._compute_rule(localdict)[0]
for deduction in payslip.deduction_ids:
if line.name == deduction.name:
if line._compute_rule(localdict)[0] != deduction.amount:
amount = (-deduction.amount)
else:
amount = line._compute_rule(localdict)[0]
# Update 29/07/2019
for allow in payslip.allowance_ids:
if line.name == allow.name:
allow.update({
'name': line.name,
'code': line.code,
'category_id': line.category_id.id,
'contract_id': payslip.contract_id.id,
'slip_id': payslip.id,
'quantity': 1,
'rate': 100,
'salary_rule_id': line.id,
'leave_request_case': True,
'amount': amount
})
for ded in payslip.deduction_ids:
if line.name == ded.name:
ded.update({
'name': line.name,
'code': line.code,
'category_id': line.category_id.id,
'contract_id': payslip.contract_id.id,
'slip_id': payslip.id,
'quantity': 1,
'rate': 100,
'salary_rule_id': line.id,
'leave_request_case': True,
'amount': -amount
})
elif holiday.holiday_status_id.payslip_type == 'exclusion' or (
holiday.holiday_status_id.payslip_type == 'reconcile' and holiday.reconcile_leave is True):
start_holiday = datetime.strptime(str(holiday_date_from), "%Y-%m-%d %H:%M:%S").date()
end_holiday = datetime.strptime(str(holiday_date_to), "%Y-%m-%d %H:%M:%S").date()
payroll_start = datetime.strptime(str(payslip_date_from), "%Y-%m-%d").date()
pyroll_end = datetime.strptime(str(payslip_date_to), "%Y-%m-%d").date()
if payslip.date_from >= start_holiday and payslip_date_to >= end_holiday and end_holiday >= payslip_date_from:
pyroll_days = relativedelta(pyroll_end, payroll_start).days + 1
number_of_days = relativedelta(end_holiday, payroll_start).days+ 1
if pyroll_days == 28:
number_of_days = number_of_days + 2
if pyroll_days == 29:
number_of_days = number_of_days + 1
if number_of_days >= 0: # number_of_days <= 0
payslip.worked_days_line_ids = [fields.Command.create({
'name': "Exclusion or Reconcile Paid Holidays",
'sequence': 2,
'payslip_id': payslip.id,
'code': 'exclusion',
'number_of_days': number_of_days,
'number_of_hours': 0.0,
'contract_id': payslip.contract_id.id})]
elif payslip.date_to >= end_holiday and start_holiday >= payslip.date_from:
pyroll_days = relativedelta(pyroll_end, payroll_start).days + 1
number_of_days = relativedelta(pyroll_end, start_holiday).days + 1
if pyroll_days == 28:
number_of_days = number_of_days + 2
if pyroll_days == 29:
number_of_days = number_of_days + 1
if pyroll_days == 31:
number_of_days = number_of_days - 1
if holiday.number_of_days_temp >= 0: # holiday.number_of_days_temp <= 0
payslip.worked_days_line_ids = [fields.Command.create({
'name': "Exclusion or Reconcile Paid Holidays",
'sequence': 2,
'payslip_id': payslip.id,
'code': 'exclusion',
'number_of_days': number_of_days,
'number_of_hours': 0.0,
'contract_id': payslip.contract_id.id})]
elif start_holiday >= payslip.date_from and payslip.date_to <= end_holiday and start_holiday <= payslip.date_to:
pyroll_days = relativedelta(pyroll_end, payroll_start).days + 1
number_of_days = relativedelta(pyroll_end, start_holiday).days + 1
if pyroll_days == 28:
number_of_days = number_of_days + 2
if pyroll_days == 29:
number_of_days = number_of_days + 1
if pyroll_days == 31:
number_of_days = number_of_days - 1
if number_of_days >= 0: # number_of_days <= 0
payslip.worked_days_line_ids = [fields.Command.create({
'name': "Exclusion or Reconcile Paid Holidays",
'sequence': 2,
'payslip_id': payslip.id,
'code': 'exclusion',
'number_of_days': number_of_days,
'number_of_hours': 0.0,
'contract_id': payslip.contract_id.id})]
else:
if payslip.date_to <= end_holiday and start_holiday <= payslip.date_from:
number_of_days = relativedelta(pyroll_end, payroll_start).days + 1
if number_of_days == 28:
number_of_days = number_of_days + 2
if number_of_days == 29:
number_of_days = number_of_days + 1
if number_of_days ==31:
number_of_days= number_of_days - 1
if number_of_days >= 0: # number_of_days <= 0
payslip.worked_days_line_ids = [fields.Command.create({
'name': "Exclusion or Reconcile Paid Holidays",
'sequence': 2,
'payslip_id': payslip.id,
'code': 'exclusion',
'number_of_days': number_of_days,
'number_of_hours': 0.0,
'contract_id': payslip.contract_id.id})]
if payslip.worked_days_line_ids:
for line in holiday.holiday_status_id.salary_rules_ids:
if line.amount_select == 'fix':
for allowance in payslip.allowance_ids:
if line.name == allowance.name:
if line._compute_rule(localdict)[0] != allowance.amount:
amount = allowance.amount
else:
amount = line._compute_rule(localdict)[0]
else:
amount = line._compute_rule(localdict)[0]
for deduction in payslip.deduction_ids:
if line.name == deduction.name:
if line._compute_rule(localdict)[0] != deduction.amount:
amount = (-deduction.amount)
else:
amount = line._compute_rule(localdict)[0]
elif line.amount_select == 'percentage':
if line.related_benefits_discounts:
for li in line.related_benefits_discounts:
for allowance in payslip.allowance_ids:
if line.name == allowance.name:
if li._compute_rule(localdict)[0] != allowance.amount:
amount = allowance.amount
else:
amount = li._compute_rule(localdict)[0]
for deduction in payslip.deduction_ids:
if line.name == deduction.name:
if li._compute_rule(localdict)[0] != deduction.amount:
amount = (-deduction.amount)
else:
amount = li._compute_rule(localdict)[0]
else:
for allowance in payslip.allowance_ids:
if line.name == allowance.name:
if line._compute_rule(localdict)[0] != allowance.amount:
amount = allowance.amount
else:
amount = line._compute_rule(localdict)[0]
for deduction in payslip.deduction_ids:
if line.name == deduction.name:
if line._compute_rule(localdict)[0] != deduction.amount:
amount = (-deduction.amount)
else:
amount = line._compute_rule(localdict)[0]
for allow in payslip.allowance_ids:
if line.name == allow.name:
allow.update({
'name': line.name,
'code': line.code,
'category_id': line.category_id.id,
'contract_id': payslip.contract_id.id,
'slip_id': payslip.id,
'quantity': 1,
'rate': 100,
'salary_rule_id': line.id,
'leave_request_case': True,
'amount': amount
})
for ded in payslip.deduction_ids:
if line.name == ded.name:
ded.update({
'name': line.name,
'code': line.code,
'category_id': line.category_id.id,
'contract_id': payslip.contract_id.id,
'slip_id': payslip.id,
'quantity': 1,
'rate': 100,
'salary_rule_id': line.id,
'leave_request_case': True,
'amount': -amount
})
lines = [(0, 0, line) for line in self._get_payslip_lines(contract_ids, payslip.id)]
payslip.write({'line_ids': lines, 'number': number, 'level_id': payslip.contract_id.salary_level.id,
'group_id': payslip.contract_id.salary_group.id,
'degree_id': payslip.contract_id.salary_degree.id, })
for line in payslip.line_ids:
if line.category_id.rule_type == 'allowance' or line.category_id.rule_type == 'deduction':
flag = True
if flag:
allowances = payslip.line_ids.filtered(
lambda a: a.amount != 0 and a.rate != 0 and a.category_id.rule_type == 'allowance')
payslip.allowance_ids = [fields.Command.set(allowances.ids)]
deductions = payslip.line_ids.filtered(
lambda a: a.amount != 0 and a.rate != 0 and a.category_id.rule_type == 'deduction')
for d in deductions:
if d.amount > 0:
d.amount = -d.amount
else:
d.amount = d.amount
payslip.deduction_ids = [fields.Command.set(deductions.ids)]
if 'hr.loan.salary.advance' in self.env:
loans = self.env['hr.loan.salary.advance'].search([('employee_id', '=', payslip.employee_id.id),
('request_type.refund_from', '=', 'salary'),
('state', '=', 'pay')]).filtered(
lambda item: item.employee_id.state == 'open')
if loans:
for loan in loans:
for l in loan.deduction_lines:
if not l.paid and (
str(l.installment_date) <= str(payslip.date_from) or str(l.installment_date) <= str(
payslip.date_to)):
employee_loan_id = payslip.loan_ids.filtered(
lambda item: item.name == loan.request_type.name)
if not employee_loan_id:
payslip_loans.append({
'name': loan.request_type.name,
'code': loan.code,
'amount': round((-l.installment_amount), 2),
'date': l.installment_date,
'account_id': loan.request_type.account_id.id,
'loan_id': loan.id
})
l.paid = True
l.payment_date = payslip.date_to
else:
payslip.loan_ids = [(0, 0, loan_item) for loan_item in payslip_loans]
# check remaining loan and change state to closed
if loan.remaining_loan_amount <= 0.0 < loan.gm_propos_amount:
loan.state = 'closed'
payslip.loan_ids = [(0, 0, loan_item) for loan_item in payslip_loans]
payslip.allowance_ids._compute_total()
payslip.deduction_ids._compute_total()
for pay in payslip:
if pay.total_sum < 0:
raise UserError(_("Salary is less than 0 this month for the following employees \n %s") % (
pay.employee_id.name))
self.write({'state': 'computed'})
return True
# Override function get_payslip_lines
@api.model
def _get_payslip_lines(self, contract_ids, payslip_id):
def _sum_salary_rule_category(localdict, category, amount):
if category.parent_id:
localdict = _sum_salary_rule_category(localdict, category.parent_id, amount)
localdict['categories'].dict[category.code] = category.code in localdict['categories'].dict and \
localdict['categories'].dict[category.code] + amount or amount
return localdict
class BrowsableObject(object):
def __init__(self, employee_id, dict, env):
self.employee_id = employee_id
self.dict = dict
self.env = env
def __getattr__(self, attr):
return attr in self.dict and self.dict.__getitem__(attr) or 0.0
class InputLine(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(amount) as sum
FROM hr_payslip as hp, hr_payslip_input as pi
WHERE hp.employee_id = %s AND hp.state = 'done'
AND hp.date_from >= %s AND hp.date_to <= %s AND hp.id = pi.payslip_id AND pi.code = %s""",
(self.employee_id, from_date, to_date, code))
return self.env.cr.fetchone()[0] or 0.0
class WorkedDays(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(number_of_days) as number_of_days, sum(number_of_hours) as number_of_hours
FROM hr_payslip as hp, hr_payslip_worked_days as pi
WHERE hp.employee_id = %s AND hp.state = 'done'
AND hp.date_from >= %s AND hp.date_to <= %s AND hp.id = pi.payslip_id AND pi.code = %s""",
(self.employee_id, from_date, to_date, code))
return self.env.cr.fetchone()
def sum(self, code, from_date, to_date=None):
res = self._sum(code, from_date, to_date)
return res and res[0] or 0.0
def sum_hours(self, code, from_date, to_date=None):
res = self._sum(code, from_date, to_date)
return res and res[1] 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
# we keep a dict with the result because a value can be overwritten by another rule with the same code
result_dict, rules_dict, worked_days_dict, inputs_dict = {}, {}, {}, {}
blacklist = []
payslip = self.env['hr.payslip'].browse(payslip_id)
for worked_days_line in payslip.worked_days_line_ids:
worked_days_dict[worked_days_line.code] = worked_days_line
for input_line in payslip.input_line_ids:
inputs_dict[input_line.code] = input_line
categories = BrowsableObject(payslip.employee_id.id, {}, self.env)
inputs = InputLine(payslip.employee_id.id, inputs_dict, self.env)
worked_days = WorkedDays(payslip.employee_id.id, worked_days_dict, self.env)
payslips = Payslips(payslip.employee_id.id, payslip, self.env)
rules = BrowsableObject(payslip.employee_id.id, rules_dict, self.env)
baselocaldict = {'categories': categories, 'rules': rules, 'payslip': payslips, 'worked_days': worked_days,
'inputs': inputs}
# get the ids of the structures on the contracts and their parent id as well
contracts = self.env['hr.contract'].browse(contract_ids)
if len(contracts) == 1 and payslip.struct_id:
structure_ids = list(set(payslip.contract_id.salary_scale.ids))
else:
structure_ids = contracts.get_all_structures()
# get the rules of the structure and their children
rule_ids = self.env['hr.payroll.structure'].browse(structure_ids).get_all_rules()
# run the rules by sequence
sorted_rule_ids = [id for id, sequence in sorted(rule_ids, key=lambda x: x[1])]
sorted_rules = self.env['hr.salary.rule'].browse(sorted_rule_ids)
for contract in contracts:
employee = contract.employee_id
localdict = dict(baselocaldict, payslip=payslip, employee=employee, contract=contract)
if contract.contractor_type.salary_type == 'scale':
for rule in sorted_rules:
key1 = rule.code + '-' + str(contract.id)
localdict['result'] = None
localdict['result_qty'] = 1.0
localdict['result_rate'] = 100
# check if the rule can be applied
if rule._satisfy_condition(localdict) and rule.id not in blacklist:
if payslip.contract_id.advantages:
for advantage_rule in payslip.contract_id.advantages:
date1 = datetime.strptime(str(advantage_rule.date_from), "%Y-%m-%d")
key = str(advantage_rule.benefits_discounts.code) + '-' + str(contract.id)
if advantage_rule.date_to:
date2 = datetime.strptime(str(advantage_rule.date_to), "%Y-%m-%d")
if (datetime.strptime(str(payslip.date_from), "%Y-%m-%d") >= date1
and date2 >= datetime.strptime(str(payslip.date_to), "%Y-%m-%d")) \
or date2 >= datetime.strptime(str(payslip.date_from), "%Y-%m-%d") >= date1 \
or date2 >= datetime.strptime(str(payslip.date_to), "%Y-%m-%d") >= date1 \
or (datetime.strptime(str(payslip.date_to), "%Y-%m-%d") >= date1
and date2 >= datetime.strptime(str(payslip.date_from), "%Y-%m-%d")):
if advantage_rule.benefits_discounts and advantage_rule.benefits_discounts.name not in sorted_rules:
amount, qty, rate = rule._compute_rule(localdict)
previous_amount = rule.code in localdict and localdict[
rule.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[rule.code] = tot_rule
rules_dict[rule.code] = rule
localdict = _sum_salary_rule_category(localdict, rule.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
if amount != 0:
result_dict[key1] = {
'salary_rule_id': rule.id,
'contract_id': contract.id,
'name': rule.name,
'code': rule.code,
'category_id': rule.category_id.id,
'amount_select': rule.amount_select,
'amount_fix': rule.amount_fix,
'amount_python_compute': rule.amount_python_compute,
'amount_percentage': rule.amount_percentage,
'register_id': rule.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
if advantage_rule.type == 'customize':
amount = advantage_rule.amount
qty, rate = 1, 100.0
previous_amount = advantage_rule.benefits_discounts.code in localdict and \
localdict[
advantage_rule.benefits_discounts.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[advantage_rule.benefits_discounts.code] = tot_rule
rules_dict[advantage_rule.benefits_discounts.code] = advantage_rule
# sum the amount for its salary category
localdict = _sum_salary_rule_category(localdict,
advantage_rule.benefits_discounts.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
result_dict[key] = {
'salary_rule_id': advantage_rule.benefits_discounts.id,
'contract_id': contract.id,
'name': advantage_rule.benefits_discounts.name,
'code': advantage_rule.benefits_discounts.code,
'category_id': advantage_rule.benefits_discounts.category_id.id,
'amount_select': advantage_rule.benefits_discounts.amount_select,
'amount_fix': advantage_rule.benefits_discounts.amount_fix,
'amount_python_compute': advantage_rule.benefits_discounts.amount_python_compute,
'amount_percentage': advantage_rule.benefits_discounts.amount_percentage,
'register_id': advantage_rule.benefits_discounts.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
elif advantage_rule.type == 'exception':
total = advantage_rule.benefits_discounts._compute_rule(localdict)[0]
if total == advantage_rule.amount or total == 0.0:
amount, qty, rate = 0.0, 0, 0.0
previous_amount = advantage_rule.benefits_discounts.code in localdict and \
localdict[
advantage_rule.benefits_discounts.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[advantage_rule.benefits_discounts.code] = tot_rule
rules_dict[advantage_rule.benefits_discounts.code] = advantage_rule
# sum the amount for its salary category
localdict = _sum_salary_rule_category(localdict,
advantage_rule.benefits_discounts.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
result_dict[key] = {
'salary_rule_id': advantage_rule.benefits_discounts.id,
'contract_id': contract.id,
'name': advantage_rule.benefits_discounts.name,
'code': advantage_rule.benefits_discounts.code,
'category_id': advantage_rule.benefits_discounts.category_id.id,
'amount_select': advantage_rule.benefits_discounts.amount_select,
'amount_fix': advantage_rule.benefits_discounts.amount_fix,
'amount_python_compute': advantage_rule.benefits_discounts.amount_python_compute,
'amount_percentage': advantage_rule.benefits_discounts.amount_percentage,
'register_id': advantage_rule.benefits_discounts.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
elif total <= advantage_rule.amount:
raise UserError(
_(
'The amount you put is greater than fact value of this Salary rule'))
else:
amount = total - advantage_rule.amount # update 21/04/2019
qty, rate = 1, 100.0
previous_amount = advantage_rule.benefits_discounts.code in localdict and \
localdict[
advantage_rule.benefits_discounts.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[advantage_rule.benefits_discounts.code] = tot_rule
rules_dict[advantage_rule.benefits_discounts.code] = advantage_rule
# sum the amount for its salary category
localdict = _sum_salary_rule_category(localdict,
advantage_rule.benefits_discounts.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
result_dict[key] = {
'salary_rule_id': advantage_rule.benefits_discounts.id,
'contract_id': contract.id,
'name': advantage_rule.benefits_discounts.name,
'code': advantage_rule.benefits_discounts.code,
'category_id': advantage_rule.benefits_discounts.category_id.id,
'amount_select': advantage_rule.benefits_discounts.amount_select,
'amount_fix': advantage_rule.benefits_discounts.amount_fix,
'amount_python_compute': advantage_rule.benefits_discounts.amount_python_compute,
'amount_percentage': advantage_rule.benefits_discounts.amount_percentage,
'register_id': advantage_rule.benefits_discounts.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
advantage_rule.done = False
else:
amount, qty, rate = rule._compute_rule(localdict)
previous_amount = rule.code in localdict and localdict[rule.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[rule.code] = tot_rule
rules_dict[rule.code] = rule
localdict = _sum_salary_rule_category(localdict, rule.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
if amount != 0:
result_dict[key1] = {
'salary_rule_id': rule.id,
'contract_id': contract.id,
'name': rule.name,
'code': rule.code,
'category_id': rule.category_id.id,
'amount_select': rule.amount_select,
'amount_fix': rule.amount_fix,
'amount_python_compute': rule.amount_python_compute,
'amount_percentage': rule.amount_percentage,
'register_id': rule.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
else:
if date2 <= datetime.strptime(str(payslip.date_from), "%Y-%m-%d"):
amount, qty, rate = rule._compute_rule(localdict)
previous_amount = rule.code in localdict and localdict[rule.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[rule.code] = tot_rule
rules_dict[rule.code] = rule
localdict = _sum_salary_rule_category(localdict, rule.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
if amount != 0:
result_dict[key1] = {
'salary_rule_id': rule.id,
'contract_id': contract.id,
'name': rule.name,
'code': rule.code,
'category_id': rule.category_id.id,
'amount_select': rule.amount_select,
'amount_fix': rule.amount_fix,
'amount_python_compute': rule.amount_python_compute,
'amount_percentage': rule.amount_percentage,
'register_id': rule.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
else:
if date1 <= datetime.strptime(str(payslip.date_from),
"%Y-%m-%d") or date1 <= datetime.strptime(
str(payslip.date_to), "%Y-%m-%d"):
if advantage_rule.benefits_discounts.name not in sorted_rules:
amount, qty, rate = rule._compute_rule(localdict)
previous_amount = rule.code in localdict and localdict[rule.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[rule.code] = tot_rule
rules_dict[rule.code] = rule
localdict = _sum_salary_rule_category(localdict, rule.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
if amount != 0:
result_dict[key1] = {
'salary_rule_id': rule.id,
'contract_id': contract.id,
'name': rule.name,
'code': rule.code,
'category_id': rule.category_id.id,
'amount_select': rule.amount_select,
'amount_fix': rule.amount_fix,
'amount_python_compute': rule.amount_python_compute,
'amount_percentage': rule.amount_percentage,
'register_id': rule.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
# To Doooooooooooooo #if
# if rule.name == advantage_rule.benefits_discounts.name:
if advantage_rule.type == 'customize':
amount = advantage_rule.amount
qty, rate = 1, 100.0
previous_amount = advantage_rule.benefits_discounts.code in localdict and \
localdict[
advantage_rule.benefits_discounts.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[advantage_rule.benefits_discounts.code] = tot_rule
rules_dict[advantage_rule.benefits_discounts.code] = advantage_rule
# sum the amount for its salary category
localdict = _sum_salary_rule_category(localdict,
advantage_rule.benefits_discounts.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
result_dict[key] = {
'salary_rule_id': advantage_rule.benefits_discounts.id,
'contract_id': contract.id,
'name': advantage_rule.benefits_discounts.name,
'code': advantage_rule.benefits_discounts.code,
'category_id': advantage_rule.benefits_discounts.category_id.id,
'amount_select': advantage_rule.benefits_discounts.amount_select,
'amount_fix': advantage_rule.benefits_discounts.amount_fix,
'amount_python_compute': advantage_rule.benefits_discounts.amount_python_compute,
'amount_percentage': advantage_rule.benefits_discounts.amount_percentage,
'register_id': advantage_rule.benefits_discounts.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
elif advantage_rule.type == 'exception':
total = advantage_rule.benefits_discounts._compute_rule(localdict)[
0]
if total == advantage_rule.amount or total == 0.0:
amount, qty, rate = 0.0, 0, 0.0
previous_amount = advantage_rule.benefits_discounts.code in localdict and \
localdict[
advantage_rule.benefits_discounts.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[advantage_rule.benefits_discounts.code] = tot_rule
rules_dict[
advantage_rule.benefits_discounts.code] = advantage_rule
# sum the amount for its salary category
localdict = _sum_salary_rule_category(localdict,
advantage_rule.benefits_discounts.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
result_dict[key] = {
'salary_rule_id': advantage_rule.benefits_discounts.id,
'contract_id': contract.id,
'name': advantage_rule.benefits_discounts.name,
'code': advantage_rule.benefits_discounts.code,
'category_id': advantage_rule.benefits_discounts.category_id.id,
'amount_select': advantage_rule.benefits_discounts.amount_select,
'amount_fix': advantage_rule.benefits_discounts.amount_fix,
'amount_python_compute': advantage_rule.benefits_discounts.amount_python_compute,
'amount_percentage': advantage_rule.benefits_discounts.amount_percentage,
'register_id': advantage_rule.benefits_discounts.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
elif total <= advantage_rule.amount:
raise UserError(
_(
'The amount you put is greater than fact value of this Salary rule'))
else:
amount = total - advantage_rule.amount # update 21/04/2019
qty, rate = 1, 100.0
previous_amount = advantage_rule.benefits_discounts.code in localdict and \
localdict[
advantage_rule.benefits_discounts.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[advantage_rule.benefits_discounts.code] = tot_rule
rules_dict[
advantage_rule.benefits_discounts.code] = advantage_rule
# sum the amount for its salary category
localdict = _sum_salary_rule_category(localdict,
advantage_rule.benefits_discounts.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
result_dict[key] = {
'salary_rule_id': advantage_rule.benefits_discounts.id,
'contract_id': contract.id,
'name': advantage_rule.benefits_discounts.name,
'code': advantage_rule.benefits_discounts.code,
'category_id': advantage_rule.benefits_discounts.category_id.id,
'amount_select': advantage_rule.benefits_discounts.amount_select,
'amount_fix': advantage_rule.benefits_discounts.amount_fix,
'amount_python_compute': advantage_rule.benefits_discounts.amount_python_compute,
'amount_percentage': advantage_rule.benefits_discounts.amount_percentage,
'register_id': advantage_rule.benefits_discounts.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
else:
amount, qty, rate = rule._compute_rule(localdict)
previous_amount = rule.code in localdict and localdict[rule.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[rule.code] = tot_rule
rules_dict[rule.code] = rule
localdict = _sum_salary_rule_category(localdict, rule.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
if amount != 0:
result_dict[key1] = {
'salary_rule_id': rule.id,
'contract_id': contract.id,
'name': rule.name,
'code': rule.code,
'category_id': rule.category_id.id,
'amount_select': rule.amount_select,
'amount_fix': rule.amount_fix,
'amount_python_compute': rule.amount_python_compute,
'amount_percentage': rule.amount_percentage,
'register_id': rule.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
advantage_rule.write({'done': True})
else:
amount, qty, rate = rule._compute_rule(localdict)
previous_amount = rule.code in localdict and localdict[rule.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[rule.code] = tot_rule
rules_dict[rule.code] = rule
localdict = _sum_salary_rule_category(localdict, rule.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
if amount != 0:
result_dict[key1] = {
'salary_rule_id': rule.id,
'contract_id': contract.id,
'name': rule.name,
'code': rule.code,
'category_id': rule.category_id.id,
'amount_select': rule.amount_select,
'amount_fix': rule.amount_fix,
'amount_python_compute': rule.amount_python_compute,
'amount_percentage': rule.amount_percentage,
'register_id': rule.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
else:
blacklist += [id for id, seq in rule._recursive_search_of_rules()]
if payslip.contract_id.salary_level.benefits_discounts_ids:
level_structure_ids = list(set(payslip.contract_id.salary_level.ids))
level_rule_ids = self.env['hr.payroll.structure'].browse(level_structure_ids).get_all_rules()
level_sorted_rule_ids = [id for id, sequence in sorted(level_rule_ids, key=lambda x: x[1])]
level_sorted_rules = self.env['hr.salary.rule'].browse(level_sorted_rule_ids)
for rule in level_sorted_rules:
key = rule.code + '-' + str(contract.id)
localdict['result'] = None
localdict['result_qty'] = 1.0
localdict['result_rate'] = 100
# check if the rule can be applied
if rule._satisfy_condition(localdict) and rule.id not in blacklist:
amount, qty, rate = rule._compute_rule(localdict)
if qty == 0:
qty = 1
previous_amount = rule.code in localdict and localdict[rule.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[rule.code] = tot_rule
rules_dict[rule.code] = rule
localdict = _sum_salary_rule_category(localdict, rule.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
result_dict[key] = {
'salary_rule_id': rule.id,
'contract_id': contract.id,
'name': rule.name,
'code': rule.code,
'category_id': rule.category_id.id,
'amount_select': rule.amount_select,
'amount_fix': rule.amount_fix,
'amount_python_compute': rule.amount_python_compute,
'amount_percentage': rule.amount_percentage,
'register_id': rule.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
for advantage_rule in payslip.contract_id.advantages:
if advantage_rule.benefits_discounts.name == rule.name:
if advantage_rule.type == 'customize':
amount = advantage_rule.amount + amount
qty, rate = 1, 100.0
previous_amount = advantage_rule.benefits_discounts.code in localdict and \
localdict[
advantage_rule.benefits_discounts.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[advantage_rule.benefits_discounts.code] = tot_rule
rules_dict[advantage_rule.benefits_discounts.code] = advantage_rule
# sum the amount for its salary category
localdict = _sum_salary_rule_category(localdict,
advantage_rule.benefits_discounts.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
result_dict[key] = {
'salary_rule_id': advantage_rule.benefits_discounts.id,
'contract_id': contract.id,
'name': advantage_rule.benefits_discounts.name,
'code': advantage_rule.benefits_discounts.code,
'category_id': advantage_rule.benefits_discounts.category_id.id,
'amount_select': advantage_rule.benefits_discounts.amount_select,
'amount_fix': advantage_rule.benefits_discounts.amount_fix,
'amount_python_compute': advantage_rule.benefits_discounts.amount_python_compute,
'amount_percentage': advantage_rule.benefits_discounts.amount_percentage,
'register_id': advantage_rule.benefits_discounts.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
if advantage_rule.type == 'exception':
total = advantage_rule.benefits_discounts._compute_rule(localdict)[0]
if total == advantage_rule.amount or total == 0.0:
amount, qty, rate = 0.0, 0, 0.0
previous_amount = advantage_rule.benefits_discounts.code in localdict and \
localdict[
advantage_rule.benefits_discounts.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[advantage_rule.benefits_discounts.code] = tot_rule
rules_dict[advantage_rule.benefits_discounts.code] = advantage_rule
# sum the amount for its salary category
localdict = _sum_salary_rule_category(localdict,
advantage_rule.benefits_discounts.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
result_dict[key] = {
'salary_rule_id': advantage_rule.benefits_discounts.id,
'contract_id': contract.id,
'name': advantage_rule.benefits_discounts.name,
'code': advantage_rule.benefits_discounts.code,
'category_id': advantage_rule.benefits_discounts.category_id.id,
'amount_select': advantage_rule.benefits_discounts.amount_select,
'amount_fix': advantage_rule.benefits_discounts.amount_fix,
'amount_python_compute': advantage_rule.benefits_discounts.amount_python_compute,
'amount_percentage': advantage_rule.benefits_discounts.amount_percentage,
'register_id': advantage_rule.benefits_discounts.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
elif total <= advantage_rule.amount:
raise UserError(
_(
'The amount you put is greater than fact value of this Salary rule'))
else:
amount = total - advantage_rule.amount # update 21/04/2019
qty, rate = 1, 100.0
previous_amount = advantage_rule.benefits_discounts.code in localdict and \
localdict[
advantage_rule.benefits_discounts.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[advantage_rule.benefits_discounts.code] = tot_rule
rules_dict[advantage_rule.benefits_discounts.code] = advantage_rule
# sum the amount for its salary category
localdict = _sum_salary_rule_category(localdict,
advantage_rule.benefits_discounts.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
result_dict[key] = {
'salary_rule_id': advantage_rule.benefits_discounts.id,
'contract_id': contract.id,
'name': advantage_rule.benefits_discounts.name,
'code': advantage_rule.benefits_discounts.code,
'category_id': advantage_rule.benefits_discounts.category_id.id,
'amount_select': advantage_rule.benefits_discounts.amount_select,
'amount_fix': advantage_rule.benefits_discounts.amount_fix,
'amount_python_compute': advantage_rule.benefits_discounts.amount_python_compute,
'amount_percentage': advantage_rule.benefits_discounts.amount_percentage,
'register_id': advantage_rule.benefits_discounts.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
else:
blacklist += [id for id, seq in rule._recursive_search_of_rules()]
if payslip.contract_id.salary_group.benefits_discounts_ids:
group_structure_ids = list(set(payslip.contract_id.salary_group.ids))
group_rule_ids = self.env['hr.payroll.structure'].browse(group_structure_ids).get_all_rules()
group_sorted_rule_ids = [id for id, sequence in sorted(group_rule_ids, key=lambda x: x[1])]
group_sorted_rules = self.env['hr.salary.rule'].browse(group_sorted_rule_ids)
for rule in group_sorted_rules:
key = rule.code + '-' + str(contract.id)
localdict['result'] = None
localdict['result_qty'] = 1.0
localdict['result_rate'] = 100
# check if the rule can be applied
if rule._satisfy_condition(localdict) and rule.id not in blacklist:
amount, qty, rate = rule._compute_rule(localdict)
previous_amount = rule.code in localdict and localdict[rule.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[rule.code] = tot_rule
rules_dict[rule.code] = rule
localdict = _sum_salary_rule_category(localdict, rule.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
result_dict[key] = {
'salary_rule_id': rule.id,
'contract_id': contract.id,
'name': rule.name,
'code': rule.code,
'category_id': rule.category_id.id,
'amount_select': rule.amount_select,
'amount_fix': rule.amount_fix,
'amount_python_compute': rule.amount_python_compute,
'amount_percentage': rule.amount_percentage,
'register_id': rule.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
for advantage_rule in payslip.contract_id.advantages:
if advantage_rule.benefits_discounts.name == rule.name:
if advantage_rule.type == 'customize':
amount = advantage_rule.amount + amount
qty, rate = 1, 100.0
previous_amount = advantage_rule.benefits_discounts.code in localdict and \
localdict[
advantage_rule.benefits_discounts.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[advantage_rule.benefits_discounts.code] = tot_rule
rules_dict[advantage_rule.benefits_discounts.code] = advantage_rule
# sum the amount for its salary category
localdict = _sum_salary_rule_category(localdict,
advantage_rule.benefits_discounts.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
result_dict[key] = {
'salary_rule_id': advantage_rule.benefits_discounts.id,
'contract_id': contract.id,
'name': advantage_rule.benefits_discounts.name,
'code': advantage_rule.benefits_discounts.code,
'category_id': advantage_rule.benefits_discounts.category_id.id,
'amount_select': advantage_rule.benefits_discounts.amount_select,
'amount_fix': advantage_rule.benefits_discounts.amount_fix,
'amount_python_compute': advantage_rule.benefits_discounts.amount_python_compute,
'amount_percentage': advantage_rule.benefits_discounts.amount_percentage,
'register_id': advantage_rule.benefits_discounts.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
if advantage_rule.type == 'exception':
total = advantage_rule.benefits_discounts._compute_rule(localdict)[0]
if total == advantage_rule.amount or total == 0.0:
amount, qty, rate = 0.0, 0, 0.0
previous_amount = advantage_rule.benefits_discounts.code in localdict and \
localdict[
advantage_rule.benefits_discounts.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[advantage_rule.benefits_discounts.code] = tot_rule
rules_dict[advantage_rule.benefits_discounts.code] = advantage_rule
# sum the amount for its salary category
localdict = _sum_salary_rule_category(localdict,
advantage_rule.benefits_discounts.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
result_dict[key] = {
'salary_rule_id': advantage_rule.benefits_discounts.id,
'contract_id': contract.id,
'name': advantage_rule.benefits_discounts.name,
'code': advantage_rule.benefits_discounts.code,
'category_id': advantage_rule.benefits_discounts.category_id.id,
'amount_select': advantage_rule.benefits_discounts.amount_select,
'amount_fix': advantage_rule.benefits_discounts.amount_fix,
'amount_python_compute': advantage_rule.benefits_discounts.amount_python_compute,
'amount_percentage': advantage_rule.benefits_discounts.amount_percentage,
'register_id': advantage_rule.benefits_discounts.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
elif total <= advantage_rule.amount:
raise UserError(
_(
'The amount you put is greater than fact value of this Salary rule'))
else:
amount = total - advantage_rule.amount # update 21/04/2019
qty, rate = 1, 100.0
previous_amount = advantage_rule.benefits_discounts.code in localdict and \
localdict[
advantage_rule.benefits_discounts.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[advantage_rule.benefits_discounts.code] = tot_rule
rules_dict[advantage_rule.benefits_discounts.code] = advantage_rule
# sum the amount for its salary category
localdict = _sum_salary_rule_category(localdict,
advantage_rule.benefits_discounts.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
result_dict[key] = {
'salary_rule_id': advantage_rule.benefits_discounts.id,
'contract_id': contract.id,
'name': advantage_rule.benefits_discounts.name,
'code': advantage_rule.benefits_discounts.code,
'category_id': advantage_rule.benefits_discounts.category_id.id,
'amount_select': advantage_rule.benefits_discounts.amount_select,
'amount_fix': advantage_rule.benefits_discounts.amount_fix,
'amount_python_compute': advantage_rule.benefits_discounts.amount_python_compute,
'amount_percentage': advantage_rule.benefits_discounts.amount_percentage,
'register_id': advantage_rule.benefits_discounts.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
else:
blacklist += [id for id, seq in rule._recursive_search_of_rules()]
else:
advantage_list = []
for advantage_rule in payslip.contract_id.advantages:
advantage_list.append(advantage_rule.benefits_discounts.id)
for rule in sorted_rules:
key1 = rule.code + '-' + str(contract.id)
localdict['result'] = None
localdict['result_qty'] = 1.0
localdict['result_rate'] = 100
# check if the rule can be applied
if rule._satisfy_condition(localdict) and rule.id not in blacklist:
if payslip.contract_id.advantages:
for advantage_rule in payslip.contract_id.advantages:
key = advantage_rule.benefits_discounts.code + '-' + str(contract.id)
date1 = datetime.strptime(str(advantage_rule.date_from), "%Y-%m-%d")
if advantage_rule.benefits_discounts.name == rule.name:
if advantage_rule.date_to:
date2 = datetime.strptime(str(advantage_rule.date_to), "%Y-%m-%d")
if (datetime.strptime(str(payslip.date_from),
"%Y-%m-%d") >= date1 and date2 >= datetime.strptime(
str(payslip.date_to), "%Y-%m-%d")) \
or date2 >= datetime.strptime(str(payslip.date_from),
"%Y-%m-%d") >= date1 \
or date2 >= datetime.strptime(str(payslip.date_to), "%Y-%m-%d") >= date1 \
or (datetime.strptime(str(payslip.date_to),
"%Y-%m-%d") >= date1 and date2 >= datetime.strptime(
str(payslip.date_from), "%Y-%m-%d")):
if advantage_rule.type == 'customize':
amount = advantage_rule.amount
qty, rate = 1, 100.0
previous_amount = advantage_rule.benefits_discounts.code in localdict and \
localdict[
advantage_rule.benefits_discounts.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[advantage_rule.benefits_discounts.code] = tot_rule
rules_dict[advantage_rule.benefits_discounts.code] = advantage_rule
# sum the amount for its salary category
localdict = _sum_salary_rule_category(localdict,
advantage_rule.benefits_discounts.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
result_dict[key] = {
'salary_rule_id': advantage_rule.benefits_discounts.id,
'contract_id': contract.id,
'name': advantage_rule.benefits_discounts.name,
'code': advantage_rule.benefits_discounts.code,
'category_id': advantage_rule.benefits_discounts.category_id.id,
'amount_select': advantage_rule.benefits_discounts.amount_select,
'amount_fix': advantage_rule.benefits_discounts.amount_fix,
'amount_python_compute': advantage_rule.benefits_discounts.amount_python_compute,
'amount_percentage': advantage_rule.benefits_discounts.amount_percentage,
'register_id': advantage_rule.benefits_discounts.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
elif advantage_rule.type == 'exception':
total = advantage_rule.benefits_discounts._compute_rule(localdict)[
0] # update 21/04/2019
if total == advantage_rule.amount or total == 0.0:
amount, qty, rate = 0.0, 0, 0.0
previous_amount = advantage_rule.benefits_discounts.code in localdict and \
localdict[
advantage_rule.benefits_discounts.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[advantage_rule.benefits_discounts.code] = tot_rule
rules_dict[advantage_rule.benefits_discounts.code] = advantage_rule
localdict = _sum_salary_rule_category(localdict,
advantage_rule.benefits_discounts.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
result_dict[key] = {
'salary_rule_id': advantage_rule.benefits_discounts.id,
'contract_id': contract.id,
'name': advantage_rule.benefits_discounts.name,
'code': advantage_rule.benefits_discounts.code,
'category_id': advantage_rule.benefits_discounts.category_id.id,
'amount_select': advantage_rule.benefits_discounts.amount_select,
'amount_fix': advantage_rule.benefits_discounts.amount_fix,
'amount_python_compute': advantage_rule.benefits_discounts.amount_python_compute,
'amount_percentage': advantage_rule.benefits_discounts.amount_percentage,
'register_id': advantage_rule.benefits_discounts.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
elif total <= advantage_rule.amount:
raise UserError(
_(
'The amount you put is greater than fact value of this Salary rule'))
else:
amount = total - advantage_rule.amount # update 21/04/2019
qty, rate = 1, 100.0
previous_amount = advantage_rule.benefits_discounts.code in localdict and \
localdict[
advantage_rule.benefits_discounts.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[advantage_rule.benefits_discounts.code] = tot_rule
rules_dict[advantage_rule.benefits_discounts.code] = advantage_rule
# sum the amount for its salary category
localdict = _sum_salary_rule_category(localdict,
advantage_rule.benefits_discounts.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
result_dict[key] = {
'salary_rule_id': advantage_rule.benefits_discounts.id,
'contract_id': contract.id,
'name': advantage_rule.benefits_discounts.name,
'code': advantage_rule.benefits_discounts.code,
'category_id': advantage_rule.benefits_discounts.category_id.id,
'amount_select': advantage_rule.benefits_discounts.amount_select,
'amount_fix': advantage_rule.benefits_discounts.amount_fix,
'amount_python_compute': advantage_rule.benefits_discounts.amount_python_compute,
'amount_percentage': advantage_rule.benefits_discounts.amount_percentage,
'register_id': advantage_rule.benefits_discounts.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
else:
amount, qty, rate = rule._compute_rule(localdict)
previous_amount = rule.code in localdict and localdict[rule.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[rule.code] = tot_rule
rules_dict[rule.code] = rule
localdict = _sum_salary_rule_category(localdict, rule.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
if amount != 0:
result_dict[key1] = {
'salary_rule_id': rule.id,
'contract_id': contract.id,
'name': rule.name,
'code': rule.code,
'category_id': rule.category_id.id,
'amount_select': rule.amount_select,
'amount_fix': rule.amount_fix,
'amount_python_compute': rule.amount_python_compute,
'amount_percentage': rule.amount_percentage,
'register_id': rule.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
else:
if date1 <= datetime.strptime(str(payslip.date_from), "%Y-%m-%d"):
if advantage_rule.benefits_discounts.name in sorted_rules:
if advantage_rule.type == 'customize':
amount = advantage_rule.amount
qty, rate = 1, 100.0
previous_amount = advantage_rule.benefits_discounts.code in localdict and \
localdict[
advantage_rule.benefits_discounts.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[advantage_rule.benefits_discounts.code] = tot_rule
rules_dict[advantage_rule.benefits_discounts.code] = advantage_rule
# sum the amount for its salary category
localdict = _sum_salary_rule_category(localdict,
advantage_rule.benefits_discounts.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
result_dict[key] = {
'salary_rule_id': advantage_rule.benefits_discounts.id,
'contract_id': contract.id,
'name': advantage_rule.benefits_discounts.name,
'code': advantage_rule.benefits_discounts.code,
'category_id': advantage_rule.benefits_discounts.category_id.id,
'amount_select': advantage_rule.benefits_discounts.amount_select,
'amount_fix': advantage_rule.benefits_discounts.amount_fix,
'amount_python_compute': advantage_rule.benefits_discounts.amount_python_compute,
'amount_percentage': advantage_rule.benefits_discounts.amount_percentage,
'register_id': advantage_rule.benefits_discounts.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
elif advantage_rule.type == 'exception':
total = advantage_rule.benefits_discounts._compute_rule(localdict)[
0]
if total == advantage_rule.amount or total == 0.0:
amount, qty, rate = 0.0, 0, 0.0
previous_amount = advantage_rule.benefits_discounts.code in localdict and \
localdict[
advantage_rule.benefits_discounts.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[advantage_rule.benefits_discounts.code] = tot_rule
rules_dict[
advantage_rule.benefits_discounts.code] = advantage_rule
# sum the amount for its salary category
localdict = _sum_salary_rule_category(localdict,
advantage_rule.benefits_discounts.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
result_dict[key] = {
'salary_rule_id': advantage_rule.benefits_discounts.id,
'contract_id': contract.id,
'name': advantage_rule.benefits_discounts.name,
'code': advantage_rule.benefits_discounts.code,
'category_id': advantage_rule.benefits_discounts.category_id.id,
'amount_select': advantage_rule.benefits_discounts.amount_select,
'amount_fix': advantage_rule.benefits_discounts.amount_fix,
'amount_python_compute': advantage_rule.benefits_discounts.amount_python_compute,
'amount_percentage': advantage_rule.benefits_discounts.amount_percentage,
'register_id': advantage_rule.benefits_discounts.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
elif total <= advantage_rule.amount:
raise UserError(
_(
'The amount you put is greater than fact value of this Salary rule'))
else:
amount = total - advantage_rule.amount # update 21/04/2019
qty, rate = 1, 100.0
previous_amount = advantage_rule.benefits_discounts.code in localdict and \
localdict[
advantage_rule.benefits_discounts.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[advantage_rule.benefits_discounts.code] = tot_rule
rules_dict[
advantage_rule.benefits_discounts.code] = advantage_rule
# sum the amount for its salary category
localdict = _sum_salary_rule_category(localdict,
advantage_rule.benefits_discounts.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
result_dict[key] = {
'salary_rule_id': advantage_rule.benefits_discounts.id,
'contract_id': contract.id,
'name': advantage_rule.benefits_discounts.name,
'code': advantage_rule.benefits_discounts.code,
'category_id': advantage_rule.benefits_discounts.category_id.id,
'amount_select': advantage_rule.benefits_discounts.amount_select,
'amount_fix': advantage_rule.benefits_discounts.amount_fix,
'amount_python_compute': advantage_rule.benefits_discounts.amount_python_compute,
'amount_percentage': advantage_rule.benefits_discounts.amount_percentage,
'register_id': advantage_rule.benefits_discounts.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
else:
if advantage_rule.benefits_discounts.name not in sorted_rules:
amount, qty, rate = rule._compute_rule(localdict)
previous_amount = rule.code in localdict and localdict[
rule.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[rule.code] = tot_rule
rules_dict[rule.code] = rule
localdict = _sum_salary_rule_category(localdict, rule.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
if amount != 0:
result_dict[key1] = {
'salary_rule_id': rule.id,
'contract_id': contract.id,
'name': rule.name,
'code': rule.code,
'category_id': rule.category_id.id,
'amount_select': rule.amount_select,
'amount_fix': rule.amount_fix,
'amount_python_compute': rule.amount_python_compute,
'amount_percentage': rule.amount_percentage,
'register_id': rule.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
if advantage_rule.type == 'customize':
amount = advantage_rule.amount
qty, rate = 1, 100.0
previous_amount = advantage_rule.benefits_discounts.code in localdict and \
localdict[
advantage_rule.benefits_discounts.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[advantage_rule.benefits_discounts.code] = tot_rule
rules_dict[
advantage_rule.benefits_discounts.code] = advantage_rule
# sum the amount for its salary category
localdict = _sum_salary_rule_category(localdict,
advantage_rule.benefits_discounts.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
result_dict[key] = {
'salary_rule_id': advantage_rule.benefits_discounts.id,
'contract_id': contract.id,
'name': advantage_rule.benefits_discounts.name,
'code': advantage_rule.benefits_discounts.code,
'category_id': advantage_rule.benefits_discounts.category_id.id,
'amount_select': advantage_rule.benefits_discounts.amount_select,
'amount_fix': advantage_rule.benefits_discounts.amount_fix,
'amount_python_compute': advantage_rule.benefits_discounts.amount_python_compute,
'amount_percentage': advantage_rule.benefits_discounts.amount_percentage,
'register_id': advantage_rule.benefits_discounts.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
elif advantage_rule.type == 'exception':
total = \
advantage_rule.benefits_discounts._compute_rule(localdict)[
0]
if total == advantage_rule.amount or total == 0.0:
amount, qty, rate = 0.0, 0, 0.0
previous_amount = advantage_rule.benefits_discounts.code in localdict and \
localdict[
advantage_rule.benefits_discounts.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[advantage_rule.benefits_discounts.code] = tot_rule
rules_dict[
advantage_rule.benefits_discounts.code] = advantage_rule
# sum the amount for its salary category
localdict = _sum_salary_rule_category(localdict,
advantage_rule.benefits_discounts.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
result_dict[key] = {
'salary_rule_id': advantage_rule.benefits_discounts.id,
'contract_id': contract.id,
'name': advantage_rule.benefits_discounts.name,
'code': advantage_rule.benefits_discounts.code,
'category_id': advantage_rule.benefits_discounts.category_id.id,
'amount_select': advantage_rule.benefits_discounts.amount_select,
'amount_fix': advantage_rule.benefits_discounts.amount_fix,
'amount_python_compute': advantage_rule.benefits_discounts.amount_python_compute,
'amount_percentage': advantage_rule.benefits_discounts.amount_percentage,
'register_id': advantage_rule.benefits_discounts.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
elif total <= advantage_rule.amount:
raise UserError(
_(
'The amount you put is greater than fact value of this Salary rule'))
else:
amount = total - advantage_rule.amount # update 21/04/2019
qty, rate = 1, 100.0
previous_amount = advantage_rule.benefits_discounts.code in localdict and \
localdict[
advantage_rule.benefits_discounts.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[advantage_rule.benefits_discounts.code] = tot_rule
rules_dict[
advantage_rule.benefits_discounts.code] = advantage_rule
# sum the amount for its salary category
localdict = _sum_salary_rule_category(localdict,
advantage_rule.benefits_discounts.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
result_dict[key] = {
'salary_rule_id': advantage_rule.benefits_discounts.id,
'contract_id': contract.id,
'name': advantage_rule.benefits_discounts.name,
'code': advantage_rule.benefits_discounts.code,
'category_id': advantage_rule.benefits_discounts.category_id.id,
'amount_select': advantage_rule.benefits_discounts.amount_select,
'amount_fix': advantage_rule.benefits_discounts.amount_fix,
'amount_python_compute': advantage_rule.benefits_discounts.amount_python_compute,
'amount_percentage': advantage_rule.benefits_discounts.amount_percentage,
'register_id': advantage_rule.benefits_discounts.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
else:
amount, qty, rate = rule._compute_rule(localdict)
previous_amount = rule.code in localdict and localdict[rule.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[rule.code] = tot_rule
rules_dict[rule.code] = rule
localdict = _sum_salary_rule_category(localdict, rule.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
if amount != 0:
result_dict[key1] = {
'salary_rule_id': rule.id,
'contract_id': contract.id,
'name': rule.name,
'code': rule.code,
'category_id': rule.category_id.id,
'amount_select': rule.amount_select,
'amount_fix': rule.amount_fix,
'amount_python_compute': rule.amount_python_compute,
'amount_percentage': rule.amount_percentage,
'register_id': rule.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
else:
if rule.id not in advantage_list:
# compute the amount of the rule
amount, qty, rate = rule._compute_rule(localdict)
# check if there is already a rule computed with that code
previous_amount = rule.code in localdict and localdict[rule.code] or 0.0
# set/overwrite the amount computed for this rule in the localdict
tot_rule = amount * qty * rate / 100.0
localdict[rule.code] = tot_rule
rules_dict[rule.code] = rule
# sum the amount for its salary category
localdict = _sum_salary_rule_category(localdict, rule.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
if amount != 0:
result_dict[key1] = {
'salary_rule_id': rule.id,
'contract_id': contract.id,
'name': rule.name,
'code': rule.code,
'category_id': rule.category_id.id,
'amount_select': rule.amount_select,
'amount_fix': rule.amount_fix,
'amount_python_compute': rule.amount_python_compute,
'amount_percentage': rule.amount_percentage,
'register_id': rule.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
if advantage_rule.type == 'customize':
amount = advantage_rule.amount
qty, rate = 1, 100.0
previous_amount = advantage_rule.benefits_discounts.code in localdict and \
localdict[advantage_rule.benefits_discounts.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[advantage_rule.benefits_discounts.code] = tot_rule
rules_dict[advantage_rule.benefits_discounts.code] = advantage_rule
# sum the amount for its salary category
localdict = _sum_salary_rule_category(localdict,
advantage_rule.benefits_discounts.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
result_dict[key] = {
'salary_rule_id': advantage_rule.benefits_discounts.id,
'contract_id': contract.id,
'name': advantage_rule.benefits_discounts.name,
'code': advantage_rule.benefits_discounts.code,
'category_id': advantage_rule.benefits_discounts.category_id.id,
'amount_select': advantage_rule.benefits_discounts.amount_select,
'amount_fix': advantage_rule.benefits_discounts.amount_fix,
'amount_python_compute': advantage_rule.benefits_discounts.amount_python_compute,
'amount_percentage': advantage_rule.benefits_discounts.amount_percentage,
'register_id': advantage_rule.benefits_discounts.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
elif advantage_rule.type == 'exception':
total = advantage_rule.benefits_discounts._compute_rule(
localdict)[0] # update 21/04/2019
if total == advantage_rule.amount or total == 0.0:
amount, qty, rate = 0.0, 0, 0.0
previous_amount = advantage_rule.benefits_discounts.code in localdict and \
localdict[
advantage_rule.benefits_discounts.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[advantage_rule.benefits_discounts.code] = tot_rule
rules_dict[advantage_rule.benefits_discounts.code] = advantage_rule
localdict = _sum_salary_rule_category(localdict,
advantage_rule.benefits_discounts.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
result_dict[key] = {
'salary_rule_id': advantage_rule.benefits_discounts.id,
'contract_id': contract.id,
'name': advantage_rule.benefits_discounts.name,
'code': advantage_rule.benefits_discounts.code,
'category_id': advantage_rule.benefits_discounts.category_id.id,
'amount_select': advantage_rule.benefits_discounts.amount_select,
'amount_fix': advantage_rule.benefits_discounts.amount_fix,
'amount_python_compute': advantage_rule.benefits_discounts.amount_python_compute,
'amount_percentage': advantage_rule.benefits_discounts.amount_percentage,
'register_id': advantage_rule.benefits_discounts.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
elif total <= advantage_rule.amount:
raise UserError(
_(
'The amount you put is greater than fact value of this Salary rule'))
else:
amount = total - advantage_rule.amount # update 21/04/2019
qty, rate = 1, 100.0
previous_amount = advantage_rule.benefits_discounts.code in localdict and \
localdict[advantage_rule.benefits_discounts.code] or 0.0
tot_rule = amount * qty * rate / 100.0
localdict[advantage_rule.benefits_discounts.code] = tot_rule
rules_dict[advantage_rule.benefits_discounts.code] = advantage_rule
# sum the amount for its salary category
localdict = _sum_salary_rule_category(localdict,
advantage_rule.benefits_discounts.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
result_dict[key] = {
'salary_rule_id': advantage_rule.benefits_discounts.id,
'contract_id': contract.id,
'name': advantage_rule.benefits_discounts.name,
'code': advantage_rule.benefits_discounts.code,
'category_id': advantage_rule.benefits_discounts.category_id.id,
'amount_select': advantage_rule.benefits_discounts.amount_select,
'amount_fix': advantage_rule.benefits_discounts.amount_fix,
'amount_python_compute': advantage_rule.benefits_discounts.amount_python_compute,
'amount_percentage': advantage_rule.benefits_discounts.amount_percentage,
'register_id': advantage_rule.benefits_discounts.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
advantage_rule.write({'done': True})
else:
# compute the amount of the rule
amount, qty, rate = rule._compute_rule(localdict)
# check if there is already a rule computed with that code
previous_amount = rule.code in localdict and localdict[rule.code] or 0.0
# set/overwrite the amount computed for this rule in the localdict
tot_rule = amount * qty * rate / 100.0
localdict[rule.code] = tot_rule
rules_dict[rule.code] = rule
# sum the amount for its salary category
localdict = _sum_salary_rule_category(localdict, rule.category_id,
tot_rule - previous_amount)
# create/overwrite the rule in the temporary results
if amount != 0:
result_dict[key1] = {
'salary_rule_id': rule.id,
'contract_id': contract.id,
'name': rule.name,
'code': rule.code,
'category_id': rule.category_id.id,
'amount_select': rule.amount_select,
'amount_fix': rule.amount_fix,
'amount_python_compute': rule.amount_python_compute,
'amount_percentage': rule.amount_percentage,
'register_id': rule.register_id.id,
'amount': amount,
'employee_id': contract.employee_id.id,
'quantity': qty,
'rate': rate}
else:
blacklist += [id for id, seq in rule._recursive_search_of_rules()]
return list(result_dict.values())
class HrPayslipLine(models.Model):
_inherit = 'hr.payslip.line'
leave_request_case = fields.Boolean()
# Relational fields
payslip_allowance = fields.Many2one('hr.payslip', ondelete='cascade', index=True)
payslip_deduction = fields.Many2one('hr.payslip', ondelete='cascade', index=True)
related_benefits_discounts = fields.Many2many(comodel_name='hr.salary.rule',
relation='payslip_line_benefit_discount_rel',
column1='rule_id', column2='sub_rule_id',
string='Related Benefits and Discount')
percentage = fields.Float(string='Percentage', related='slip_id.percentage')
# override compute function in payslip lines
@api.depends('quantity', 'amount', 'rate')
def _compute_total(self):
# payslip = self.env['hr.payslip'].search([('id', '=', self.slip_id.id)])
#print("payslip######################### ", self)
start_time = time.time()
for line in self:
#print('--------------------------hr.payslip.line-------------------', line.id)
if line.slip_id.worked_days_line_ids:
total_days = 0
per = 0
days_number = sum(line.number_of_days for line in line.slip_id.worked_days_line_ids)
for wo in line.slip_id.worked_days_line_ids:
####################################################### Holidays Unpaid ######################################
if wo.name == "Unpaid Holidays For this month":
work_days = wo.number_of_days
if total_days:
line.slip_id.total_allowances = 0.0
line.slip_id.total_deductions = 0.0
total_days_after_holiday = total_days - work_days
total_days = total_days_after_holiday
else:
total_days_after_holiday = 30 - work_days
total_days = total_days_after_holiday
if line.salary_rule_id.reduce_with_leaves == True and line.salary_rule_id.min_leave_days_to_deduct <= days_number:
line.total = round(((line.amount / 30) * total_days_after_holiday) * line.percentage / 100,2)
else:
line.total = round(((line.amount) * line.percentage / 100),2)
# line.total = ((line.amount / 30) * total_days_after_holiday) * line.percentage / 100
#################################################### Holidays percentage #######################################
elif wo.name == "Paid Holidays By percentage":
work_days = wo.number_of_days
percentage = wo.number_of_hours
if total_days:
line.slip_id.total_allowances = 0.0
line.slip_id.total_deductions = 0.0
total_days_after_holiday = total_days - work_days
total_days = total_days_after_holiday
else:
total_days_after_holiday = 30 - work_days
total_days = total_days_after_holiday
allow = (line.amount / 30) * work_days
per += (allow * percentage / 100)
actual_allow_tot = (line.amount / 30) * total_days_after_holiday
if line.salary_rule_id.reduce_with_leaves == True and line.salary_rule_id.min_leave_days_to_deduct <= days_number:
line.total = round((actual_allow_tot + per) * line.percentage / 100,2)
else:
line.total = round(((line.amount) * line.percentage / 100),2)
# line.total = (actual_allow_tot + per) * line.percentage / 100
##################################################### Holidays Additional ########################################
elif wo.name == "Additional Paid Holidays":
work_days = wo.number_of_days
if total_days:
line.slip_id.total_allowances = 0.0
line.slip_id.total_deductions = 0.0
total_days_after_holiday = total_days - work_days
total_days = total_days_after_holiday
else:
total_days_after_holiday = 30 - work_days
total_days = total_days_after_holiday
if line.leave_request_case or line.salary_rule_id.reduce_with_leaves == False or line.salary_rule_id.min_leave_days_to_deduct > days_number:
line.total = round((line.amount) * line.percentage / 100,2)
else:
line.total = round(((line.amount / 30) * total_days_after_holiday) * line.percentage / 100,2)
################################################### Holidays Reconcile and Exclusion ###############################
elif wo.name == "Exclusion or Reconcile Paid Holidays":
work_days = wo.number_of_days
if total_days:
line.slip_id.total_allowances = 0.0
line.slip_id.total_deductions = 0.0
total_days_after_holiday = total_days - work_days
total_days = total_days_after_holiday
else:
total_days_after_holiday = 30 - work_days
total_days = total_days_after_holiday
if not line.leave_request_case or line.salary_rule_id.reduce_with_leaves == False or line.salary_rule_id.min_leave_days_to_deduct > days_number:
line.total = round((line.amount) * line.percentage / 100,2)
else:
line.total = round(((line.amount / 30) * total_days_after_holiday) * line.percentage / 100,2)
################################################### Working days for this month ######################################
else:
work_days = wo.number_of_days
total_days = work_days
if line.leave_request_case or line.salary_rule_id.reduce_with_leaves == False or line.salary_rule_id.min_leave_days_to_deduct > days_number:
line.total = round((line.amount) * line.percentage / 100,2)
else:
line.total = round(((line.amount / 30) * work_days) * line.percentage / 100,2)
################################################### End IF Then else #################################################
else:
total = Decimal(line.amount * line.percentage / 100)
rounded = total.quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)
line.total = round(rounded,2)
#print("compute_shee_computee_total payslips_Run %s" % (time.time() - start_time))
class HrPayslipRun(models.Model):
_inherit = 'hr.payslip.run'
required_condition = fields.Boolean(string='Required Condition', compute='compute_type')
state = fields.Selection(selection_add=[('computed', 'Computed'),
('confirmed', 'Confirmed'),
('transfered', 'Transfer'), ('close', 'Close')], tracking=True)
# Relational fields
salary_scale = fields.Many2one('hr.payroll.structure', string='Salary Scale')
employee_ids = fields.Many2many('hr.employee', 'hr_employee_payslip_rel', 'payslip_id', 'employee_id', 'Employees',
index=True,domain="[('id', 'in', employee_value_ids)]")
department_ids = fields.Many2many('hr.department', 'hr_department_payslip_rel',
'payslip_id', 'department_id', 'Departments')
journal_id = fields.Many2one('account.journal', 'Salary Journal')
percentage = fields.Float(string='Percentage', default=100)
move_id = fields.Many2one('account.move', string="Move Number")
company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.company)
employee_value_ids = fields.Many2many(comodel_name="hr.employee", compute="_compute_allowed_value_ids")
holiday_start_date = fields.Date(string="Holiday Start Date")
holiday_end_date = fields.Date(string="Holiday End Date")
@api.onchange('date_start')
def check_date_start(self):
if self.date_start :
self.date_end = fields.Date.from_string(self.date_start)+relativedelta(months=+1, day=1, days=-1)
@api.onchange('date_end')
def check_date_end(self):
if self.date_start and self.date_end and self.date_start > self.date_end:
raise UserError(_('Date From must be less than or equal Date To'))
month_current_from = datetime.strptime(str(self.date_start), '%Y-%m-%d').strftime('%m')
year_current_from = datetime.strptime(str(self.date_start), '%Y-%m-%d').strftime('%y')
month_current_to = datetime.strptime(str(self.date_end), '%Y-%m-%d').strftime('%m')
year_current_to = datetime.strptime(str(self.date_end), '%Y-%m-%d').strftime('%y')
if month_current_from != month_current_to or year_current_from != year_current_to:
raise UserError(_('Sorry, The Pyroll period Must be During the same Month'))
@api.depends('salary_scale.transfer_type')
def compute_type(self):
if self.salary_scale.transfer_type == 'all' or self.salary_scale.transfer_type == 'per_analytic_account':
self.required_condition = True
else:
self.required_condition = False
# domain the employee to compute salary
@api.depends('salary_scale','department_ids','date_start')
def _compute_allowed_value_ids(self):
for item in self:
date_from = str(item.date_start)
date_to = str(item.date_end)
if item.salary_scale:
if item.department_ids:
depart = item.department_ids._origin
#for dep in item.department_ids._origin:
employee_contracts = self.env['hr.contract'].search(
[('salary_scale', '=', item.salary_scale.id),
('state', '=', 'program_directory')]).filtered(
lambda item: item.employee_id.department_id in depart and item.employee_id.state == 'open'
and str(item.employee_id.first_hiring_date) <= date_to)
item.employee_value_ids = employee_contracts.mapped("employee_id")
else:
employee_contracts = self.env['hr.contract'].search(
[('salary_scale', '=', item.salary_scale.id), ('state', '=', 'program_directory')]).filtered(
lambda item: item.employee_id.state == 'open' and str(item.employee_id.first_hiring_date) <= date_to)
item.employee_value_ids = employee_contracts.mapped("employee_id")
else:
item.employee_value_ids = False
@api.onchange('salary_scale')
def _onchange_salary_scale_id(self):
for item in self:
if item.salary_scale:
item.employee_ids = False
item.department_ids = False
@api.onchange('department_ids','date_start')
def _onchange_department_ids(self):
for item in self:
item.employee_ids = False
'''@api.onchange('salary_scale')
def onchange_salary_scale_id(self):
for item in self:
if item.salary_scale:
item.employee_ids = False
item.department_ids = False
if item.department_ids:
for dep in item.department_ids:
employee_contracts = self.env['hr.contract'].search(
[('salary_scale', '=', item.salary_scale.id),
('state', '=', 'program_directory')]).filtered(
lambda item: item.employee_id.department_id == dep and item.employee_id.state == 'open')
emps = []
for contract in employee_contracts:
emps.append(contract.employee_id.id)
return {'domain': {'employee_ids': [('id', 'in', emps)]}}
else:
employee_contracts = self.env['hr.contract'].search(
[('salary_scale', '=', item.salary_scale.id), ('state', '=', 'program_directory')]).filtered(
lambda item: item.employee_id.state == 'open')
emps = []
for contract in employee_contracts:
emps.append(contract.employee_id.id)
return {'domain': {'employee_ids': [('id', 'in', emps)]}}
else:
return {'domain': {'employee_ids': [('id', 'in', [])]}}'''
# Override function compute sheet in Payslip Batches
def compute_sheet(self):
payslips = self.env['hr.payslip']
[data] = self.read()
from_date = str(self.date_start)
to_date = str(self.date_end)
holiday_start_date = str(self.holiday_start_date) if self.holiday_start_date else False
holiday_end_date = str(self.holiday_end_date) if self.holiday_end_date else False
start_time = time.time()
#worked_days, emps, dictionary = [], [], []
worked_days, emps, dictionary,emp_last_payslip,emp_priv_payslip = [], [], [], [],[]
if datetime.strptime(str(from_date), "%Y-%m-%d").date().month == datetime.strptime(str(to_date),"%Y-%m-%d").date().month:
month_date = datetime.strptime(str(from_date), "%Y-%m-%d").date()
if self.department_ids:
for dep in self.department_ids:
employee_contracts = self.env['hr.contract'].search(
[('salary_scale', '=', self.salary_scale.id), ('state', '=', 'program_directory')]).filtered(
lambda item: item.employee_id.department_id == dep and item.employee_id.state == 'open'
and str(item.employee_id.first_hiring_date) <= to_date)
for contract in employee_contracts:
emps.append(contract.employee_id.id)
else:
employee_contracts = self.env['hr.contract'].search(
[('salary_scale', '=', self.salary_scale.id), ('state', '=', 'program_directory')]).filtered(
lambda item: item.employee_id.state == 'open' and str(item.employee_id.first_hiring_date) <= to_date)
for contract in employee_contracts:
emps.append(contract.employee_id.id)
emps = self.env['hr.employee'].browse(emps)
employees = self.env['hr.employee'].browse(data['employee_ids'])
################### Employee run payslip one in month and previously month #######
last_payslips = self.env['hr.payslip'].search([('date_from', '>=', self.date_start),('date_from', '<=', self.date_end),
('payslip_run_id', '!=', self.id)])
if last_payslips:
for priv_pay in last_payslips:
if employees:
for emp in employees:
if emp.id == priv_pay.employee_id.id:
emp_last_payslip.append(emp.name)
else :
for emp in emps:
if emp.id == priv_pay.employee_id.id:
emp_last_payslip.append(emp.name)
if emp_last_payslip:
raise UserError(
_("Sorry, Salary has already been calculated This Month for Employees \n %s") % (emp_last_payslip))
########################################################################################
last_month = self.date_start - relativedelta(months=1)
end_last_month = self.date_start - relativedelta(days=1)
priv_payslips_month = self.env['hr.payslip'].search([('date_from', '>=', last_month),('date_from', '<=', end_last_month),
('payslip_run_id', '!=', self.id)]).employee_id
old_payslips = self.env['hr.payslip'].search([('date_from', '<', self.date_start),
('payslip_run_id', '!=', self.id)]).employee_id
if employees:
diff_employee= employees-priv_payslips_month
else:
diff_employee= emps-priv_payslips_month
#if diff_employee and diff_employee in old_payslips :
if diff_employee :
for emp in diff_employee:
if emp in old_payslips:
emp_priv_payslip.append(emp.name)
if emp_priv_payslip:
raise UserError(
_("Sorry, The Previous month's salary has Not been calculated for Employees \n %s") % (emp_priv_payslip))
################### End ################################################################
if employees:
locale = self.env.context.get('lang') or 'en_US'
for employee in employees:
slip_data = self.env['hr.payslip'].onchange_employee_id(from_date, to_date, employee.id,
contract_id=False)
# pays = self.env['hr.payslip'].search([('contract_id', '=', employee.contract_id.id)])
################### Rename Slip and Date#######
ttyme = datetime.fromtimestamp(time.mktime(time.strptime(str(from_date), "%Y-%m-%d")))
slip_data['value'].update({
'name': _('Salary Slip of %s for %s') % (
employee.name, tools.ustr(babel.dates.format_date(date=ttyme, format='MMMM-y',locale=locale))),
'company_id': employee.company_id.id,
})
###########
employee_slip_line = self.slip_ids.filtered(lambda item: item.employee_id.id == employee.id)
if to_date >= str(employee.first_hiring_date) >= from_date:
contract_start_date = datetime.strptime(str(employee.first_hiring_date), "%Y-%m-%d").date()
if to_date >= str(employee.leaving_date) >= str(employee.first_hiring_date):
contract_end_date = datetime.strptime(str(employee.leaving_date),
"%Y-%m-%d").date() + timedelta(
days=1)
duration = relativedelta(contract_end_date, contract_start_date).days
hours = (float((contract_end_date - contract_start_date).seconds) / 86400) * 24
if not employee_slip_line:
res = {
'employee_id': employee.id,
'name': slip_data['value'].get('name'),
'struct_id': self.salary_scale.id,
'contract_id': employee.contract_id.id,
'input_line_ids': [(0, 0, x) for x in slip_data['value'].get('input_line_ids')],
'worked_days_line_ids': worked_days,
'date_from': str(employee.first_hiring_date) or from_date,
'date_to': employee.leaving_date or to_date,
'holiday_start_date': holiday_start_date,
'holiday_end_date': holiday_end_date,
'credit_note': self.credit_note,
'company_id': employee.company_id.id,
'percentage': self.percentage}
item_payslip = self.env['hr.payslip'].create(res)
payslips += item_payslip
# if pays:
# for p in pays:
# if p.employee_id != employee and p not in payslips:
# payslips += item_payslip
# else:
# payslips += item_payslip
if item_payslip:
days = {'name': "Working days for this month",
'sequence': 1,
'payslip_id': item_payslip.id,
'code': 2,
'number_of_days': duration,
'number_of_hours': hours,
'contract_id': employee.contract_id.id}
worked_days += self.env['hr.payslip.worked_days'].create(days)
else:
item_payslip = employee_slip_line
payslips += item_payslip
# if pays:
# for p in pays:
# if p.employee_id != employee and p not in payslips:
# payslips += item_payslip
# else:
# payslips += item_payslip
else:
from calendar import monthrange
month_range = monthrange(datetime.now().date().year, month_date.month)[1]
contract_end_date = datetime.strptime(str(to_date), "%Y-%m-%d").date()
if month_range == 30 and contract_end_date.day == 30:
duration = relativedelta(contract_end_date, contract_start_date).days + 1
elif month_range > 30 and contract_end_date.day > 30:
duration = relativedelta(contract_end_date, contract_start_date).days
if duration == 0:
duration = duration + 1
elif month_range == 28 and contract_end_date.day == 28:
duration = relativedelta(contract_end_date, contract_start_date).days + 3
elif month_range == 29 and contract_end_date.day == 29:
duration = relativedelta(contract_end_date, contract_start_date).days + 2
else:
duration = relativedelta(contract_end_date, contract_start_date).days + 1
hours = (float((contract_end_date - contract_start_date).seconds) / 86400) * 24
if not employee_slip_line:
res = {
'employee_id': employee.id,
'name': slip_data['value'].get('name'),
'struct_id': self.salary_scale.id,
'contract_id': employee.contract_id.id,
'input_line_ids': [(0, 0, x) for x in slip_data['value'].get('input_line_ids')],
# 'worked_days_line_ids': worked_days ,
'date_from': str(employee.first_hiring_date) or from_date,
'date_to': to_date,
'holiday_start_date': holiday_start_date,
'holiday_end_date': holiday_end_date,
'credit_note': self.credit_note,
'company_id': employee.company_id.id,
'percentage': self.percentage}
item_payslip = self.env['hr.payslip'].create(res)
payslips += item_payslip
# if pays:
# for p in pays:
# if p.employee_id != employee and p not in payslips:
# payslips += item_payslip
# else:
# payslips += item_payslip
if item_payslip:
# print("22222222222222222222222222222222222222222222222", employee.english_name)
days = {'name': "Working days for this month",
'sequence': 1,
'payslip_id': item_payslip.id,
'code': 2,
'number_of_days': duration,
'number_of_hours': hours,
'contract_id': employee.contract_id.id}
worked_days += self.env['hr.payslip.worked_days'].create(days)
else:
item_payslip = employee_slip_line
payslips += item_payslip
# if pays:
# for p in pays:
# if p.employee_id != employee and p not in payslips:
# payslips += item_payslip
# else:
# payslips += item_payslip
elif to_date >= str(employee.leaving_date) >= from_date:
contract_start_date = datetime.strptime(str(from_date), "%Y-%m-%d").date()
contract_end_date = datetime.strptime(str(employee.leaving_date), "%Y-%m-%d").date() + timedelta(
days=1)
duration = relativedelta(contract_end_date, contract_start_date).days
hours = (float((contract_end_date - contract_start_date).seconds) / 86400) * 24
employee_slip_line = self.slip_ids.filtered(lambda item: item.employee_id.id == employee.id)
if not employee_slip_line:
res = {
'employee_id': employee.id,
'name': slip_data['value'].get('name'),
'struct_id': self.salary_scale.id,
'contract_id': employee.contract_id.id,
'input_line_ids': [(0, 0, x) for x in slip_data['value'].get('input_line_ids')],
'worked_days_line_ids': worked_days,
'date_from': from_date,
'date_to': employee.leaving_date or to_date,
'holiday_start_date': holiday_start_date,
'holiday_end_date': holiday_end_date,
'credit_note': self.credit_note,
'company_id': employee.company_id.id,
'percentage': self.percentage}
item_payslip = self.env['hr.payslip'].create(res)
payslips += item_payslip
# if pays:
# for p in pays:
# if p.employee_id != employee and p not in payslips:
# payslips += item_payslip
# else:
# payslips += item_payslip
if item_payslip:
days = {'name': "Working days for this month",
'sequence': 1,
'payslip_id': item_payslip.id,
'code': 2,
'number_of_days': duration,
'number_of_hours': hours,
'contract_id': employee.contract_id.id}
worked_days += self.env['hr.payslip.worked_days'].create(days)
else:
item_payslip = employee_slip_line
payslips += item_payslip
# if pays:
# for p in pays:
# if p.employee_id != employee and p not in payslips:
# payslips += item_payslip
# else:
# payslips += item_payslip
else:
if not employee_slip_line and str(employee.first_hiring_date) < from_date:
if employee.leaving_date:
if str(employee.leaving_date) <= from_date:
pass
else:
res = {
'employee_id': employee.id,
'name': slip_data['value'].get('name'),
'struct_id': self.salary_scale.id,
'contract_id': employee.contract_id.id,
'input_line_ids': [(0, 0, x) for x in slip_data['value'].get('input_line_ids')],
'worked_days_line_ids': [(0, 0, x) for x in
slip_data['value'].get('worked_days_line_ids')],
'date_from': from_date,
'date_to': to_date,
'holiday_start_date': holiday_start_date,
'holiday_end_date': holiday_end_date,
'credit_note': self.credit_note,
'company_id': employee.company_id.id,
'percentage': self.percentage}
payslips += self.env['hr.payslip'].create(res)
else:
res = {
'employee_id': employee.id,
'name': slip_data['value'].get('name'),
'struct_id': self.salary_scale.id,
'contract_id': employee.contract_id.id,
'input_line_ids': [(0, 0, x) for x in slip_data['value'].get('input_line_ids')],
'worked_days_line_ids': [(0, 0, x) for x in
slip_data['value'].get('worked_days_line_ids')],
'date_from': from_date,
'date_to': to_date,
'holiday_start_date': holiday_start_date,
'holiday_end_date': holiday_end_date,
'credit_note': self.credit_note,
'company_id': employee.company_id.id,
'percentage': self.percentage}
payslips += self.env['hr.payslip'].create(res)
else:
if employee.leaving_date and str(employee.first_hiring_date) < from_date:
if str(employee.leaving_date) <= from_date:
pass
else:
payslips += employee_slip_line
else:
payslips += employee_slip_line
else:
for emp in emps:
slip_data = self.env['hr.payslip'].onchange_employee_id(from_date, to_date, emp.id, contract_id=False)
# pays = self.env['hr.payslip'].search(
# [('contract_id', '=', emp.contract_id.id), ('date_from', '>=', self.date_start)])
################### Rename Slip and Date#######
ttyme = datetime.fromtimestamp(time.mktime(time.strptime(str(from_date), "%Y-%m-%d")))
slip_data['value'].update({
'name': _('Salary Slip of %s for %s') % (
emp.name, tools.ustr(babel.dates.format_date(date=ttyme, format='MMMM-y'))),
'company_id': emp.company_id.id,
})
###########
employee_slip_line = self.slip_ids.filtered(lambda item: item.employee_id.id == emp.id)
if to_date >= str(emp.first_hiring_date) >= from_date:
if to_date >= str(emp.leaving_date) >= str(emp.first_hiring_date):
contract_start_date = datetime.strptime(str(emp.first_hiring_date), "%Y-%m-%d").date()
contract_end_date = datetime.strptime(str(emp.leaving_date), "%Y-%m-%d").date() + timedelta(
days=1)
duration = relativedelta(contract_end_date, contract_start_date).days
hours = (float((contract_end_date - contract_start_date).seconds) / 86400) * 24
if not employee_slip_line:
res = {
'employee_id': emp.id,
'name': slip_data['value'].get('name'),
'struct_id': self.salary_scale.id,
'contract_id': emp.contract_id.id,
'input_line_ids': [(0, 0, x) for x in slip_data['value'].get('input_line_ids')],
# 'worked_days_line_ids': worked_days,
'date_from': emp.first_hiring_date or from_date,
'date_to': emp.leaving_date or to_date,
'holiday_start_date': holiday_start_date,
'holiday_end_date': holiday_end_date,
'credit_note': self.credit_note,
'company_id': emp.company_id.id,
'percentage': self.percentage}
item_payslip = self.env['hr.payslip'].create(res)
payslips += item_payslip
# if pays:
# for p in pays:
# if p.employee_id != emp and p not in payslips:
# payslips += item_payslip
# else:
# payslips += item_payslip
if item_payslip:
days = {'name': "Working days for this month",
'sequence': 1,
'payslip_id': item_payslip.id,
'code': 2,
'number_of_days': duration,
'number_of_hours': hours,
'contract_id': emp.contract_id.id}
worked_days += self.env['hr.payslip.worked_days'].create(days)
else:
item_payslip = employee_slip_line
payslips += item_payslip
# if pays:
# for p in pays:
# if p.employee_id != emp and p not in payslips:
# payslips += item_payslip
# else:
# payslips += item_payslip
else:
contract_start_date = datetime.strptime(str(emp.first_hiring_date), "%Y-%m-%d").date()
from calendar import monthrange
month_range = monthrange(datetime.now().date().year, month_date.month)[1]
contract_end_date = datetime.strptime(str(to_date), "%Y-%m-%d").date()
if month_range == 30 and contract_end_date.day == 30:
duration = relativedelta(contract_end_date, contract_start_date).days + 1
elif month_range > 30 and contract_end_date.day > 30:
duration = relativedelta(contract_end_date, contract_start_date).days
if duration == 0:
duration = duration + 1
elif month_range == 28 and contract_end_date.day == 28:
duration = relativedelta(contract_end_date, contract_start_date).days + 3
elif month_range == 29 and contract_end_date.day == 29:
duration = relativedelta(contract_end_date, contract_start_date).days + 2
else:
duration = relativedelta(contract_end_date, contract_start_date).days + 1
hours = (float((contract_end_date - contract_start_date).seconds) / 86400) * 24
if not employee_slip_line:
res = {
'employee_id': emp.id,
'name': slip_data['value'].get('name'),
'struct_id': self.salary_scale.id,
'contract_id': emp.contract_id.id,
'input_line_ids': [(0, 0, x) for x in slip_data['value'].get('input_line_ids')],
# 'worked_days_line_ids': worked_days,
'date_from': emp.first_hiring_date or from_date,
'date_to': to_date,
'holiday_start_date': holiday_start_date,
'holiday_end_date': holiday_end_date,
'credit_note': self.credit_note,
'company_id': emp.company_id.id,
'percentage': self.percentage}
item_payslip = self.env['hr.payslip'].create(res)
payslips += item_payslip
# if pays:
# for p in pays:
# if p.employee_id != emp and p not in payslips:
# payslips += item_payslip
# else:
# payslips += item_payslip
if item_payslip:
days = {'name': "Working days for this month",
'sequence': 1,
'payslip_id': item_payslip.id,
'code': 2,
'number_of_days': duration,
'number_of_hours': hours,
'contract_id': emp.contract_id.id}
worked_days += self.env['hr.payslip.worked_days'].create(days)
else:
item_payslip = employee_slip_line
payslips += item_payslip
# if pays:
# for p in pays:
# if p.employee_id != emp and p not in payslips:
# payslips += item_payslip
# else:
# payslips += item_payslip
elif to_date >= str(emp.leaving_date) >= from_date:
contract_start_date = datetime.strptime(str(from_date), "%Y-%m-%d").date()
contract_end_date = datetime.strptime(str(emp.leaving_date), "%Y-%m-%d").date() + timedelta(days=1)
duration = relativedelta(contract_end_date, contract_start_date).days
hours = (float((contract_end_date - contract_start_date).seconds) / 86400) * 24
if not employee_slip_line:
res = {
'employee_id': emp.id,
'name': slip_data['value'].get('name'),
'struct_id': self.salary_scale.id,
'contract_id': emp.contract_id.id,
'input_line_ids': [(0, 0, x) for x in slip_data['value'].get('input_line_ids')],
'worked_days_line_ids': worked_days,
'date_from': from_date,
'date_to': emp.leaving_date,
'holiday_start_date': holiday_start_date,
'holiday_end_date': holiday_end_date,
'credit_note': self.credit_note,
'company_id': emp.company_id.id,
'percentage': self.percentage}
item_payslip = self.env['hr.payslip'].create(res)
payslips += item_payslip
# if pays:
# for p in pays:
# if p.employee_id != emp and p not in payslips:
# payslips += item_payslip
# else:
# payslips += item_payslip
if item_payslip:
days = {'name': "Working days for this month",
'sequence': 1,
'payslip_id': item_payslip.id,
'code': 2,
'number_of_days': duration,
'number_of_hours': hours,
'contract_id': emp.contract_id.id}
worked_days += self.env['hr.payslip.worked_days'].create(days)
else:
item_payslip = employee_slip_line
payslips += item_payslip
# if pays:
# for p in pays:
# if p.employee_id != emp and p not in payslips:
# payslips += item_payslip
# else:
# payslips += item_payslip
else:
if not employee_slip_line and str(emp.first_hiring_date) < from_date:
if emp.leaving_date:
if str(emp.leaving_date) <= from_date:
pass
else:
res = {
'employee_id': emp.id,
'name': slip_data['value'].get('name'),
'struct_id': self.salary_scale.id,
'contract_id': emp.contract_id.id,
'input_line_ids': [(0, 0, x) for x in slip_data['value'].get('input_line_ids')],
'worked_days_line_ids': [(0, 0, x) for x in
slip_data['value'].get('worked_days_line_ids')],
'date_from': from_date,
'date_to': to_date,
'holiday_start_date': holiday_start_date,
'holiday_end_date': holiday_end_date,
'credit_note': self.credit_note,
'company_id': emp.company_id.id,
'percentage': self.percentage}
# if pays:
# for p in pays:
# if p.employee_id != emp and p not in payslips:
# payslips += self.env['hr.payslip'].create(res)
# else:
payslips += self.env['hr.payslip'].create(res)
else:
res = {
'employee_id': emp.id,
'name': slip_data['value'].get('name'),
'struct_id': self.salary_scale.id,
'contract_id': emp.contract_id.id,
'input_line_ids': [(0, 0, x) for x in slip_data['value'].get('input_line_ids')],
'worked_days_line_ids': [(0, 0, x) for x in
slip_data['value'].get('worked_days_line_ids')],
'date_from': from_date,
'date_to': to_date,
'holiday_start_date': holiday_start_date,
'holiday_end_date': holiday_end_date,
'credit_note': self.credit_note,
'company_id': emp.company_id.id,
'percentage': self.percentage}
# if pays:
# for p in pays:
# if p.employee_id != emp and p not in payslips:
# payslips += self.env['hr.payslip'].create(res)
# else:
payslips += self.env['hr.payslip'].create(res)
else:
if emp.leaving_date and str(emp.first_hiring_date) < from_date:
if str(emp.leaving_date) <= from_date:
pass
else:
payslips += employee_slip_line
else:
payslips += employee_slip_line
payslips.compute_sheet()
self.env['hr.payslip.line']._compute_total()
for pay in payslips:
if pay.total_sum < 0:
dictionary.append(pay.employee_id.name)
if dictionary:
raise UserError(
_("Salary is less than 0 this month for the following employees \n %s") % (dictionary))
self.slip_ids = payslips
self.write({'state': 'computed'})
def withdraw(self):
for line in self.slip_ids:
payslip = self.env['hr.payslip'].search([('number', '=', line.number)])
if 'hr.loan.salary.advance' in self.env:
loans = self.env['hr.loan.salary.advance'].search([('employee_id', '=', line.employee_id.id)])
if line.number == payslip.number:
if line.loan_ids:
for loan in line.loan_ids:
loan.paid = False
if loans:
for i in loans:
if i.id == loan.loan_id.id:
for l in i.deduction_lines:
if loan.date == l.installment_date and loan.paid is False:
l.paid = False
l.payment_date = False
#i.remaining_loan_amount += l.installment_amount
i.get_remaining_loan_amount()
# check remaining loan and change state to pay
if i.state == 'closed' and i.remaining_loan_amount > 0.0:
i.state = 'pay'
elif i.remaining_loan_amount == 0.0 and i.gm_propos_amount > 0.0:
i.state = 'closed'
for record in payslip:
record.write({'state': 'draft'})
record.unlink()
self.write({'slip_ids': [fields.Command.clear()]})
self.write({'state': 'draft'})
def unlink(self):
if any(self.filtered(lambda payslip: payslip.state != 'draft')):
raise UserError(_('You cannot delete a payslip which is not draft!'))
return super(HrPayslipRun, self).unlink()
def return_button(self):
for line in self.slip_ids:
payslip = self.env['hr.payslip'].search([('state', '=', line.state)])
if payslip:
if self.move_id:
if self.move_id.state == 'posted':
raise UserError(
_('You can not Return account move %s in state not draft') % self.move_id.name)
else:
self.move_id.unlink()
self.move_id = False
if line.move_id:
if line.move_id.state == 'posted':
raise UserError(
_('You can not Return account move %s in state not draft') % line.move_id.name)
else:
line.move_id.unlink()
line.move_id = False
line.write({'state': 'computed'})
self.write({'state': 'computed'})
def confirm(self):
for line in self.slip_ids:
payslip = self.env['hr.payslip'].search([('state', '=', line.state)])
if payslip:
line.write({'state': 'confirmed'})
self.write({'state': 'confirmed'})
def merge_lists(self, l1, key, key2):
grupos = it.groupby(sorted(l1, key=itemgetter(key,key2)), key=itemgetter(key, key2))
res = []
for v, items in grupos:
new_items = list(items)
analytic_account_id = None
if round(sum(dicc['debit'] for dicc in new_items),2) > 0:
analytic_account_id = self.salary_scale.analytic_account_id.id
res.append({
'name': v[0],
'account_id': v[1],
'debit': round(sum(dicc['debit'] for dicc in new_items),2),
'credit': round(sum(dicc2['credit'] for dicc2 in new_items),2),
'analytic_account_id': analytic_account_id ,
})
return res
def new_merge_lists(self, l1, key1, key2, key3):
# groups = it.groupby(sorted(l1, key=itemgetter(key)), key=itemgetter(key, key2, key3))
groups = it.groupby(sorted(l1, key=itemgetter(key1, key2, key3)), key=itemgetter(key1, key2, key3))
res = []
for v, items in groups:
new_items = list(items)
res.append({
'name': v[0],
'account_id': v[1],
'analytic_account_id': v[2],
'debit': sum(dicc['debit'] for dicc in new_items),
'credit': sum(dicc2['credit'] for dicc2 in new_items)
})
return res
def transfer(self):
list_of_vals = []
if self.salary_scale.transfer_type == 'all':
total_of_list = []
for line in self.slip_ids:
emp_type = line.employee_id.employee_type_id.id
total_allow, total_ded, total_loan = 0.0, 0.0, 0.0
total_list = []
total_loan_list = []
move_vals = dict()
journal = self.journal_id
if list_of_vals:
for item in list_of_vals:
if item.get('move') == journal.id:
move_vals = item
break
for l in line.allowance_ids:
amount_allow = l.total
# account = l.salary_rule_id.rule_debit_account_id
account = l.salary_rule_id.get_debit_account_id(emp_type)
if not account:
raise UserError(
_('Sorry The Allowance %s is Not account Set') % l.name)
total_list.append({
'name': l.name,
'debit': amount_allow,
'journal_id': journal.id,
'credit': 0,
'account_id': account,
})
total_allow += amount_allow
for ded in line.deduction_ids:
amount_ded = -ded.total
# account = ded.salary_rule_id.rule_credit_account_id
account = ded.salary_rule_id.get_credit_account_id(emp_type)
if not account:
raise UserError(
_('Sorry The Deduction %s is Not account Set') % ded.name)
total_list.append({
'name': ded.name,
'credit': amount_ded,
'journal_id': journal.id,
'debit': 0,
'account_id': account,
})
total_ded += amount_ded
for lo in line.loan_ids:
amount_loans = -lo.amount
if not lo.account_id:
raise UserError(
_('Sorry The Loan %s is Not account Set') % lo.name)
loan_line_vals = {
'name': lo.name,
'credit': amount_loans,
'debit': 0,
'journal_id': journal.id,
'account_id': lo.account_id.id,
'partner_id': line.employee_id.user_id.partner_id.id,
}
total_loan_list.append(loan_line_vals)
total_loan += amount_loans
# credit_loans_vals = {
# 'name': lo.name,
# 'credit': amount_loans,
# 'journal_id': journal.id,
# 'debit': 0,
# 'account_id': lo.account_id.id,
# }
# total_list.append(credit_loans_vals)
# create line for total of all allowance, deduction, loans of all employees
total_of_list.append({
'name': "Total",
'journal_id': journal.id,
'partner_id': line.employee_id.user_id.partner_id.id,
'account_id': journal.default_account_id.id,
'credit': round(total_allow, 2) - round(total_ded, 2) - round(total_loan, 2),
'debit': 0,
})
if not move_vals:
move_vals.update({'move': journal.id, 'list_ids': total_list, 'loans': total_loan_list})
list_of_vals.append(move_vals)
else:
new_list = move_vals.get('list_ids')
new_list.extend(total_list)
new_loan_list = move_vals.get('loans')
new_loan_list.extend(total_loan_list)
move_vals.update({'list_ids': new_list, 'loans': new_loan_list})
for record in list_of_vals:
new_record_list = record.get('list_ids') + [d for d in total_of_list if
d['journal_id'] == record.get('move')]
new_rec_loan_list = record.get('loans')
merged_list = self.merge_lists(new_record_list, 'name', 'account_id')
record_final_item = merged_list + new_rec_loan_list
if not self.move_id:
move = self.env['account.move'].create({
'state': 'draft',
'journal_id': record.get('move'),
# 'date': fields.Date.context_today(self),
'date': self.date_end,
'ref': self.name,
'line_ids': [(0, 0, item) for item in record_final_item],
'res_model': 'hr.payslip.run',
'res_id': self.id
})
self.move_id = move.id
########################## per_analytic_account ###########
elif self.salary_scale.transfer_type == 'per_analytic_account':
total_of_list = []
journal = self.journal_id
department_totals = {} # Dictionary to store department-wise totals
total_allow, total_ded, total_loan = 0.0, 0.0, 0.0
for line in self.slip_ids:
emp_type = line.employee_id.employee_type_id.id
total_list = []
total_loan_list = []
move_vals = dict()
journal = self.journal_id
if list_of_vals:
for item in list_of_vals:
if item.get('move') == journal.id:
move_vals = item
break
for l in line.allowance_ids:
amount_allow = l.total
# account = l.salary_rule_id.rule_debit_account_id
account = l.salary_rule_id.get_debit_account_id(emp_type)
if not account:
raise UserError(
_('Sorry The Allowance %s is Not account Set') % l.name)
total_list.append({
'name': l.name,
'debit': amount_allow,
'journal_id': journal.id,
'credit': 0,
'account_id': account,
'analytic_account_id': line.employee_id.department_id.analytic_account_id.id,
})
total_allow += amount_allow
for ded in line.deduction_ids:
amount_ded = -ded.total
account = ded.salary_rule_id.get_credit_account_id(emp_type)
# account = ded.salary_rule_id.rule_credit_account_id
if not account:
raise UserError(
_('Sorry The Deduction %s is Not account Set') % ded.name)
total_list.append({
'name': ded.name,
'credit': amount_ded,
'journal_id': journal.id,
'debit': 0,
'account_id': account,
'analytic_account_id': None,
})
total_ded += amount_ded
for lo in line.loan_ids:
amount_loans = -lo.amount
if not lo.account_id:
raise UserError(
_('Sorry The Loan %s is Not account Set') % lo.name)
credit_loans_vals = {
'name': lo.name,
'credit': amount_loans,
'journal_id': journal.id,
'debit': 0,
'account_id': lo.account_id.id,
'analytic_account_id': None,
'partner_id': line.employee_id.user_id.partner_id.id,
}
total_loan += amount_loans
total_loan_list.append(credit_loans_vals)
# Get the department of the employee
department = line.employee_id.department_id
# Add allowance amount to the department total
if department in department_totals:
department_totals[department] += total_allow
else:
department_totals[department] = total_allow
if not move_vals:
move_vals.update({'move': journal.id, 'list_ids': total_list, 'loans': total_loan_list})
list_of_vals.append(move_vals)
else:
new_list = move_vals.get('list_ids')
new_list.extend(total_list)
new_loan_list = move_vals.get('loans')
new_loan_list.extend(total_loan_list)
move_vals.update({'list_ids': new_list, 'loans': new_loan_list})
total_of_list.append({
'name': "Total",
'journal_id': journal.id,
'account_id': journal.default_account_id.id,
'credit': total_allow - total_ded - total_loan,
'debit': 0,
'analytic_account_id': None,
})
# for department, allowance_total in department_totals.items():
# total_of_list.append({
# 'name': f"Total ({department.analytic_account_id.name})",
# 'journal_id': journal.id,
# 'account_id': journal.default_credit_account_id.id,
# 'credit': allowance_total - total_ded - total_loan,
# 'analytic_account_id': department.analytic_account_id.id,
# 'debit': 0,
# })
for record in list_of_vals:
new_record_list = record.get('list_ids') + [d for d in total_of_list if
d['journal_id'] == record.get('move')]
new_rec_loan_list = record.get('loans')
merged_list = self.new_merge_lists(new_record_list, 'name', 'account_id', 'analytic_account_id')
record_final_item = merged_list + new_rec_loan_list
if not self.move_id:
move = self.env['account.move'].create({
'state': 'draft',
'journal_id': record.get('move'),
'date': self.date_end,
'ref': self.name,
'line_ids': [(0, 0, item) for item in record_final_item],
'res_model': 'hr.payslip.run',
'res_id': self.id
})
self.move_id = move.id
# import pdb
# pdb.set_trace()
#####################################
elif self.salary_scale.transfer_type == 'one_by_one':
for line in self.slip_ids:
emp_type = line.employee_id.employee_type_id.id
total_allow, total_ded, total_loan = 0.0, 0.0, 0.0
total_list = []
move_vals = dict()
journal = line.contract_id.journal_id
if not journal:
raise UserError(
_('Sorry The Contract Employee %s is Not Journal Set') % line.employee_id.name)
for l in line.allowance_ids:
amount_allow = l.total
# account = l.salary_rule_id.rule_debit_account_id
account = l.salary_rule_id.get_debit_account_id(emp_type)
if not account:
raise UserError(
_('Sorry The Allowance %s is Not account Set') % l.name)
total_list.append({
'name': l.name,
'debit': amount_allow,
'partner_id': line.employee_id.user_id.partner_id.id,
'credit': 0,
'account_id': account,
'analytic_account_id': line.employee_id.contract_id.analytic_account_id.id,
})
total_allow += amount_allow
for ded in line.deduction_ids:
amount_ded = -ded.total
# account = ded.salary_rule_id.rule_credit_account_id
account = ded.salary_rule_id.get_credit_account_id(emp_type)
if not account:
raise UserError(
_('Sorry The Deduction %s is Not account Set') % ded.name)
total_list.append({
'name': ded.name,
'credit': amount_ded,
'partner_id': line.employee_id.user_id.partner_id.id,
'debit': 0,
'account_id': account,
})
total_ded += amount_ded
for lo in line.loan_ids:
amount_loans = -lo.amount
if not lo.account_id:
raise UserError(
_('Sorry The Loan %s is Not account Set') % lo.name)
credit_loans_vals = {
'name': lo.name,
'credit': amount_loans,
'partner_id': line.employee_id.user_id.partner_id.id,
'debit': 0,
'account_id': lo.account_id.id,
}
total_loan += amount_loans
total_list.append(credit_loans_vals)
# create line for total of all allowance, deduction, loans of all employees
total = total_allow - total_ded - total_loan
total_list.append({
'name': line.name,
'partner_id': line.employee_id.user_id.partner_id.id,
'account_id': line.contract_id.journal_id.default_account_id.id,
'credit': total,
'debit': 0,
})
# print('total list', total_list)
if not move_vals:
move_vals.update({'move': journal.id, 'list_ids': total_list})
list_of_vals.append(move_vals)
else:
new_list = move_vals.get('list_ids')
new_list.extend(total_list)
move_vals.update({'list_ids': new_list})
for record in list_of_vals:
new_record_list = record.get('list_ids')
# merged_list = self.merge_lists(new_record_list, 'name', 'account_id')
# record_final_item = merged_list
if not line.move_id:
move = self.env['account.move'].create({
'state': 'draft',
'partner_id': line.employee_id.user_id.partner_id.id,
'journal_id': line.contract_id.journal_id.id,
# 'date': fields.Date.context_today(self),
'date': self.date_end,
'ref': line.name,
'line_ids': [(0, 0, item) for item in new_record_list],
'res_model': 'hr.payslip.run',
'res_id': self.id
})
line.move_id = move.id
else:
bank_id = ''
for line in self.slip_ids:
emp_type = line.employee_id.employee_type_id.id
total_allow, total_ded, total_loan = 0.0, 0.0, 0.0
total_list = []
total_loan_list = []
move_vals = dict()
if line.employee_id.payment_method == 'bank':
journal = self.env['account.journal'].search([('type', '=', line.employee_id.payment_method),
], limit=1)
if not journal:
raise UserError(' There is no journal For that Bank..'
' Please define a sale journal')
if list_of_vals:
for item in list_of_vals:
if item.get('move') == journal.id:
move_vals = item
break
for l in line.allowance_ids:
amount_allow = l.total
# account = l.salary_rule_id.rule_debit_account_id
account = l.salary_rule_id.get_debit_account_id(emp_type)
if not account:
raise UserError(
_('Sorry The Allowance %s is Not account Set') % l.name)
total_list.append({
'name': l.name,
'debit': amount_allow,
'journal_id': journal.id,
'credit': 0,
'account_id': account,
})
total_allow += amount_allow
for ded in line.deduction_ids:
amount_ded = -ded.total
# account = ded.salary_rule_id.rule_credit_account_id
account = ded.salary_rule_id.get_credit_account_id(emp_type)
if not account:
raise UserError(
_('Sorry The Deduction %s is Not account Set') % ded.name)
total_list.append({
'name': ded.name,
'credit': amount_ded,
'journal_id': journal.id,
'debit': 0,
'account_id': account,
})
total_ded += amount_ded
for lo in line.loan_ids:
amount_loans = -lo.amount
if not lo.account_id:
raise UserError(
_('Sorry The Loan %s is Not account Set') % lo.name)
credit_loans_vals = {
'name': lo.name,
'credit': amount_loans,
'journal_id': journal.id,
'debit': 0,
'account_id': lo.account_id.id,
'partner_id': line.employee_id.user_id.partner_id.id,
}
total_loan += amount_loans
total_loan_list.append(credit_loans_vals)
# create line for total of all allowance, deduction, loans of all employees
total_list.append({
'name': "Total",
'journal_id': journal.id,
'account_id': journal.default_account_id.id,
'credit': total_allow - total_ded - total_loan,
'debit': 0,
})
if not move_vals:
move_vals.update({'move': journal.id, 'list_ids': total_list, 'loans': total_loan_list})
list_of_vals.append(move_vals)
else:
new_list = move_vals.get('list_ids')
new_list.extend(total_list)
new_loan_list = move_vals.get('loans')
new_loan_list.extend(total_loan_list)
move_vals.update({'list_ids': new_list, 'loans': new_loan_list})
bank_id = line.employee_id.bank_account_id.bank_id.name
elif line.employee_id.payment_method == 'cash':
amount, amount1, amount2 = 0.0, 0.0, 0.0
for l in line.allowance_ids:
amount_allow = l.total
# account = l.salary_rule_id.rule_debit_account_id
account = l.salary_rule_id.get_debit_account_id(emp_type)
if not account:
raise UserError(
_('Sorry The Allowance %s is Not account Set') % l.name)
total_list.append({
'name': l.name,
'account_id': account,
'debit': amount_allow,
'credit': 0,
'partner_id': line.employee_id.user_id.partner_id.id
})
amount += amount_allow
total_allow += amount
for ded in line.deduction_ids:
amount_ded = -ded.total
# account = ded.salary_rule_id.rule_credit_account_id
account = ded.salary_rule_id.get_credit_account_id(emp_type)
if not account:
raise UserError(
_('Sorry The Deduction %s is Not account Set') % ded.name)
total_list.append({
'name': ded.name,
'account_id': account,
'credit': amount_ded,
'debit': 0,
'partner_id': line.employee_id.user_id.partner_id.id
})
amount1 += amount_ded
total_ded += amount1
for lo in line.loan_ids:
amount_loans = -lo.amount
if not lo.account_id:
raise UserError(
_('Sorry The Loan %s is Not account Set') % lo.name)
total_list.append({
'name': lo.name,
'account_id': lo.account_id.id,
'credit': amount_loans,
'debit': 0,
'partner_id': line.employee_id.user_id.partner_id.id
})
amount2 += amount_loans
total_loan += amount2
# create line for total of all allowance, deduction, loans of one employee
total = total_allow - total_ded - total_loan
total_list.append({
'name': "Total",
'account_id': line.contract_id.journal_id.default_account_id.id,
'partner_id': line.employee_id.user_id.partner_id.id,
'credit': round(total, 1),
'debit': 0,
})
move = self.env['account.move'].create({
'journal_id': line.contract_id.journal_id.id,
# 'date': fields.Date.context_today(self),
'date': self.date_end,
'ref': "Cash",
'line_ids': [(0, 0, item) for item in total_list]
})
for record in list_of_vals:
new_record_list = record.get('list_ids')
new_rec_loan_list = record.get('loans')
merged_list = self.merge_lists(new_record_list, 'name', 'account_id')
record_final_item = merged_list + new_rec_loan_list
if not line.move_id:
move = self.env['account.move'].create({
'state': 'draft',
'journal_id': record.get('move'),
# 'date': fields.Date.context_today(self),
'date': self.date_end,
'ref': bank_id,
'line_ids': [(0, 0, item) for item in record_final_item],
'res_model': 'hr.payslip.run',
'res_id': self.id
})
line.move_id = move.id
for line in self.slip_ids:
payslip = self.env['hr.payslip'].search([('state', '=', line.state)])
if payslip:
line.write({'state': 'transfered'})
self.write({'state': 'transfered'})