trytonpsk-staff_payroll_co/payroll_auditory.py

292 lines
11 KiB
Python

from trytond.report import Report
from trytond.wizard import (
Wizard, StateView, Button, StateAction, StateReport, StateTransition
)
from trytond.pool import Pool, PoolMeta
class PayrollAuditory(Wizard):
'Payroll Auditory'
__name__ = 'staff.payroll.auditory'
start = StateView('staff.payroll_paycheck.start',
'staff_payroll_co.payroll_auditory_start_view_form', [
Button('Cancel', 'end', 'tryton-cancel'),
Button('Print', 'print_', 'tryton-ok', default=True),
])
print_ = StateReport('staff.payroll.auditory_report')
def do_print_(self, action):
department_id = None
if self.start.department:
department_id = self.start.department.id
periods = [p.id for p in self.start.periods]
periods_name = [p.name for p in self.start.periods]
data = {
'ids': [],
'company': self.start.company.id,
'periods': periods,
'periods_name': periods_name,
'department': department_id,
}
return action, data
def transition_print_(self):
return 'end'
class PayrollAuditoryReport(Report):
__name__ = 'staff.payroll.auditory_report'
@classmethod
def get_domain_payroll(cls, data):
dom_payroll = [
('period', 'in', data['periods']),
('state', '!=', 'draft'),
# ('employee.party.id_number', '=', 1002024128),
]
if data['department']:
dom_payroll.append(
('employee.department', '=', data['department'])
)
return dom_payroll
@classmethod
def get_domain_liquidation(cls, data):
Period = Pool().get('staff.payroll.period')
periods = Period.browse(data['periods'])
date_periods = []
for p in periods:
date_periods.append(p.start)
date_periods.append(p.end)
start_date = min(date_periods)
end_date = max(date_periods)
dom_liquidation = [
('state', '!=', 'draft'),
('liquidation_date', '>=', start_date),
('liquidation_date', '<=', end_date),
# ('employee.party.id_number', '=', 1002024128),
]
if data['department']:
dom_liquidation.append(
('employee.department', '=', data['department'])
)
return dom_liquidation, start_date, end_date
@classmethod
def get_context(cls, records, header, data):
report_context = super().get_context(records, header, data)
pool = Pool()
Company = pool.get('company.company')
Payroll = pool.get('staff.payroll')
PayrollLine = pool.get('staff.payroll.line')
Liquidation = pool.get('staff.liquidation')
LiquidationLine = pool.get('staff.liquidation.line')
company = Company(data['company'])
company_id = company.party.id_number
# process payrolls
dom_payroll = cls.get_domain_payroll(data)
fields_payroll = [
'id', 'employee.party.name', 'employee.party.id_number',
'ibc', 'contract.last_salary', 'employee', 'contract.number',
'employee.afc', 'employee.fvp', 'contract',
]
payrolls = Payroll.search_read(
dom_payroll, fields_names=fields_payroll)
res = {}
payroll_ids = []
for p in payrolls:
key = str(p['employee']) + '_' + str(p['contract'])
try:
res[key]['ibc'] += p['ibc']
except:
res[key] = cls.get_default_values_payroll(p)
res[key]['company_id'] = company_id
payroll_ids += [p['id']]
fields_lines = [
'amount', 'quantity', 'party.name', 'wage_type.type_concept',
'payroll', 'payroll.employee', 'wage_type.name', 'wage_type.uom.symbol',
'payroll.contract', 'wage_type.salary_constitute', 'wage_type.definition',
'wage_type.receipt',
]
dom_line = [
('payroll', 'in', payroll_ids),
('wage_type.provision_cancellation', '=', None),
]
order = [('payroll.employee', 'DESC'), ('payroll', 'ASC')]
payroll_lines = PayrollLine.search_read(
dom_line, fields_names=fields_lines, order=order)
for line in payroll_lines:
cls.process_line(res, line, type_line='payroll')
# process liquidations
dom_liquidation, start_date, end_date = cls.get_domain_liquidation(data)
fields_liquidation = [
'id', 'employee.party.name', 'employee.party.id_number',
'contract.last_salary', 'employee', 'contract.number',
'contract', 'employee.afc', 'employee.fvp'
]
liquidations = Liquidation.search_read(
dom_liquidation, fields_names=fields_liquidation)
liquidation_ids = []
for p in liquidations:
key = str(p['employee']) + '_' + str(p['contract'])
try:
res[key]['ibc'] += [p['ibc'] if p.get('ibc') else 0]
except:
res[key] = cls.get_default_values_payroll(p)
res[key]['company_id'] = company_id
liquidation_ids += [p['id']]
fields_lines = [
'amount', 'party.name', 'wage.type_concept', 'liquidation.kind',
'liquidation', 'liquidation.employee', 'wage.name', 'wage.uom.symbol',
'liquidation.contract', 'wage.salary_constitute', 'wage.definition',
'wage.receipt'
]
dom_line = [
('liquidation', 'in', liquidation_ids),
# ('wage_type.provision_cancellation', '=', None),
]
order = [('liquidation.employee', 'DESC'), ('liquidation', 'ASC')]
liquidation_lines = LiquidationLine.search_read(
dom_line, fields_names=fields_lines, order=order)
for line in liquidation_lines:
cls.process_line(res, line, type_line='liquidation')
cls.process_records(res)
report_context['records'] = res.values()
report_context['company'] = Company(data['company'])
report_context['start_date'] = start_date
report_context['end_date'] = end_date
return report_context
@classmethod
def get_default_values_payroll(cls, p):
value = {
'id_number': p['employee.']['party.']['id_number'],
'contract': p['contract.']['number'],
'salary': p['contract.']['last_salary'],
'ibc': [p['ibc'] if p.get('ibc') else 0],
'benefit_accruals': [],
'worked_day': [],
'unpaid_leave': [],
'overtime_hours': [],
'overgead_hours': [],
'basic_benefits': [],
'vacations_base': [],
'certifiable_non_benefits': [],
'paid_salary': [],
'legal_discounts': [],
'other_discounts': [],
'net_payable': [],
'tax_basis': [],
'social_benefits': [],
'bonus_and_interest': [],
'bonus_paid_fund': [],
'other_payments': [],
'commission': [],
'tax': [],
'health': [],
'retirement': [],
'fsp': [],
}
return value
@classmethod
def process_line(cls, res, line, type_line):
if type_line == 'payroll':
wage = line['wage_type.']
key = str(line['payroll.']['employee'])+ '_' + str(line['payroll.']['contract'])
else:
wage = line['wage.']
key = str(line['liquidation.']['employee'])+ '_' + str(line['liquidation.']['contract'])
concept = wage['type_concept']
name_concept = wage['name'].lower()
concepts_amount = ['health', 'retirement', 'commission', 'tax', 'fsp']
salary_constitute = wage['salary_constitute']
definition = wage['definition']
basic_benefit_exc = ['lic', 'sal', 'vac', 'inc']
amount = int(line['amount'])
if concept in concepts_amount:
res[key][concept] += [amount]
if definition == 'deduction':
res[key]['legal_discounts'] += [amount]
if concept != 'tax':
res[key]['tax_basis'] += [-amount]
elif concept not in concepts_amount and definition in ('deduction', 'discounts'):
res[key]['other_discounts'] += [amount]
elif concept == 'extras' and name_concept.startswith('r'):
res[key]['overgead_hours'] += [line['quantity']]
elif concept == 'extras' and ~name_concept.startswith('r'):
res[key]['overtime_hours'] += [line['quantity']]
elif concept == 'transport' and salary_constitute:
res[key]['certifiable_non_benefits'] += [amount]
elif concept == 'salary':
if definition == 'payment':
res[key]['worked_day'] += [line['quantity']/8 if wage['uom.']['symbol'] != 'd' else line['quantity']]
else:
res[key]['unpaid_leave'] += [line['quantity']/8 if wage['uom.']['symbol'] != 'd' else line['quantity']]
if salary_constitute and name_concept[:3] not in basic_benefit_exc \
and definition == 'payment':
res[key]['basic_benefits'] += [amount]
if concept != 'transport':
res[key]['vacations_base'] += [amount]
if salary_constitute and definition == 'payment' and concept not in ('bonus_service', 'interest', 'unemployment'):
res[key]['tax_basis'] += [amount]
if concept != 'transport':
res[key]['benefit_accruals'] += [amount]
if concept != 'holidays':
res[key]['paid_salary'] += [amount]
if not salary_constitute and wage['receipt'] and definition == 'payment':
res[key]['other_payments'] += [amount]
res[key]['certifiable_non_benefits'] += [amount]
if type_line == 'liquidation':
if concept in ('unemployment', 'interest', 'bonus_service', 'holidays'):
res[key]['certifiable_non_benefits'] += [amount]
if concept in ('unemployment', 'interest'):
if line['liquidation.']['kind'] != 'contract' and concept != 'interest':
res[key]['bonus_paid_fund'] += [amount]
else:
res[key]['bonus_and_interest'] += [amount]
else:
res[key]['social_benefits'] += [amount]
@classmethod
def process_records(cls, records):
vals = ['id_number', 'contract', 'salary', 'company_id']
for rec in records.values():
for k, v in rec.items():
if k not in vals:
try:
# print(k, v)
rec[k] = sum(v)
except:
print(v)