mirror of
https://gitlab.com/hibou-io/hibou-odoo/suite.git
synced 2025-01-20 12:37:31 +02:00
[MIG] hr_payroll_slip_ytd: migrate to 13.0
H4817
This commit is contained in:
committed by
Jared Kipe
parent
673f4a34d5
commit
444a1ce47a
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
'name': 'Payroll Report Year to Date',
|
'name': 'Payroll Report Year to Date',
|
||||||
'author': 'Hibou Corp. <hello@hibou.io>',
|
'author': 'Hibou Corp. <hello@hibou.io>',
|
||||||
'version': '12.0.1.1.0',
|
'version': '13.0.1.1.0',
|
||||||
'category': 'Human Resources',
|
'category': 'Human Resources',
|
||||||
'sequence': 95,
|
'sequence': 95,
|
||||||
'summary': 'Show YTD computations on Payslip Report',
|
'summary': 'Show YTD computations on Payslip Report',
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ class Payslip(models.Model):
|
|||||||
def ytd(self, code, allow_draft=False):
|
def ytd(self, code, allow_draft=False):
|
||||||
to_date = self.date_to
|
to_date = self.date_to
|
||||||
from_date = str(self.date_to.year) + '-01-01'
|
from_date = str(self.date_to.year) + '-01-01'
|
||||||
state_allowed = ('done', 'verify') if not allow_draft else ('done', 'verify', 'draft')
|
state_allowed = ('done',) if not allow_draft else ('done', 'verify', 'draft')
|
||||||
self.env.cr.execute("""
|
self.env.cr.execute("""
|
||||||
SELECT sum(total) as total,
|
SELECT sum(pi.total) as total,
|
||||||
sum(quantity) as quantity,
|
sum(pi.quantity) as quantity,
|
||||||
sum(amount) as amount
|
sum(pi.amount) as amount
|
||||||
FROM hr_payslip as hp
|
FROM hr_payslip as hp
|
||||||
JOIN hr_payslip_line as pi ON hp.id = pi.slip_id
|
JOIN hr_payslip_line as pi ON hp.id = pi.slip_id
|
||||||
WHERE hp.employee_id = %s
|
WHERE hp.employee_id = %s
|
||||||
@@ -26,3 +26,24 @@ class Payslip(models.Model):
|
|||||||
else:
|
else:
|
||||||
res = {'total': 0.0, 'quantity': 0.0, 'amount': 0.0}
|
res = {'total': 0.0, 'quantity': 0.0, 'amount': 0.0}
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
def worked_ytd(self, code, allow_draft=False):
|
||||||
|
to_date = self.date_to
|
||||||
|
from_date = str(self.date_to.year) + '-01-01'
|
||||||
|
state_allowed = ('done',) if not allow_draft else ('done', 'verify', 'draft')
|
||||||
|
self.env.cr.execute("""
|
||||||
|
SELECT sum(wd.amount) as amount
|
||||||
|
FROM hr_payslip as hp
|
||||||
|
JOIN hr_payslip_worked_days as wd ON hp.id = wd.payslip_id
|
||||||
|
JOIN hr_work_entry_type as wt ON wd.work_entry_type_id = wt.id
|
||||||
|
WHERE hp.employee_id = %s
|
||||||
|
AND hp.state in %s
|
||||||
|
AND hp.date_to >= %s AND hp.date_to <= %s AND wt.code = %s""",
|
||||||
|
(self.employee_id.id, state_allowed, from_date, to_date, code))
|
||||||
|
res = self.env.cr.dictfetchone()
|
||||||
|
if res:
|
||||||
|
# Can return dictionary with NULL aka Nones
|
||||||
|
res['amount'] = res.get('amount', 0.0)
|
||||||
|
else:
|
||||||
|
res = {'amount': 0.0}
|
||||||
|
return res
|
||||||
|
|||||||
@@ -1,31 +1,54 @@
|
|||||||
from odoo.addons.hr_payroll.tests.common import TestPayslipBase
|
from odoo.addons.hr_payroll.tests.common import TestPayslipBase
|
||||||
|
from odoo.tests.common import Form
|
||||||
|
from datetime import date
|
||||||
|
|
||||||
|
|
||||||
class TestPayslipYtd(TestPayslipBase):
|
class TestPayslipYtd(TestPayslipBase):
|
||||||
def test_00_payslip_ytd(self):
|
def test_00_payslip_ytd(self):
|
||||||
richard_payslip = self.env['hr.payslip'].create({
|
# The common test leaves the contract in draft mode
|
||||||
'name': 'Payslip of Richard',
|
richard_contract = self.richard_emp.contract_ids[0]
|
||||||
'employee_id': self.richard_emp.id,
|
richard_contract.state = 'open'
|
||||||
'contract_id': self.richard_emp.contract_id.id,
|
# pay structure in TestPayslipBase is missing default Salary Rules
|
||||||
|
# I don't need all of them, but I would like to use Basic Salary
|
||||||
|
self.developer_pay_structure.write({
|
||||||
|
'rule_ids': [(4, self.env['hr.salary.rule'].search([('code', '=', 'BASIC')], limit=1).id)]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
payslip_form = Form(self.env['hr.payslip'])
|
||||||
|
payslip_form.employee_id = self.richard_emp
|
||||||
|
payslip_form.date_from = date(2020, 1, 1)
|
||||||
|
payslip_form.date_to = date(2020, 1, 31)
|
||||||
|
richard_payslip = payslip_form.save()
|
||||||
|
|
||||||
richard_payslip.compute_sheet()
|
richard_payslip.compute_sheet()
|
||||||
richard_payslip.action_payslip_done()
|
richard_payslip.action_payslip_done()
|
||||||
|
richard_payslip.flush() # Didn't have to do this in 12, but now the test fails if I don't
|
||||||
|
|
||||||
basic_line = richard_payslip.line_ids.filtered(lambda l: l.code == 'BASIC')
|
basic_line = richard_payslip.line_ids.filtered(lambda l: l.code == 'BASIC')
|
||||||
self.assertEqual(basic_line.amount, 5000.0)
|
self.assertEqual(basic_line.amount, 5000.0)
|
||||||
ytd = richard_payslip.ytd('BASIC', allow_draft=False)
|
self.assertEqual(basic_line.total, 5000.0)
|
||||||
|
ytd = richard_payslip.ytd(basic_line.code, allow_draft=False)
|
||||||
self.assertEqual(ytd, {'total': 5000.0, 'quantity': 1.0, 'amount': 5000.0})
|
self.assertEqual(ytd, {'total': 5000.0, 'quantity': 1.0, 'amount': 5000.0})
|
||||||
|
|
||||||
richard_payslip_next = self.env['hr.payslip'].create({
|
# get worked days
|
||||||
'name': 'Payslip of Richard',
|
self.assertTrue(richard_payslip.worked_days_line_ids)
|
||||||
'employee_id': self.richard_emp.id,
|
worked_day_line = richard_payslip.worked_days_line_ids.filtered(lambda l: l.code == 'WORK100')
|
||||||
'contract_id': self.richard_emp.contract_id.id,
|
self.assertEqual(worked_day_line.amount, 5000.0)
|
||||||
})
|
worked_day_ytd = richard_payslip.worked_ytd(worked_day_line.code, allow_draft=False)
|
||||||
|
self.assertEqual(worked_day_ytd, {'amount': 5000.0})
|
||||||
|
|
||||||
|
payslip_form = Form(self.env['hr.payslip'])
|
||||||
|
payslip_form.employee_id = self.richard_emp
|
||||||
|
payslip_form.date_from = date(2020, 2, 1)
|
||||||
|
payslip_form.date_to = date(2020, 2, 29)
|
||||||
|
richard_payslip_next = payslip_form.save()
|
||||||
richard_payslip_next.compute_sheet()
|
richard_payslip_next.compute_sheet()
|
||||||
|
richard_payslip_next.flush()
|
||||||
|
|
||||||
basic_line = richard_payslip_next.line_ids.filtered(lambda l: l.code == 'BASIC')
|
basic_line = richard_payslip_next.line_ids.filtered(lambda l: l.code == 'BASIC')
|
||||||
self.assertEqual(basic_line.amount, 5000.0)
|
self.assertEqual(basic_line.amount, 5000.0)
|
||||||
ytd = richard_payslip_next.ytd('BASIC', allow_draft=True)
|
self.assertEqual(basic_line.total, 5000.0)
|
||||||
|
ytd = richard_payslip_next.ytd(basic_line.code, allow_draft=True)
|
||||||
self.assertEqual(ytd, {'total': 10000.0, 'quantity': 2.0, 'amount': 10000.0})
|
self.assertEqual(ytd, {'total': 10000.0, 'quantity': 2.0, 'amount': 10000.0})
|
||||||
ytd = richard_payslip_next.ytd('BASIC', allow_draft=False)
|
ytd = richard_payslip_next.ytd(basic_line.code, allow_draft=False)
|
||||||
self.assertEqual(ytd, {'total': 5000.0, 'quantity': 1.0, 'amount': 5000.0})
|
self.assertEqual(ytd, {'total': 5000.0, 'quantity': 1.0, 'amount': 5000.0})
|
||||||
|
|||||||
@@ -1,15 +1,39 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<odoo>
|
<odoo>
|
||||||
<template id="report_payslip_inherit" name="Payslip YTD" inherit_id="hr_payroll.report_payslip">
|
<template id="report_payslip_inherit" name="Payslip YTD" inherit_id="hr_payroll.report_payslip">
|
||||||
|
<!-- Add YTD to basic salary summary -->
|
||||||
|
<xpath expr="//table[3]/tr" position="inside">
|
||||||
|
<t t-set="ytd" t-value="o.ytd('BASIC', allow_draft=True)"/>
|
||||||
|
<td><strong>YTD</strong></td>
|
||||||
|
<td><span t-esc="ytd.get('total', 0.0)" t-options="{"widget": "monetary", "display_currency": o.company_id.currency_id}"/></td>
|
||||||
|
</xpath>
|
||||||
|
|
||||||
<!-- Add YTD to the table head-->
|
<!-- Add YTD to the table head-->
|
||||||
<xpath expr="//table[2]/thead/tr//th[last()]" position="after">
|
<xpath expr="//table[4]/thead/tr//th[last()]" position="after">
|
||||||
|
<th>Total</th>
|
||||||
<th>YTD Quantity</th>
|
<th>YTD Quantity</th>
|
||||||
<th>YTD Amount</th>
|
<th>YTD Amount</th>
|
||||||
<th>YTD Total</th>
|
<th>YTD Total</th>
|
||||||
</xpath>
|
</xpath>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Add YTD worked days data -->
|
||||||
|
<xpath expr="//table[4]/tbody/tr[1]/td[last()]" position="after">
|
||||||
|
<t t-set="worked_ytd" t-value="o.worked_ytd(worked_days.code, allow_draft=True)"/>
|
||||||
|
<td/>
|
||||||
|
<td/>
|
||||||
|
<td><span t-esc="worked_ytd.get('amount', 0.0)" t-options="{"widget": "monetary", "display_currency": o.company_id.currency_id}"/></td>
|
||||||
|
<td/>
|
||||||
|
</xpath>
|
||||||
|
|
||||||
|
<!-- Re-add column for line amount -->
|
||||||
|
<xpath expr="//table[4]/tbody/tr[2]/td[last()]" position="before">
|
||||||
|
<td><span t-esc="line.amount"
|
||||||
|
t-options='{"widget": "monetary", "display_currency": o.company_id.currency_id}'/></td>
|
||||||
|
</xpath>
|
||||||
|
|
||||||
<!-- Add YTD table data-->
|
<!-- Add YTD table data-->
|
||||||
<xpath expr="//table[2]/tbody//td[last()]" position="after">
|
<xpath expr="//table[4]/tbody/tr[2]/td[last()]" position="after">
|
||||||
<t t-set="ytd" t-value="o.ytd(line.code, allow_draft=True)"/>
|
<t t-set="ytd" t-value="o.ytd(line.code, allow_draft=True)"/>
|
||||||
<td><span t-esc="ytd.get('quantity', 0.0)"/></td>
|
<td><span t-esc="ytd.get('quantity', 0.0)"/></td>
|
||||||
<td><span t-esc="ytd.get('amount', 0.0)" t-options="{"widget": "monetary", "display_currency": o.company_id.currency_id}"/></td>
|
<td><span t-esc="ytd.get('amount', 0.0)" t-options="{"widget": "monetary", "display_currency": o.company_id.currency_id}"/></td>
|
||||||
|
|||||||
Reference in New Issue
Block a user