diff --git a/payroll/README.rst b/payroll/README.rst index 68138ba7..70610e71 100644 --- a/payroll/README.rst +++ b/payroll/README.rst @@ -65,6 +65,7 @@ Contributors - Hilar AK - Nimarosa (Nicolas Rodriguez) - Henrik Norlin (@appstogrow) +- Régis Pirard Maintainers ----------- diff --git a/payroll/__manifest__.py b/payroll/__manifest__.py index b23f35e7..d3f35336 100644 --- a/payroll/__manifest__.py +++ b/payroll/__manifest__.py @@ -2,7 +2,7 @@ { "name": "Payroll", - "version": "17.0.1.0.0", + "version": "18.0.1.0.0", "category": "Payroll", "website": "https://github.com/OCA/payroll", "sequence": 38, diff --git a/payroll/models/hr_payroll_structure.py b/payroll/models/hr_payroll_structure.py index f5d9d6d9..a68a27a8 100644 --- a/payroll/models/hr_payroll_structure.py +++ b/payroll/models/hr_payroll_structure.py @@ -59,7 +59,7 @@ def _compute_require_code(self): @api.constrains("parent_id") def _check_parent_id(self): - if not self._check_recursion(): + if self._has_cycle(): raise ValidationError(_("You cannot create a recursive salary structure.")) @api.returns("self", lambda value: value.id) diff --git a/payroll/models/hr_payslip.py b/payroll/models/hr_payslip.py index 88b0ae69..d2c7d376 100644 --- a/payroll/models/hr_payslip.py +++ b/payroll/models/hr_payslip.py @@ -8,9 +8,8 @@ from dateutil.relativedelta import relativedelta from pytz import timezone -from odoo import _, api, fields, models, tools +from odoo import _, api, fields, models from odoo.exceptions import UserError, ValidationError -from odoo.tools.safe_eval import safe_eval from .base_browsable import ( BaseBrowsableObject, @@ -228,34 +227,44 @@ def action_payslip_cancel(self): return self.write({"state": "cancel"}) def refund_sheet(self): + copied_payslips = self.env["hr.payslip"] for payslip in self: + # Create a refund slip copied_payslip = payslip.copy( {"credit_note": True, "name": _("Refund: %s") % payslip.name} ) + # Assign a number number = copied_payslip.number or self.env["ir.sequence"].next_by_code( "salary.slip" ) copied_payslip.write({"number": number}) + # Validated refund slip copied_payslip.with_context( without_compute_sheet=True ).action_payslip_done() + # Write refund reference on payslip + payslip.write( + {"refunded_id": copied_payslip.id if copied_payslip else False} + ) + # Add to list of refund slips + copied_payslips |= copied_payslip + # Action to open list view of refund slips formview_ref = self.env.ref("payroll.hr_payslip_view_form", False) treeview_ref = self.env.ref("payroll.hr_payslip_view_tree", False) res = { "name": _("Refund Payslip"), - "view_mode": "tree, form", + "view_mode": "list, form", "view_id": False, "res_model": "hr.payslip", "type": "ir.actions.act_window", "target": "current", - "domain": "[('id', 'in', %s)]" % copied_payslip.ids, + "domain": [("id", "in", copied_payslips.ids)], "views": [ - (treeview_ref and treeview_ref.id or False, "tree"), + (treeview_ref and treeview_ref.id or False, "list"), (formview_ref and formview_ref.id or False, "form"), ], "context": {}, } - payslip.write({"refunded_id": safe_eval(res["domain"])[0][2][0] or False}) return res def unlink(self): @@ -756,15 +765,14 @@ def onchange_employee(self): def _compute_name(self): for record in self: + date_formatted = babel.dates.format_date( + date=datetime.combine(record.date_from, time.min), + format="MMMM-y", + locale=record.env.context.get("lang") or "en_US", + ) record.name = _("Salary Slip of %(name)s for %(dt)s") % { "name": record.employee_id.name, - "dt": tools.ustr( - babel.dates.format_date( - date=datetime.combine(record.date_from, time.min), - format="MMMM-y", - locale=record.env.context.get("lang") or "en_US", - ) - ), + "dt": str(date_formatted), } @api.onchange("contract_id") diff --git a/payroll/models/hr_salary_rule.py b/payroll/models/hr_salary_rule.py index 2a57eec3..eb89edf6 100644 --- a/payroll/models/hr_salary_rule.py +++ b/payroll/models/hr_salary_rule.py @@ -37,7 +37,7 @@ class HrSalaryRule(models.Model): help="Used to display the salary rule on payslip.", ) parent_rule_id = fields.Many2one( - "hr.salary.rule", string="Parent Salary Rule", index=True + comodel_name="hr.salary.rule", string="Parent Salary Rule", index=True ) company_id = fields.Many2one( "res.company", @@ -167,10 +167,15 @@ class HrSalaryRule(models.Model): @api.constrains("parent_rule_id") def _check_parent_rule_id(self): - if not self._check_recursion(parent="parent_rule_id"): - raise ValidationError( - _("Error! You cannot create recursive hierarchy of Salary Rules.") - ) + if self.env.registry[self._name]._name != "hr.salary.rule": + # HrPayslipLine inherits from "hr.salary.rule" and we don't + # want to do this check on a payslip line + return + for rule in self: + if rule._has_cycle(field_name="parent_rule_id"): + raise ValidationError( + _("Error! You cannot create recursive hierarchy of Salary Rules.") + ) def _recursive_search_of_rules(self): """ diff --git a/payroll/models/hr_salary_rule_category.py b/payroll/models/hr_salary_rule_category.py index 357acbc9..2f2c731d 100644 --- a/payroll/models/hr_salary_rule_category.py +++ b/payroll/models/hr_salary_rule_category.py @@ -45,7 +45,7 @@ def _compute_require_code(self): @api.constrains("parent_id") def _check_parent_id(self): - if not self._check_recursion(): + if self._has_cycle(): raise ValidationError( _( "Error! You cannot create recursive hierarchy of Salary " diff --git a/payroll/readme/CONTRIBUTORS.md b/payroll/readme/CONTRIBUTORS.md index 0bc8d15e..11cb0ddf 100644 --- a/payroll/readme/CONTRIBUTORS.md +++ b/payroll/readme/CONTRIBUTORS.md @@ -3,3 +3,4 @@ - Hilar AK \<\> - Nimarosa (Nicolas Rodriguez) \<\> - Henrik Norlin (@appstogrow) +- Régis Pirard \<\> diff --git a/payroll/static/description/index.html b/payroll/static/description/index.html index 30db5c6f..5ca9bc4c 100644 --- a/payroll/static/description/index.html +++ b/payroll/static/description/index.html @@ -410,6 +410,7 @@

Contributors

  • Hilar AK <hilarak@gmail.com>
  • Nimarosa (Nicolas Rodriguez) <nicolarsande@gmail.com>
  • Henrik Norlin (@appstogrow)
  • +
  • Régis Pirard <regis.pirard@tincid.com>
  • diff --git a/payroll/tests/test_hr_payslip_worked_days.py b/payroll/tests/test_hr_payslip_worked_days.py index 8ffc9b3e..fd2e3460 100644 --- a/payroll/tests/test_hr_payslip_worked_days.py +++ b/payroll/tests/test_hr_payslip_worked_days.py @@ -3,7 +3,7 @@ import time from datetime import date, datetime -from odoo.tests.common import Form +from odoo.tests import Form from .common import TestPayslipBase @@ -20,7 +20,7 @@ def setUp(self): { "name": "TestLeaveType", "code": "TESTLV", - "allocation_validation_type": "no", + "allocation_validation_type": "no_validation", "leave_validation_type": "no_validation", } ) diff --git a/payroll/views/hr_contribution_register_views.xml b/payroll/views/hr_contribution_register_views.xml index af0d99a8..19dc02a6 100644 --- a/payroll/views/hr_contribution_register_views.xml +++ b/payroll/views/hr_contribution_register_views.xml @@ -1,17 +1,17 @@ - hr.contribution.register.tree + hr.contribution.register.list hr.contribution.register - + - + @@ -20,7 +20,7 @@ - +
    @@ -72,7 +72,7 @@ Contribution Registers hr.contribution.register - tree,kanban,form + list,kanban,form

    Add a new contribution register

    diff --git a/payroll/views/hr_payroll_structure_views.xml b/payroll/views/hr_payroll_structure_views.xml index f5c27405..7bad06f7 100644 --- a/payroll/views/hr_payroll_structure_views.xml +++ b/payroll/views/hr_payroll_structure_views.xml @@ -1,10 +1,10 @@ - hr.payroll.structure.tree + hr.payroll.structure.list hr.payroll.structure - + @@ -13,14 +13,14 @@ groups="base.group_multi_company" options="{'no_create': True}" /> - + - hr.payroll.structure.tree + hr.payroll.structure.list hr.payroll.structure - + - + @@ -37,7 +37,7 @@ - +

    @@ -92,13 +92,13 @@ - + - + @@ -108,7 +108,7 @@ Salary Structures hr.payroll.structure - tree,kanban,form + list,kanban,form - hr.payslip.line.tree + hr.payslip.line.list hr.payslip.line - + @@ -18,7 +18,7 @@ - + @@ -62,8 +62,8 @@ - @@ -82,7 +82,7 @@ decoration-success="total > 0 and parent_line_id == False" sum="total_net" /> - + @@ -155,14 +155,14 @@ > Payslip Computation Details hr.payslip.line - tree,pivot,form + list,pivot,form [('slip_id', 'in', active_ids)] Batch Payslip Lines hr.payslip.line - pivot,tree,form + pivot,list,form [('payslip_run_id', 'in', active_ids)] diff --git a/payroll/views/hr_payslip_run_views.xml b/payroll/views/hr_payslip_run_views.xml index 7e9ced07..8228e070 100644 --- a/payroll/views/hr_payslip_run_views.xml +++ b/payroll/views/hr_payslip_run_views.xml @@ -26,10 +26,10 @@ - hr.payslip.run.tree + hr.payslip.run.list hr.payslip.run - - + @@ -62,7 +62,7 @@ - +
    @@ -163,7 +163,7 @@ Payslips Batches hr.payslip.run - tree,kanban,form + list,kanban,form - hr.payslip.tree + hr.payslip.list hr.payslip - + @@ -27,7 +27,7 @@ /> - + @@ -36,7 +36,7 @@ - +
    @@ -183,7 +183,7 @@ name="worked_days_line_ids" readonly="state != 'draft'" > - + @@ -194,7 +194,7 @@ context="{'default_employee_id': parent.employee_id}" /> - +
    @@ -213,7 +213,7 @@ nolabel="1" readonly="state != 'draft'" > - + @@ -224,7 +224,7 @@ context="{'default_employee_id': parent.employee_id}" /> - + @@ -252,7 +252,7 @@ colspan="4" nolabel="1" > - - + @@ -315,11 +315,7 @@ -
    - - - -
    +
    @@ -358,7 +354,7 @@ string="Date" name="date_filter" date="date_to" - default_period="last_month" + default_period="month-1" /> Employee Payslips hr.payslip - tree,kanban,form + list,kanban,form hr.payslip Payslips - tree,form + list,form { 'search_default_employee_id': [active_id], diff --git a/payroll/views/hr_salary_rule_category_views.xml b/payroll/views/hr_salary_rule_category_views.xml index 67e9508b..0845d1ad 100644 --- a/payroll/views/hr_salary_rule_category_views.xml +++ b/payroll/views/hr_salary_rule_category_views.xml @@ -21,10 +21,10 @@ - + - + @@ -41,14 +41,14 @@ - hr.salary.rule.category.tree + hr.salary.rule.category.list hr.salary.rule.category - + - + diff --git a/payroll/views/hr_salary_rule_views.xml b/payroll/views/hr_salary_rule_views.xml index acd4c33c..9c0051db 100644 --- a/payroll/views/hr_salary_rule_views.xml +++ b/payroll/views/hr_salary_rule_views.xml @@ -4,13 +4,13 @@ hr.salary.rule.list hr.salary.rule - + - + @@ -19,7 +19,7 @@ - +
    @@ -48,11 +48,11 @@ - hr.salary.rule.tree + hr.salary.rule.list hr.salary.rule - + @@ -61,7 +61,7 @@ groups="base.group_multi_company" options="{'no_create': True}" /> - + @@ -224,11 +224,11 @@ - - + + - + @@ -364,7 +364,7 @@ Salary Rules hr.salary.rule - tree,kanban,form + list,kanban,form [('parent_rule_id','=',False)] diff --git a/payroll/views/res_config_settings_views.xml b/payroll/views/res_config_settings_views.xml index ebb2f9ae..766a26c6 100644 --- a/payroll/views/res_config_settings_views.xml +++ b/payroll/views/res_config_settings_views.xml @@ -3,7 +3,7 @@ Payroll ir.module.module - kanban,tree,form + kanban,list,form Generate Payslips hr.payslip.employees - tree,form + list,form new diff --git a/payroll/wizard/hr_payslip_change_state.py b/payroll/wizard/hr_payslip_change_state.py index 5457d3b0..676ad8aa 100644 --- a/payroll/wizard/hr_payslip_change_state.py +++ b/payroll/wizard/hr_payslip_change_state.py @@ -83,7 +83,7 @@ def change_state_confirm(self): return { "domain": "[('id','in', [" + ",".join(map(str, record_ids)) + "])]", "name": _("Payslips"), - "view_mode": "tree,form", + "view_mode": "list,form", "res_model": "hr.payslip", "view_id": False, "context": False, diff --git a/payroll/wizard/hr_payslip_change_state_view.xml b/payroll/wizard/hr_payslip_change_state_view.xml index a5c38151..d4ae040e 100644 --- a/payroll/wizard/hr_payslip_change_state_view.xml +++ b/payroll/wizard/hr_payslip_change_state_view.xml @@ -27,7 +27,7 @@ Change state hr.payslip.change.state - form,tree + form,list new