mirror of
https://bitbucket.org/presik/trytonpsk-staff_payroll_co.git
synced 2023-12-14 06:42:56 +01:00
Add adjust payment/discount partial sunday
This commit is contained in:
parent
ed958568c7
commit
a76b7cc289
|
@ -1,5 +1,5 @@
|
|||
#This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
#this repository contains the full copyright notices and license terms.
|
||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
from trytond.pool import Pool
|
||||
import wage_type
|
||||
import payroll
|
||||
|
@ -10,7 +10,7 @@ import employee
|
|||
import uvt
|
||||
import event_category
|
||||
import account
|
||||
import liquidation
|
||||
|
||||
|
||||
def register():
|
||||
Pool.register(
|
||||
|
@ -36,7 +36,6 @@ def register():
|
|||
event_category.EventCategory,
|
||||
payroll.OpenPayrollByPeriodStart,
|
||||
payroll.PayrollByPeriodDynamic,
|
||||
payroll.FixPayrollStart,
|
||||
account.SeverancePayClearingStart,
|
||||
account.SeverancePayClearingDone,
|
||||
payroll.Exo2276Start,
|
||||
|
@ -62,7 +61,6 @@ def register():
|
|||
payroll.PayrollSheet,
|
||||
payroll.PayrollGroup,
|
||||
payroll.OpenPayrollByPeriod,
|
||||
payroll.FixPayroll,
|
||||
account.SeverancePayClearing,
|
||||
payroll.Exo2276,
|
||||
payroll.IncomeWithholdings,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
#this repository contains the full copyright notices and license terms.
|
||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
from trytond.model import fields
|
||||
from trytond.pool import PoolMeta
|
||||
|
||||
|
@ -7,8 +7,7 @@ from trytond.pool import PoolMeta
|
|||
__all__ = ['Configuration']
|
||||
|
||||
|
||||
class Configuration:
|
||||
__metaclass__ = PoolMeta
|
||||
class Configuration(metaclass=PoolMeta):
|
||||
__name__ = "staff.configuration"
|
||||
staff_liquidation_sequence = fields.Many2One('ir.sequence',
|
||||
'Liquidation Sequence', required=True, domain=[
|
||||
|
@ -20,4 +19,4 @@ class Configuration:
|
|||
'Liquidation Account', domain=[
|
||||
('kind', '=', 'payable'),
|
||||
], required=True)
|
||||
|
||||
payment_partial_sunday = fields.Boolean('Payment Partial Sunday')
|
||||
|
|
|
@ -21,6 +21,7 @@ STATES = {'readonly': (Eval('state') != 'draft')}
|
|||
_ZERO = Decimal('0.0')
|
||||
|
||||
BONUS_SERVICE = ['bonus_service']
|
||||
|
||||
CONTRACT = [
|
||||
'bonus_service', 'health', 'retirement', 'unemployment', 'interest',
|
||||
'holidays'
|
||||
|
@ -119,22 +120,22 @@ class Liquidation(Workflow, ModelSQL, ModelView):
|
|||
('posted', 'draft'),
|
||||
))
|
||||
cls._buttons.update({
|
||||
'draft': {
|
||||
'invisible': Eval('state') == 'draft',
|
||||
},
|
||||
'confirm': {
|
||||
'invisible': Eval('state') != 'draft',
|
||||
},
|
||||
'cancel': {
|
||||
'invisible': Eval('state') != 'draft',
|
||||
},
|
||||
'post': {
|
||||
'invisible': Eval('state') != 'confirmed',
|
||||
},
|
||||
'compute_liquidation': {
|
||||
'invisible': Bool(Eval('lines')),
|
||||
},
|
||||
})
|
||||
'draft': {
|
||||
'invisible': Eval('state') == 'draft',
|
||||
},
|
||||
'confirm': {
|
||||
'invisible': Eval('state') != 'draft',
|
||||
},
|
||||
'cancel': {
|
||||
'invisible': Eval('state') != 'draft',
|
||||
},
|
||||
'post': {
|
||||
'invisible': Eval('state') != 'confirmed',
|
||||
},
|
||||
'compute_liquidation': {
|
||||
'invisible': Bool(Eval('lines')),
|
||||
},
|
||||
})
|
||||
|
||||
@staticmethod
|
||||
def default_company():
|
||||
|
|
89
payroll.py
89
payroll.py
|
@ -2,7 +2,7 @@
|
|||
# this repository contains the full copyright notices and license terms.
|
||||
import calendar
|
||||
from decimal import Decimal
|
||||
from datetime import date
|
||||
from datetime import date, timedelta
|
||||
import math
|
||||
from trytond.model import ModelView, fields, Workflow
|
||||
from trytond.pool import Pool, PoolMeta
|
||||
|
@ -74,45 +74,32 @@ ENTITY_ACCOUNTS = {
|
|||
class PayrollLine(metaclass=PoolMeta):
|
||||
__name__ = "staff.payroll.line"
|
||||
|
||||
# BUG BUG BUG BUG BUG BUG BUG BUG
|
||||
# def get_amount(self, name):
|
||||
# amount = super(PayrollLine, self).get_amount(name)
|
||||
# if amount and self.wage_type and self.wage_type.round_amounts:
|
||||
# if self.wage_type.round_amounts == 'above_amount':
|
||||
# amount = math.ceil(float(amount) / 100.0) * 100
|
||||
# elif self.wage_type.round_amounts == 'under_amount':
|
||||
# amount = math.floor(float(amount) / 100.0) * 100
|
||||
# elif self.wage_type.round_amounts == 'automatic':
|
||||
# amount = round(amount, -2)
|
||||
# return amount
|
||||
|
||||
|
||||
class Payroll(metaclass=PoolMeta):
|
||||
__name__ = "staff.payroll"
|
||||
last_payroll = fields.Boolean('Last Payroll', states=STATES, select=True)
|
||||
ibc = fields.Function(fields.Numeric('IBC'), 'on_change_with_ibc')
|
||||
health_amount = fields.Function(fields.Numeric('EPS Amount'),
|
||||
'get_non_fiscal_amount')
|
||||
'get_non_fiscal_amount')
|
||||
retirement_amount = fields.Function(fields.Numeric('AFP Amount'),
|
||||
'get_non_fiscal_amount')
|
||||
'get_non_fiscal_amount')
|
||||
risk_amount = fields.Function(fields.Numeric('ARL Amount'),
|
||||
'get_non_fiscal_amount')
|
||||
'get_non_fiscal_amount')
|
||||
box_family_amount = fields.Function(fields.Numeric('Box Amount'),
|
||||
'get_non_fiscal_amount')
|
||||
absenteeism_days = fields.Integer("Absenteeism Days",
|
||||
states=STATES)
|
||||
'get_non_fiscal_amount')
|
||||
absenteeism_days = fields.Integer("Absenteeism Days", states=STATES)
|
||||
department = fields.Many2One('company.department', 'Department',
|
||||
required=False, depends=['employee'])
|
||||
required=False, depends=['employee'])
|
||||
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(Payroll, cls).__setup__()
|
||||
cls._error_messages.update({
|
||||
'period_without_contract': ('The period selected without contract'
|
||||
' for the employee!'),
|
||||
'period_without_contract': (
|
||||
'The period selected without contract for the employee!'
|
||||
),
|
||||
'error_report': ('Error %s !'),
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
@fields.depends('end', 'date_effective')
|
||||
def on_change_with_date_effective(self):
|
||||
|
@ -182,11 +169,37 @@ class Payroll(metaclass=PoolMeta):
|
|||
if not self.description and self.period:
|
||||
self.description = self.period.description
|
||||
|
||||
def adjust_partial_sunday(self, quantity):
|
||||
# Factor = 8 hour sunday / 6 days (monday-saturday)
|
||||
factor = 1.33
|
||||
if self.is_first_payroll():
|
||||
delta_days = (self.end - self.start).days
|
||||
_sunday = False
|
||||
for dd in range(delta_days):
|
||||
next_day = self.start + timedelta(days=dd)
|
||||
if next_day.weekday() == 6:
|
||||
_sunday = True
|
||||
break
|
||||
|
||||
if _sunday:
|
||||
fix_qty = self.start.weekday() * factor
|
||||
quantity = Decimal(str(round(quantity - fix_qty, 2)))
|
||||
|
||||
# FIXME
|
||||
# if self.is_last_payroll:
|
||||
# pass
|
||||
return quantity
|
||||
|
||||
def _get_line_quantity(self, quantity_days, wage, extras, discount):
|
||||
Configuration = Pool().get('staff.configuration')
|
||||
config = Configuration(1)
|
||||
quantity_days = self.get_days(self.start, self.end, wage)
|
||||
quantity = super(Payroll, self)._get_line_quantity(
|
||||
quantity_days, wage, extras, discount
|
||||
)
|
||||
|
||||
if config.payment_partial_sunday and wage.type_concept == 'salary':
|
||||
quantity = self.adjust_partial_sunday(quantity)
|
||||
return quantity
|
||||
|
||||
@fields.depends('start', 'end', 'employee', 'period', 'contract')
|
||||
|
@ -217,24 +230,6 @@ class Payroll(metaclass=PoolMeta):
|
|||
res = super(Payroll, self).get_salary_full(wage)
|
||||
salary_pae = _ZERO
|
||||
salary_full = res['salary']
|
||||
|
||||
"""
|
||||
if wage.type_concept in ('health', 'retirement', 'fsp', 'tax', 'box_family') \
|
||||
and self.kind == 'special':
|
||||
# PAE: Payroll Accrual Entry
|
||||
salary_pae = self._compute_apply_special_salary()
|
||||
if self.last_payroll:
|
||||
payrolls = self.search([
|
||||
('employee', '=', self.employee.id),
|
||||
('start', '>=', date(self.start.year, 1, 1)),
|
||||
('start', '<=', date(self.start.year, 12, 31)),
|
||||
])
|
||||
hoard_holidays = self._compute_hoard(
|
||||
[p.id for p in payrolls],
|
||||
['holidays']
|
||||
)
|
||||
salary_pae += hoard_holidays
|
||||
"""
|
||||
if wage.month_application:
|
||||
if self._is_last_payroll_month():
|
||||
salary_full_month = self.search_salary_month(wage)
|
||||
|
@ -256,7 +251,7 @@ class Payroll(metaclass=PoolMeta):
|
|||
|
||||
def is_first_payroll(self):
|
||||
if self.start <= self.contract.start_date <= self.end:
|
||||
pass
|
||||
return True
|
||||
return False
|
||||
|
||||
def _is_last_payroll_month(self):
|
||||
|
@ -313,18 +308,10 @@ class Payroll(metaclass=PoolMeta):
|
|||
|
||||
def search_salary_month(self, wage):
|
||||
res = _ZERO
|
||||
Configuration = Pool().get('staff.configuration')
|
||||
config = Configuration(1)
|
||||
payrolls = self._get_payrolls_month()
|
||||
# payrolls_contract = {}
|
||||
# contract_id_payrolls = [payroll.contract.id for payroll in payrolls]
|
||||
if payrolls:
|
||||
# num_subperiod = 30 / config.default_liquidation_period
|
||||
# if len(payrolls) >= num_subperiod:
|
||||
for payroll in payrolls:
|
||||
res += payroll.compute_salary_full(wage)
|
||||
# if payroll.contract:
|
||||
# payrolls_contract[payroll.contract.id] = res
|
||||
return res
|
||||
|
||||
def get_line(self, wage, qty, unit_value, party=None):
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[tryton]
|
||||
version=5.0.2
|
||||
version=5.0.3
|
||||
depends:
|
||||
company
|
||||
company_department
|
||||
|
|
|
@ -12,5 +12,7 @@ this repository contains the full copyright notices and license terms. -->
|
|||
<field name="uvt_value"/>
|
||||
<label name="liquidation_account"/>
|
||||
<field name="liquidation_account"/>
|
||||
<label name="payment_partial_sunday"/>
|
||||
<field name="payment_partial_sunday"/>
|
||||
</xpath>
|
||||
</data>
|
||||
|
|
Loading…
Reference in a new issue