diff --git a/hr_expense_advance_clearing_consolidation/README.rst b/hr_expense_advance_clearing_consolidation/README.rst index c303297f5..b4c7b1e86 100644 --- a/hr_expense_advance_clearing_consolidation/README.rst +++ b/hr_expense_advance_clearing_consolidation/README.rst @@ -7,7 +7,7 @@ Hr Expense Advance Clearing Consolidation !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:7b87b9b5cd2a4d9107cde631255eda39d0f52201c6489ac57d064c7e781688d4 + !! source digest: sha256:2604ed1287fb981afea2d21294c4c1e38f2d872850c6b1bd3d8c578417821623 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png @@ -16,14 +16,14 @@ Hr Expense Advance Clearing Consolidation .. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 -.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fhr-lightgray.png?logo=github - :target: https://github.com/OCA/hr/tree/12.0/hr_expense_advance_clearing_consolidation - :alt: OCA/hr +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fhr--expense-lightgray.png?logo=github + :target: https://github.com/OCA/hr-expense/tree/14.0/hr_expense_advance_clearing_consolidation + :alt: OCA/hr-expense .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/hr-12-0/hr-12-0-hr_expense_advance_clearing_consolidation + :target: https://translation.odoo-community.org/projects/hr-expense-14-0/hr-expense-14-0-hr_expense_advance_clearing_consolidation :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/hr&target_branch=12.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/hr-expense&target_branch=14.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| @@ -38,10 +38,10 @@ This module adds the possibility to consolidate open advances, creating a new ad Bug Tracker =========== -Bugs are tracked on `GitHub Issues `_. +Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -73,6 +73,6 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -This module is part of the `OCA/hr `_ project on GitHub. +This module is part of the `OCA/hr-expense `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/hr_expense_advance_clearing_consolidation/__manifest__.py b/hr_expense_advance_clearing_consolidation/__manifest__.py index 51f3d0112..b0cb8a1f9 100644 --- a/hr_expense_advance_clearing_consolidation/__manifest__.py +++ b/hr_expense_advance_clearing_consolidation/__manifest__.py @@ -2,17 +2,18 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). { - 'name': 'Hr Expense Advance Clearing Consolidation', - 'summary': """ + "name": "Hr Expense Advance Clearing Consolidation", + "summary": """ HR Expense Advance Clearing Consolidation""", - 'version': '12.0.1.0.0', - 'license': 'AGPL-3', - 'author': 'Escodoo,Odoo Community Association (OCA)', - 'website': 'https://github.com/OCA/hr', - 'depends': [ - 'hr_expense_advance_clearing', + "version": "14.0.1.0.0", + "license": "AGPL-3", + "author": "Escodoo,Odoo Community Association (OCA)", + "website": "https://github.com/OCA/hr-expense", + "depends": [ + "hr_expense_advance_clearing", + "account_reconciliation_widget", ], - 'data': [ - 'views/hr_expense_sheet_view.xml', + "data": [ + "views/hr_expense_sheet_view.xml", ], } diff --git a/hr_expense_advance_clearing_consolidation/models/hr_expense_sheet.py b/hr_expense_advance_clearing_consolidation/models/hr_expense_sheet.py index 45fa4a5bc..9001597bf 100644 --- a/hr_expense_advance_clearing_consolidation/models/hr_expense_sheet.py +++ b/hr_expense_advance_clearing_consolidation/models/hr_expense_sheet.py @@ -1,20 +1,18 @@ # Copyright 2022 - TODAY, Marcel Savegnago # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import api, fields, models, _ +from odoo import _, fields, models from odoo.exceptions import UserError class HrExpenseSheet(models.Model): - _inherit = 'hr.expense.sheet' + _inherit = "hr.expense.sheet" is_consolidated_advance = fields.Boolean( - string='Is Consolidated Advance', - readonly=True + string="Is Consolidated Advance", readonly=True ) - @api.multi - def _consolidate_open_advances(self): + def _consolidate_open_advances(self): # noqa: C901 if not len(self) > 1: raise UserError( _( @@ -35,11 +33,11 @@ def _consolidate_open_advances(self): if any(rec.state != "done" for rec in self): raise UserError(_("You cannot consolidate advances that are not paid.")) - if self.env['hr.expense.sheet'].search( + if self.env["hr.expense.sheet"].search( [ - ('advance', '=', False), - ('state', '!=', 'done'), - ('advance_sheet_id', 'in', self.ids) + ("advance", "=", False), + ("state", "!=", "done"), + ("advance_sheet_id", "in", self.ids), ] ): raise UserError( @@ -48,7 +46,6 @@ def _consolidate_open_advances(self): "report that is open." ) ) - writeoff_lines = self.env["account.move.line"] emp_advance = self.env.ref("hr_expense_advance_clearing." "product_emp_advance") @@ -57,14 +54,24 @@ def _consolidate_open_advances(self): for line in advance.sudo().account_move_id.line_ids: if line.account_id == emp_advance.property_account_expense_id: residual_value += line.amount_residual - writeoff_acc_id = self.env["account.account"].search( - [("code", "=", line.counterpart)] - ) - writeoff_journal_id = line.move_id.journal_id - line.reconcile( - writeoff_acc_id=writeoff_acc_id, - writeoff_journal_id=writeoff_journal_id, + + line.reconcile() + + counterpart_line = self.env["account.move.line"].search( + [ + ("move_id", "=", line.move_id.id), + ("account_id", "!=", line.account_id.id), + ] ) + + writeoff_vals = { + "account_id": counterpart_line.account_id.id, + "journal_id": line.move_id.journal_id.id, + } + + writeoff_to_reconcile = line._create_writeoff([writeoff_vals]) + (line + writeoff_to_reconcile).reconcile() + for matched_credit_id in line.matched_credit_ids: for ( move_line @@ -89,12 +96,13 @@ def _consolidate_open_advances(self): "name": "Consolidated Advance", "employee_id": employee.id, "product_id": emp_advance.id, + "account_id": emp_advance.property_account_expense_id.id, "unit_amount": residual_value, "sheet_id": consolidated_advance.id, "advance": True, } ) - consolidated_advance_line._onchange_product_id() + consolidated_advance_line._onchange_product_id_date_account_id() consolidated_advance_line.unit_amount = residual_value # Submitted to Manager @@ -117,29 +125,32 @@ def _consolidate_open_advances(self): if line.debit > 0: aml_to_reconcile_debit |= line - aml._reconcile_lines( - aml_to_reconcile_debit, - aml_to_reconcile_credit, - "amount_residual_currency", - ) - aml_to_reconcile.check_full_reconcile() + aml_to_reconcile.reconcile() consolidated_advance.set_to_paid() self._log_consolidation_open_advance(self, consolidated_advance) return consolidated_advance - @api.multi def consolidate_open_advances(self): if self.env.user.has_group("account.group_account_manager"): self._consolidate_open_advances() else: - raise UserError( - _("You do not have permission to perform this action.") - ) + raise UserError(_("You do not have permission to perform this action.")) - @api.multi def _log_consolidation_open_advance(self, advances, consolidated_advance): - consolidated_advance.message_post(body='%s %s' % (_("Consolidated advances:"), ", ".join('%s (ID %s)' % (p.name or 'n/a', p.id) for p in advances))) + consolidated_advance.message_post( + body="%s %s" + % ( + _("Consolidated advances:"), + ", ".join("%s (ID %s)" % (p.name or "n/a", p.id) for p in advances), + ) + ) for advance in advances: - advance.message_post(body='%s' % (_("This advance was consolidated in the advance: %s (ID %s)") % (consolidated_advance.name or 'n/a', consolidated_advance.id))) + advance.message_post( + body=_("%s") + % ( + _("This advance was consolidated in the advance: %s (ID %s)") + % (consolidated_advance.name or "n/a", consolidated_advance.id) + ) + ) diff --git a/hr_expense_advance_clearing_consolidation/static/description/index.html b/hr_expense_advance_clearing_consolidation/static/description/index.html index e0a63fe05..f595d3dbd 100644 --- a/hr_expense_advance_clearing_consolidation/static/description/index.html +++ b/hr_expense_advance_clearing_consolidation/static/description/index.html @@ -367,9 +367,9 @@

Hr Expense Advance Clearing Consolidation

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:7b87b9b5cd2a4d9107cde631255eda39d0f52201c6489ac57d064c7e781688d4 +!! source digest: sha256:2604ed1287fb981afea2d21294c4c1e38f2d872850c6b1bd3d8c578417821623 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

Beta License: AGPL-3 OCA/hr Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/hr-expense Translate me on Weblate Try me on Runboat

This module adds the possibility to consolidate open advances, creating a new advance with the sum of the residual value of all consolidated advances.

Table of contents

@@ -385,10 +385,10 @@

Hr Expense Advance Clearing Consolidation

Bug Tracker

-

Bugs are tracked on GitHub Issues. +

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -feedback.

+feedback.

Do not contact contributors directly about support or help with technical issues.

@@ -415,7 +415,7 @@

Maintainers

OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.

-

This module is part of the OCA/hr project on GitHub.

+

This module is part of the OCA/hr-expense project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

diff --git a/hr_expense_advance_clearing_consolidation/tests/test_hr_expense_advance_clearing_consolidation.py b/hr_expense_advance_clearing_consolidation/tests/test_hr_expense_advance_clearing_consolidation.py index 0dea0ad5f..7e23245c4 100644 --- a/hr_expense_advance_clearing_consolidation/tests/test_hr_expense_advance_clearing_consolidation.py +++ b/hr_expense_advance_clearing_consolidation/tests/test_hr_expense_advance_clearing_consolidation.py @@ -1,119 +1,147 @@ # Copyright 2019 Kitti Upariphutthiphong # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from odoo import fields +from odoo.exceptions import UserError, ValidationError from odoo.tests import common from odoo.tests.common import Form -from odoo.exceptions import UserError, ValidationError class TestHrExpenseAdvanceClearingConsolidation(common.SavepointCase): - @classmethod def setUpClass(cls): super().setUpClass() - company = cls.env.ref('base.main_company') - cls.journal_bank = cls.env['account.journal'].search( - [('type', '=', 'bank')], limit=1) - cls.product = cls.env['product.product'].create({ - 'name': 'Service 1', - 'type': 'service', - }) - employee_home = cls.env['res.partner'].create({ - 'name': 'Employee Home Address', - }) - cls.employee = cls.env['hr.employee'].create({ - 'name': 'Employee A', - 'address_home_id': employee_home.id, - }) - advance_account = cls.env['account.account'].create({ - 'code': '154000', - 'name': 'Employee Advance', - 'user_type_id': cls.env.ref( - 'account.data_account_type_current_assets').id, - 'reconcile': True, - }) - cls.emp_advance = cls.env.ref('hr_expense_advance_clearing.' - 'product_emp_advance') + cls.env.ref("base.main_company") + cls.journal_bank = cls.env["account.journal"].search( + [("type", "=", "bank")], limit=1 + ) + cls.product = cls.env["product.product"].create( + { + "name": "Service 1", + "type": "service", + } + ) + employee_home = cls.env["res.partner"].create( + { + "name": "Employee Home Address", + } + ) + cls.employee = cls.env["hr.employee"].create( + { + "name": "Employee A", + "address_home_id": employee_home.id, + } + ) + advance_account = cls.env["account.account"].create( + { + "code": "154000", + "name": "Employee Advance", + "user_type_id": cls.env.ref( + "account.data_account_type_current_assets" + ).id, + "reconcile": True, + } + ) + cls.emp_advance = cls.env.ref("hr_expense_advance_clearing.product_emp_advance") cls.emp_advance.property_account_expense_id = advance_account # Create advance expense 1,000 cls.advance1 = cls._create_expense_sheet( - cls, 'Advance1 1,000', cls.employee, cls.emp_advance, 1000.0, - advance=True) + cls, "Advance1 1,000", cls.employee, cls.emp_advance, 1000.0, advance=True + ) cls.advance2 = cls._create_expense_sheet( - cls, 'Advance2 1,000', cls.employee, cls.emp_advance, 1000.0, - advance=True) + cls, "Advance2 1,000", cls.employee, cls.emp_advance, 1000.0, advance=True + ) cls.advance3 = cls._create_expense_sheet( - cls, 'Advance3 1,000', cls.employee, cls.emp_advance, 1000.0, - advance=True) + cls, "Advance3 1,000", cls.employee, cls.emp_advance, 1000.0, advance=True + ) # Create clearing expense 800 cls.clearing_less = cls._create_expense_sheet( - cls, 'Buy service 800', cls.employee, cls.product, 800.0) + cls, "Buy service 800", cls.employee, cls.product, 800.0 + ) # Create clearing expense 800 - not done cls.clearing_not_done = cls._create_expense_sheet( - cls, 'Buy service 800', cls.employee, cls.product, 800.0) - - def _create_expense(self, description, employee, - product, amount, advance=False, - payment_mode='own_account'): - with Form(self.env['hr.expense']) as expense: - expense.advance = advance + cls, "Buy service 800", cls.employee, cls.product, 800.0 + ) + + def _create_expense( + self, + description, + employee, + product, + amount, + advance=False, + payment_mode="own_account", + account=False, + ): + with Form( + self.env["hr.expense"].with_context(default_advance=advance) + ) as expense: expense.name = description expense.employee_id = employee - expense.product_id = product + if not advance: + expense.product_id = product expense.unit_amount = amount expense.payment_mode = payment_mode expense = expense.save() expense.tax_ids = False # Test no vat return expense - def _create_expense_sheet(self, description, employee, - product, amount, advance=False): - expense = self._create_expense(self, description, employee, - product, amount, advance) + def _create_expense_sheet( + self, description, employee, product, amount, advance=False + ): + expense = self._create_expense( + self, description, employee, product, amount, advance + ) # Add expense to expense sheet - expense_sheet = self.env['hr.expense.sheet'].create({ - 'name': description, - 'employee_id': expense.employee_id.id, - 'expense_line_ids': [(6, 0, [expense.id])], - }) + expense_sheet = self.env["hr.expense.sheet"].create( + { + "name": description, + "employee_id": expense.employee_id.id, + "expense_line_ids": [(6, 0, [expense.id])], + } + ) return expense_sheet - def _register_payment(self, expense_sheet, hr_return_advance=False): - ctx = {'active_ids': [expense_sheet.id], - 'active_id': expense_sheet.id, - 'hr_return_advance': hr_return_advance, } - PaymentWizard = self.env['hr.expense.sheet.register.payment.wizard'] + def _register_payment(self, move_id, hr_return_advance=False): + ctx = { + "active_ids": [move_id.id], + "active_id": move_id.id, + "hr_return_advance": hr_return_advance, + "active_model": "account.move", + } + PaymentWizard = self.env["account.payment.register"] with Form(PaymentWizard.with_context(ctx)) as f: f.journal_id = self.journal_bank + f.payment_date = fields.Date.today() payment_wizard = f.save() - payment_wizard.expense_post_payment() + payment_wizard.action_create_payments() def test_0_test_constraints(self): - """ Test some constraints """ + """Test some constraints""" # Advance Sheet can't be clearing at the same time. with self.assertRaises(ValidationError): self.advance1.advance_sheet_id = self.advance1 def test_1_consolidate_open_advances(self): - """ When clear less than advance, do return advance """ + """When clear less than advance, do return advance""" # ------------------ Advance1 -------------------------- self.advance1.action_submit_sheet() self.advance1.approve_expense_sheets() self.advance1.action_sheet_move_create() self.assertEqual(self.advance1.clearing_residual, 1000.0) - self._register_payment(self.advance1) - self.assertEqual(self.advance1.state, 'done') + self._register_payment(self.advance1.account_move_id) + self.assertEqual(self.advance1.state, "done") # ------------------ Advance2 -------------------------- self.advance2.action_submit_sheet() self.advance2.approve_expense_sheets() self.advance2.action_sheet_move_create() self.assertEqual(self.advance2.clearing_residual, 1000.0) - self._register_payment(self.advance2) - self.assertEqual(self.advance2.state, 'done') + self._register_payment(self.advance2.account_move_id) + self.assertEqual(self.advance2.state, "done") # ------------------ Clearing -------------------------- # Clear this with previous advance @@ -123,7 +151,7 @@ def test_1_consolidate_open_advances(self): self.clearing_less.approve_expense_sheets() self.clearing_less.action_sheet_move_create() # Less amount, state set to done. Still remain 200 to be returned - self.assertEqual(self.clearing_less.state, 'done') + self.assertEqual(self.clearing_less.state, "done") self.assertEqual(self.clearing_less.advance_sheet_residual, 200.0) # Consolidation advance1 and advance2 @@ -132,7 +160,7 @@ def test_1_consolidate_open_advances(self): self.assertTrue(consolidated_advance) self.assertEqual(consolidated_advance.clearing_residual, 1200.0) - self.assertEqual(consolidated_advance.state, 'done') + self.assertEqual(consolidated_advance.state, "done") # Try consolidate only one advance with self.assertRaises(UserError): @@ -154,8 +182,8 @@ def test_1_consolidate_open_advances(self): with self.assertRaises(UserError): advances._consolidate_open_advances() - self._register_payment(self.advance3) - self.assertEqual(self.advance3.state, 'done') + self._register_payment(self.advance3.account_move_id) + self.assertEqual(self.advance3.state, "done") # Try consolidate advance3 clearing_not_done and consolidated_advance self.clearing_not_done.advance_sheet_id = self.advance3 diff --git a/hr_expense_advance_clearing_consolidation/views/hr_expense_sheet_view.xml b/hr_expense_advance_clearing_consolidation/views/hr_expense_sheet_view.xml index 6c998b83a..a5bd31b4b 100644 --- a/hr_expense_advance_clearing_consolidation/views/hr_expense_sheet_view.xml +++ b/hr_expense_advance_clearing_consolidation/views/hr_expense_sheet_view.xml @@ -1,23 +1,31 @@ - hr.expense.sheet.tree (in hr_expense_advance_clearing_consolidation) + hr.expense.sheet.tree (in hr_expense_advance_clearing_consolidation) hr.expense.sheet - + - + - - hr.expense.sheet.filter (in hr_expense_advance_clearing_consolidation) + + hr.expense.sheet.search (in hr_expense_advance_clearing_consolidation) hr.expense.sheet - + - + @@ -25,8 +33,8 @@ Consolidate Open Advances ir.actions.server - - + + code if records: