diff --git a/.copier-answers.yml b/.copier-answers.yml index 9a30d3d52..25f740dea 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,5 +1,5 @@ # Do NOT update manually; changes here will be overwritten by Copier -_commit: v1.14.1 +_commit: v1.14.2 _src_path: gh:oca/oca-addons-repo-template ci: GitHub dependency_installation_mode: PIP diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 49459d14a..34b575644 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -101,7 +101,7 @@ repos: - id: pyupgrade args: ["--keep-percent-format"] - repo: https://github.com/PyCQA/isort - rev: 5.5.1 + rev: 5.12.0 hooks: - id: isort name: isort except __init__.py diff --git a/README.md b/README.md index 33731715c..1c2fd6f2d 100644 --- a/README.md +++ b/README.md @@ -23,48 +23,54 @@ addon | version | maintainers | summary --- | --- | --- | --- [account_account_constraint_code](account_account_constraint_code/) | 14.0.1.0.0 | | Forbid modification of code when account move line linked to the account [account_asset_batch_compute](account_asset_batch_compute/) | 14.0.1.0.0 | | Add the possibility to compute assets in batch +[account_asset_compute_batch](account_asset_compute_batch/) | 14.0.1.0.0 | | Assets - Compute Depre. in Batch +[account_asset_from_expense](account_asset_from_expense/) | 14.0.1.0.0 | | Assets from Expenses [account_asset_low_value](account_asset_low_value/) | 14.0.1.0.0 | [![kittiu](https://github.com/kittiu.png?size=30px)](https://github.com/kittiu) | Assets Management - Low Value Asset -[account_asset_management](account_asset_management/) | 14.0.2.8.1 | | Assets Management +[account_asset_management](account_asset_management/) | 14.0.3.1.1 | | Assets Management [account_asset_management_menu](account_asset_management_menu/) | 14.0.1.0.0 | | Assets Management Menu [account_asset_number](account_asset_number/) | 14.0.1.0.0 | | Assets Number [account_asset_transfer](account_asset_transfer/) | 14.0.1.0.1 | [![kittiu](https://github.com/kittiu.png?size=30px)](https://github.com/kittiu) | Asset Transfer from AUC to Asset [account_balance_line](account_balance_line/) | 14.0.1.1.0 | | Display balance totals in move line view -[account_cash_deposit](account_cash_deposit/) | 14.0.1.1.0 | | Manage cash deposits and cash orders -[account_chart_update](account_chart_update/) | 14.0.2.0.5 | | Wizard to update a company's account chart from a template -[account_check_deposit](account_check_deposit/) | 14.0.1.1.0 | | Manage deposit of checks to the bank +[account_cash_deposit](account_cash_deposit/) | 14.0.1.2.0 | | Manage cash deposits and cash orders +[account_chart_update](account_chart_update/) | 14.0.2.1.1 | | Wizard to update a company's account chart from a template +[account_check_deposit](account_check_deposit/) | 14.0.1.2.0 | | Manage deposit of checks to the bank [account_fiscal_month](account_fiscal_month/) | 14.0.1.0.0 | | Provide a fiscal month date range type [account_fiscal_position_vat_check](account_fiscal_position_vat_check/) | 14.0.1.2.0 | | Check VAT on invoice validation -[account_fiscal_year](account_fiscal_year/) | 14.0.1.2.0 | [![eLBati](https://github.com/eLBati.png?size=30px)](https://github.com/eLBati) | Create Account Fiscal Year +[account_fiscal_year](account_fiscal_year/) | 14.0.1.2.1 | [![eLBati](https://github.com/eLBati.png?size=30px)](https://github.com/eLBati) | Create Account Fiscal Year [account_invoice_constraint_chronology](account_invoice_constraint_chronology/) | 14.0.1.0.0 | | Account Invoice Constraint Chronology -[account_journal_general_sequence](account_journal_general_sequence/) | 14.0.1.0.2 | [![yajo](https://github.com/yajo.png?size=30px)](https://github.com/yajo) | Add configurable sequence to account moves, per journal +[account_journal_general_sequence](account_journal_general_sequence/) | 14.0.1.1.0 | [![yajo](https://github.com/yajo.png?size=30px)](https://github.com/yajo) | Add configurable sequence to account moves, per journal [account_journal_lock_date](account_journal_lock_date/) | 14.0.2.0.0 | | Lock each journal independently -[account_loan](account_loan/) | 14.0.1.0.3 | | Account Loan management +[account_loan](account_loan/) | 14.0.1.0.6 | | Account Loan management [account_lock_date_update](account_lock_date_update/) | 14.0.2.0.0 | | Allow an Account adviser to update locking date without having access to all technical settings [account_lock_to_date](account_lock_to_date/) | 14.0.1.0.0 | | Allows to set an account lock date in the future. -[account_menu](account_menu/) | 14.0.1.2.0 | [![legalsylvain](https://github.com/legalsylvain.png?size=30px)](https://github.com/legalsylvain) | Adds missing menu entries for Account module +[account_menu](account_menu/) | 14.0.1.2.1 | [![legalsylvain](https://github.com/legalsylvain.png?size=30px)](https://github.com/legalsylvain) | Adds missing menu entries for Account module [account_move_budget](account_move_budget/) | 14.0.1.0.0 | | Create Accounting Budgets [account_move_fiscal_month](account_move_fiscal_month/) | 14.0.1.0.0 | | Display the fiscal month on journal entries/item [account_move_fiscal_year](account_move_fiscal_year/) | 14.0.1.0.1 | | Display the fiscal year on journal entries/item [account_move_force_removal](account_move_force_removal/) | 14.0.1.0.1 | | Allow force removal account moves [account_move_line_check_number](account_move_line_check_number/) | 14.0.1.0.0 | [![ps-tubtim](https://github.com/ps-tubtim.png?size=30px)](https://github.com/ps-tubtim) | Add the check number in the journal items +[account_move_line_landed_cost_info](account_move_line_landed_cost_info/) | 14.0.1.0.0 | | Introduces the landed cost adjustment lines to the journal items [account_move_line_menu](account_move_line_menu/) | 14.0.1.0.0 | | Adds a Journal Items menu [account_move_line_purchase_info](account_move_line_purchase_info/) | 14.0.1.0.3 | | Introduces the purchase order line to the journal items -[account_move_line_sale_info](account_move_line_sale_info/) | 14.0.1.0.3 | | Introduces the purchase order line to the journal items +[account_move_line_repair_info](account_move_line_repair_info/) | 14.0.1.0.0 | | Introduces the repair order to the journal items +[account_move_line_sale_info](account_move_line_sale_info/) | 14.0.1.0.4 | | Introduces the purchase order line to the journal items [account_move_line_tax_editable](account_move_line_tax_editable/) | 14.0.2.0.0 | | Allows to edit taxes on non-posted account move lines [account_move_line_used_currency](account_move_line_used_currency/) | 14.0.1.0.0 | | Account Move Line Amount Currency -[account_move_name_sequence](account_move_name_sequence/) | 14.0.1.4.0 | [![alexis-via](https://github.com/alexis-via.png?size=30px)](https://github.com/alexis-via) [![moylop260](https://github.com/moylop260.png?size=30px)](https://github.com/moylop260) [![frahikLV](https://github.com/frahikLV.png?size=30px)](https://github.com/frahikLV) | Generate journal entry number from sequence +[account_move_name_sequence](account_move_name_sequence/) | 14.0.1.4.1 | [![alexis-via](https://github.com/alexis-via.png?size=30px)](https://github.com/alexis-via) [![moylop260](https://github.com/moylop260.png?size=30px)](https://github.com/moylop260) [![frahikLV](https://github.com/frahikLV.png?size=30px)](https://github.com/frahikLV) | Generate journal entry number from sequence [account_move_print](account_move_print/) | 14.0.1.0.0 | [![JordiBForgeFlow](https://github.com/JordiBForgeFlow.png?size=30px)](https://github.com/JordiBForgeFlow) | Adds the option to print Journal Entries [account_move_reversal_choose_method](account_move_reversal_choose_method/) | 14.0.1.0.0 | | Let's choose the Credit Method when adding a credit note to a journal entry. -[account_move_template](account_move_template/) | 14.0.1.1.1 | | Templates for recurring Journal Entries +[account_move_template](account_move_template/) | 14.0.1.1.2 | | Templates for recurring Journal Entries +[account_move_transfer_partner](account_move_transfer_partner/) | 14.0.1.0.0 | [![ChrisOForgeFlow](https://github.com/ChrisOForgeFlow.png?size=30px)](https://github.com/ChrisOForgeFlow) | Automation to translate amount due from many partners to one partner [account_netting](account_netting/) | 14.0.1.0.1 | | Compensate AR/AP accounts from the same partner [account_no_default](account_no_default/) | 14.0.1.0.0 | [![dreispt](https://github.com/dreispt.png?size=30px)](https://github.com/dreispt) | Remove default expense account for vendor bills journal [account_reconcile_show_boolean](account_reconcile_show_boolean/) | 14.0.1.0.0 | [![remi-filament](https://github.com/remi-filament.png?size=30px)](https://github.com/remi-filament) | Allows to create reconciliable accounts by showing boolean on form view [account_sequence_option](account_sequence_option/) | 14.0.1.0.2 | [![kittiu](https://github.com/kittiu.png?size=30px)](https://github.com/kittiu) | Manage sequence options for account.move, i.e., invoice, bill, entry [account_spread_cost_revenue](account_spread_cost_revenue/) | 14.0.1.0.0 | [![astirpe](https://github.com/astirpe.png?size=30px)](https://github.com/astirpe) | Spread costs and revenues over a custom period +[account_spread_cost_revenue_enhanced](account_spread_cost_revenue_enhanced/) | 14.0.1.0.0 | [![kittiu](https://github.com/kittiu.png?size=30px)](https://github.com/kittiu) | Extra feature for account spread cost/revenue [account_template_active](account_template_active/) | 14.0.1.0.0 | [![legalsylvain](https://github.com/legalsylvain.png?size=30px)](https://github.com/legalsylvain) | Allow to disable / enable account template items (tax, fiscal position, account) -[base_vat_optional_vies](base_vat_optional_vies/) | 14.0.1.0.3 | | Optional validation of VAT via VIES +[base_vat_optional_vies](base_vat_optional_vies/) | 14.0.2.1.0 | | Optional validation of VAT via VIES [product_category_tax](product_category_tax/) | 14.0.1.1.0 | | Configure taxes in the product category -[stock_account_prepare_anglo_saxon_out_lines_hook](stock_account_prepare_anglo_saxon_out_lines_hook/) | 14.0.1.0.4 | | Modify when and how anglo saxon journal items are created +[stock_account_prepare_anglo_saxon_out_lines_hook](stock_account_prepare_anglo_saxon_out_lines_hook/) | 14.0.1.0.5 | | Modify when and how anglo saxon journal items are created [//]: # (end addons) diff --git a/account_account_constraint_code/README.rst b/account_account_constraint_code/README.rst index 20f4ebd52..bd974cb03 100644 --- a/account_account_constraint_code/README.rst +++ b/account_account_constraint_code/README.rst @@ -2,10 +2,13 @@ Account Account Constraint Code =============================== -.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:a1529f7aeb3ef74f1f39c57feff052175f3074174e5cd9c227de7c4140c2f436 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status @@ -19,11 +22,11 @@ Account Account Constraint Code .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png :target: https://translation.odoo-community.org/projects/account-financial-tools-14-0/account-financial-tools-14-0-account_account_constraint_code :alt: Translate me on Weblate -.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/92/14.0 - :alt: Try me on Runbot +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/account-financial-tools&target_branch=14.0 + :alt: Try me on Runboat -|badge1| |badge2| |badge3| |badge4| |badge5| +|badge1| |badge2| |badge3| |badge4| |badge5| Disallow the modification of the code of accounts that have journal items. @@ -42,7 +45,7 @@ Bug Tracker 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 smashing it by providing a detailed and welcomed +If you spotted it first, help us to smash it by providing a detailed and welcomed `feedback `_. Do not contact contributors directly about support or help with technical issues. diff --git a/account_account_constraint_code/i18n/es.po b/account_account_constraint_code/i18n/es.po new file mode 100644 index 000000000..12220c2a5 --- /dev/null +++ b/account_account_constraint_code/i18n/es.po @@ -0,0 +1,43 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_account_constraint_code +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-06-06 11:08+0000\n" +"Last-Translator: Jesarregui \n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: account_account_constraint_code +#: model:ir.model,name:account_account_constraint_code.model_account_account +msgid "Account" +msgstr "Cuenta" + +#. module: account_account_constraint_code +#: model:ir.model.fields,field_description:account_account_constraint_code.field_account_account__display_name +msgid "Display Name" +msgstr "Nombre mostrado" + +#. module: account_account_constraint_code +#: model:ir.model.fields,field_description:account_account_constraint_code.field_account_account__id +msgid "ID" +msgstr "ID" + +#. module: account_account_constraint_code +#: model:ir.model.fields,field_description:account_account_constraint_code.field_account_account____last_update +msgid "Last Modified on" +msgstr "Última modificación el" + +#. module: account_account_constraint_code +#: code:addons/account_account_constraint_code/models/account_account.py:0 +#, python-format +msgid "You cannot change the code of account which contains journal items." +msgstr "No se puede modificar el código de la cuenta que contiene los asientos." diff --git a/account_account_constraint_code/i18n/fr.po b/account_account_constraint_code/i18n/fr.po new file mode 100644 index 000000000..8a5d927b6 --- /dev/null +++ b/account_account_constraint_code/i18n/fr.po @@ -0,0 +1,45 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_account_constraint_code +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-06-04 08:08+0000\n" +"Last-Translator: Claude R Perrin \n" +"Language-Team: none\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: account_account_constraint_code +#: model:ir.model,name:account_account_constraint_code.model_account_account +msgid "Account" +msgstr "Compte" + +#. module: account_account_constraint_code +#: model:ir.model.fields,field_description:account_account_constraint_code.field_account_account__display_name +msgid "Display Name" +msgstr "Nom affiché" + +#. module: account_account_constraint_code +#: model:ir.model.fields,field_description:account_account_constraint_code.field_account_account__id +msgid "ID" +msgstr "ID" + +#. module: account_account_constraint_code +#: model:ir.model.fields,field_description:account_account_constraint_code.field_account_account____last_update +msgid "Last Modified on" +msgstr "Dernière modification le" + +#. module: account_account_constraint_code +#: code:addons/account_account_constraint_code/models/account_account.py:0 +#, python-format +msgid "You cannot change the code of account which contains journal items." +msgstr "" +"Vous ne pouvez pas modifier le code d'un compte qui contient des éléments de " +"pièces comptables." diff --git a/account_account_constraint_code/static/description/index.html b/account_account_constraint_code/static/description/index.html index 2ada2ffd3..5ef9f60b0 100644 --- a/account_account_constraint_code/static/description/index.html +++ b/account_account_constraint_code/static/description/index.html @@ -1,20 +1,20 @@ - + - + Account Account Constraint Code + + +
+

Assets - Compute Depre. in Batch

+ + +

Beta License: AGPL-3 OCA/account-financial-tools Translate me on Weblate Try me on Runboat

+

This module extend existing “Compute Asset” feature by allowing to create an Compute Asset Batch (record) to track the computation.

+

Table of contents

+ +
+

Usage

+

There are 2 ways to create “Compute Asset Batch”

+
    +
  1. +
    On the Compute Assets wizards, choose “Create Batch” option,
    +
    1.1 Type in batch name and description. +1.2 Select asset profiles, to limit only some profiles to get computed. +1.3 Option to “Delay Compute Asset”, will only create Batch record for user to execute it later.
    +
    +
  2. +
  3. +
    Create Compute Asset Batch directly
    +
    2.1 Select date for depreciation +2.2 Type in batch name and descripton +2.3 Select asset profiles, to limit only some profiles to get computed. +2.4 Option to “Auto Compute” if you want to compute this batch by cron job. +2.4 Option to “Delay Post” if you want to post journal entry by cron job. +2.5 Click “Compute” button to compute asset.
    +
    +
  4. +
+
+
+

Bug Tracker

+

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.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Ecosoft
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

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/account-financial-tools project on GitHub.

+

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

+
+
+
+ + diff --git a/account_asset_compute_batch/tests/__init__.py b/account_asset_compute_batch/tests/__init__.py new file mode 100644 index 000000000..a8f856b8c --- /dev/null +++ b/account_asset_compute_batch/tests/__init__.py @@ -0,0 +1 @@ +from . import test_account_asset_compute_batch diff --git a/account_asset_compute_batch/tests/test_account_asset_compute_batch.py b/account_asset_compute_batch/tests/test_account_asset_compute_batch.py new file mode 100644 index 000000000..0d48c7eb6 --- /dev/null +++ b/account_asset_compute_batch/tests/test_account_asset_compute_batch.py @@ -0,0 +1,165 @@ +# Copyright 2021 Ecosoft Co., Ltd. (http://ecosoft.co.th) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import time + +from freezegun import freeze_time + +from odoo.tests import tagged +from odoo.tests.common import Form + +from odoo.addons.account_asset_management.tests.test_account_asset_management import ( + TestAssetManagement, +) + + +@tagged("post_install", "-at_install") +class TestAssetComputeBatch(TestAssetManagement): + @classmethod + def setUpClass(cls): + super().setUpClass() + # Create 3 assets from 2 profiles + cls.ict0 = cls.asset_model.create( + { + "state": "draft", + "method_time": "year", + "method_number": 3, + "method_period": "year", + "name": "Laptop", + "code": "PI00101", + "purchase_value": 1500.0, + "profile_id": cls.ict3Y.id, + "date_start": time.strftime("2000-01-01"), + } + ) + cls.ict1 = cls.asset_model.create( + { + "state": "draft", + "method_time": "year", + "method_number": 3, + "method_period": "year", + "name": "Monitor", + "code": "PI00102", + "purchase_value": 2100.0, + "profile_id": cls.ict3Y.id, + "date_start": time.strftime("2000-01-01"), + } + ) + # 2nd asset + cls.vehicle0 = cls.asset_model.create( + { + "state": "draft", + "method_time": "year", + "method_number": 5, + "method_period": "year", + "name": "CEO's Car", + "purchase_value": 12000.0, + "salvage_value": 2000.0, + "profile_id": cls.car5y.id, + "date_start": time.strftime("2000-01-01"), + } + ) + + def _create_compute_wizard(self, use_batch=False, delay_compute=False): + with Form(self.env["account.asset.compute"]) as f: + f.batch_name = "Test Batch" + f.description = "Compute asset with 2 profiles" + f.profile_ids.add(self.ict3Y) + f.profile_ids.add(self.car5y) + f.use_batch = use_batch + f.delay_compute = delay_compute + wiz = f.save() + return wiz + + @freeze_time("2000-12-31") + def test_01_asset_compute_batch_normal(self): + # Confirm 3 assets + self.ict0.validate() + self.assertEqual(self.ict0.depreciation_line_ids[1].amount, 500) + self.ict1.validate() + self.assertEqual(self.ict1.depreciation_line_ids[1].amount, 700) + self.vehicle0.validate() + self.assertEqual(self.vehicle0.depreciation_line_ids[1].amount, 2000) + # Compute Asset, no delay + wiz = self._create_compute_wizard(use_batch=True) + res = wiz.asset_compute() + batch = self.env["account.asset.compute.batch"].browse(res["res_id"]) + self.assertEqual(batch.state, "computed") + self.assertEqual(batch.depre_amount, 3200) + # Test summary amount by profile + batch.invalidate_cache() + self.assertEqual( + {x.profile_id: x.amount for x in batch.profile_report}, + {self.ict3Y: 1200, self.car5y: 2000}, + ) + # Test view moves + # 3 account.move + res = batch.open_moves() + self.assertEqual(len(res["domain"][0][2]), 3) + # 6 account.move.line + res = batch.open_move_lines() + self.assertEqual(len(res["domain"][0][2]), 6) + + @freeze_time("2000-12-31") + def test_02_asset_compute_batch_delay_compute(self): + # Confirm 2 assets + self.ict0.validate() + self.assertEqual(self.ict0.depreciation_line_ids[1].amount, 500) + self.vehicle0.validate() + self.assertEqual(self.vehicle0.depreciation_line_ids[1].amount, 2000) + # Compute Asset, with delay + wiz = self._create_compute_wizard(use_batch=True, delay_compute=True) + res = wiz.asset_compute() + batch = self.env["account.asset.compute.batch"].browse(res["res_id"]) + self.assertEqual(batch.state, "draft") + self.assertEqual(batch.depre_amount, 0) + # Batch is still draft, require to click compute + batch.action_compute() + self.assertEqual(batch.state, "computed") + self.assertEqual(batch.depre_amount, 2500) + + @freeze_time("2000-12-31") + def test_03_asset_compute_batch_delay_compute_delay_post(self): + # Confirm 2 assets + self.ict0.validate() + self.assertEqual(self.ict0.depreciation_line_ids[1].amount, 500) + self.vehicle0.validate() + self.assertEqual(self.vehicle0.depreciation_line_ids[1].amount, 2000) + # Compute Asset, with delay + wiz = self._create_compute_wizard(use_batch=True, delay_compute=True) + res = wiz.asset_compute() + batch = self.env["account.asset.compute.batch"].browse(res["res_id"]) + self.assertEqual(batch.state, "draft") + self.assertEqual(batch.depre_amount, 0) + batch.delay_post = True + # Batch is still draft, require to click compute + batch.action_compute() + self.assertEqual(batch.state, "computed") + self.assertEqual(batch.depre_amount, 2500) + # All account.move is flag as auto_post = True, and state in draft + self.assertTrue(all(batch.move_line_ids.mapped("move_id.auto_post"))) + self.assertTrue( + all( + state == "draft" + for state in batch.move_line_ids.mapped("move_id.state") + ) + ) + + @freeze_time("2000-12-31") + def test_04_asset_compute_batch_auto_compute(self): + # Confirm 2 assets + self.ict0.validate() + self.assertEqual(self.ict0.depreciation_line_ids[1].amount, 500) + self.vehicle0.validate() + self.assertEqual(self.vehicle0.depreciation_line_ids[1].amount, 2000) + # Compute Asset, with delay + wiz = self._create_compute_wizard(use_batch=True, delay_compute=True) + res = wiz.asset_compute() + batch = self.env["account.asset.compute.batch"].browse(res["res_id"]) + self.assertEqual(batch.state, "draft") + self.assertEqual(batch.depre_amount, 0) + batch.auto_compute = True + # Batch will be posted by cron job + batch._autocompute_draft_batches() + self.assertEqual(batch.state, "computed") + self.assertEqual(batch.depre_amount, 2500) diff --git a/account_asset_compute_batch/views/account_asset_compute_batch.xml b/account_asset_compute_batch/views/account_asset_compute_batch.xml new file mode 100644 index 000000000..1216a21e9 --- /dev/null +++ b/account_asset_compute_batch/views/account_asset_compute_batch.xml @@ -0,0 +1,147 @@ + + + account.asset.compute.batch.form + account.asset.compute.batch + 10 + +
+
+
+ +
+
+
+

+ +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+
+
+
+ + + account.asset.compute.batch.tree + account.asset.compute.batch + + + + + + + + + + + + + + search.account.asset.compute.batch.filter + account.asset.compute.batch + + + + + + + + + Compute Asset Batch + account.asset.compute.batch + tree,form + + + + + +
diff --git a/account_asset_compute_batch/wizard/__init__.py b/account_asset_compute_batch/wizard/__init__.py new file mode 100644 index 000000000..07bfe6b38 --- /dev/null +++ b/account_asset_compute_batch/wizard/__init__.py @@ -0,0 +1 @@ +from . import account_asset_compute diff --git a/account_asset_compute_batch/wizard/account_asset_compute.py b/account_asset_compute_batch/wizard/account_asset_compute.py new file mode 100644 index 000000000..32bbf34c6 --- /dev/null +++ b/account_asset_compute_batch/wizard/account_asset_compute.py @@ -0,0 +1,43 @@ +# Copyright 2021 Ecosoft Co., Ltd. (http://ecosoft.co.th) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import _, fields, models + + +class AccountAssetCompute(models.TransientModel): + _inherit = "account.asset.compute" + + use_batch = fields.Boolean(string="Create Batch", help="Use batch opton") + batch_name = fields.Char( + string="Batch Name", + help="If batch name is specified, computation will be tracked by a batch", + ) + description = fields.Char( + string="Description", + ) + profile_ids = fields.Many2many( + comodel_name="account.asset.profile", + string="Profiles", + ) + delay_compute = fields.Boolean(string="Delay Compute Asset") + + def asset_compute(self): + if self.use_batch: + vals = { + "date_end": self.date_end, + "name": self.batch_name, + "description": self.description, + "profile_ids": [(4, x.id) for x in self.profile_ids], + } + batch = self.env["account.asset.compute.batch"].create(vals) + if not self.delay_compute: + batch.action_compute() + return { + "name": _("Asset Compute Batch"), + "type": "ir.actions.act_window", + "view_type": "form", + "view_mode": "form", + "res_model": "account.asset.compute.batch", + "res_id": batch.id, + } + return super().asset_compute() diff --git a/account_asset_compute_batch/wizard/account_asset_compute.xml b/account_asset_compute_batch/wizard/account_asset_compute.xml new file mode 100644 index 000000000..c0339052c --- /dev/null +++ b/account_asset_compute_batch/wizard/account_asset_compute.xml @@ -0,0 +1,41 @@ + + + account.asset.compute + account.asset.compute + + + + + + + + + + + + + + + + + + + + + + diff --git a/account_asset_from_expense/README.rst b/account_asset_from_expense/README.rst new file mode 100644 index 000000000..a3cfb3d5a --- /dev/null +++ b/account_asset_from_expense/README.rst @@ -0,0 +1,78 @@ +==================== +Assets from Expenses +==================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:9ddb3d210ef0b852a02ac36036c2ce9e9dba15f35084fcf092a55bea74c19c67 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |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%2Faccount--financial--tools-lightgray.png?logo=github + :target: https://github.com/OCA/account-financial-tools/tree/14.0/account_asset_from_expense + :alt: OCA/account-financial-tools +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/account-financial-tools-14-0/account-financial-tools-14-0-account_asset_from_expense + :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/account-financial-tools&target_branch=14.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module is used to create the assets from expense. + +**Table of contents** + +.. contents:: + :local: + +Bug Tracker +=========== + +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 `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Ecosoft + +Contributors +~~~~~~~~~~~~ + +* `Ecosoft `__: + + * Pimolnat Suntian + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +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/account-financial-tools `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/account_asset_from_expense/__init__.py b/account_asset_from_expense/__init__.py new file mode 100644 index 000000000..69f7babdf --- /dev/null +++ b/account_asset_from_expense/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import models diff --git a/account_asset_from_expense/__manifest__.py b/account_asset_from_expense/__manifest__.py new file mode 100644 index 000000000..44b670b0a --- /dev/null +++ b/account_asset_from_expense/__manifest__.py @@ -0,0 +1,16 @@ +# Copyright 2022 Ecosoft Co., Ltd. (http://ecosoft.co.th) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +{ + "name": "Assets from Expenses", + "version": "14.0.1.0.0", + "license": "AGPL-3", + "depends": ["account_asset_management", "hr_expense"], + "author": "Ecosoft, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/account-financial-tools", + "category": "Accounting & Finance", + "data": [ + "security/ir.model.access.csv", + "views/hr_expense_views.xml", + ], +} diff --git a/account_asset_from_expense/i18n/account_asset_from_expense.pot b/account_asset_from_expense/i18n/account_asset_from_expense.pot new file mode 100644 index 000000000..ad24d9758 --- /dev/null +++ b/account_asset_from_expense/i18n/account_asset_from_expense.pot @@ -0,0 +1,45 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_asset_from_expense +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: account_asset_from_expense +#: model:ir.model.fields,field_description:account_asset_from_expense.field_hr_expense__asset_profile_id +msgid "Asset Profile" +msgstr "" + +#. module: account_asset_from_expense +#: model:ir.model.fields,field_description:account_asset_from_expense.field_hr_expense__display_name +msgid "Display Name" +msgstr "" + +#. module: account_asset_from_expense +#: model:ir.model,name:account_asset_from_expense.model_hr_expense +msgid "Expense" +msgstr "" + +#. module: account_asset_from_expense +#: model:ir.model.fields,field_description:account_asset_from_expense.field_hr_expense__id +msgid "ID" +msgstr "" + +#. module: account_asset_from_expense +#: model:ir.model.fields,field_description:account_asset_from_expense.field_hr_expense____last_update +msgid "Last Modified on" +msgstr "" + +#. module: account_asset_from_expense +#: code:addons/account_asset_from_expense/models/hr_expense.py:0 +#, python-format +msgid "This expense created the asset(s): %s" +msgstr "" diff --git a/account_asset_from_expense/models/__init__.py b/account_asset_from_expense/models/__init__.py new file mode 100644 index 000000000..ced2eb18d --- /dev/null +++ b/account_asset_from_expense/models/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import hr_expense diff --git a/account_asset_from_expense/models/hr_expense.py b/account_asset_from_expense/models/hr_expense.py new file mode 100644 index 000000000..ea1382da0 --- /dev/null +++ b/account_asset_from_expense/models/hr_expense.py @@ -0,0 +1,104 @@ +# Copyright 2022 Ecosoft Co., Ltd. (http://ecosoft.co.th) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import _, api, fields, models +from odoo.tests.common import Form + + +class HrExpense(models.Model): + _inherit = "hr.expense" + + asset_profile_id = fields.Many2one( + comodel_name="account.asset.profile", + string="Asset Profile", + ) + + @api.onchange("account_id") + def _onchange_account_id(self): + if self.account_id.asset_profile_id: + self.asset_profile_id = self.account_id.asset_profile_id + + @api.onchange("asset_profile_id") + def _onchange_asset_profile_id(self): + if self.asset_profile_id.account_asset_id: + self.account_id = self.asset_profile_id.account_asset_id + + def _expense_expand_asset_line(self, line): + self.ensure_one() + quantity = 1 + name = self.name + company = self.company_id + currency = self.currency_id + account_date = ( + self.sheet_id.accounting_date + or self.date + or fields.Date.context_today(self) + ) + taxes = self.tax_ids.with_context(round=True).compute_all( + self.unit_amount, currency, quantity, self.product_id + ) + amount_currency = taxes["total_excluded"] + balance = currency._convert( + amount_currency, company.currency_id, company, account_date + ) + lines = [] + for i in range(1, int(self.quantity) + 1): + cpy_line = line.copy() + cpy_line.update( + { + "name": "{} {}".format(name, i), + "quantity": quantity, + "debit": balance if balance > 0 else 0, + "credit": -balance if balance < 0 else 0, + "amount_currency": amount_currency, + } + ) + lines.append(cpy_line) + return lines + + def _get_account_move_line_values(self): + move_line_values_by_expense = super()._get_account_move_line_values() + for expense in self.filtered("asset_profile_id"): + asset_lines = [] + old_asset_line = dict() + for line in move_line_values_by_expense[expense.id]: + if line["account_id"] == expense.asset_profile_id.account_asset_id.id: + line["asset_profile_id"] = expense.asset_profile_id.id + if expense.asset_profile_id.asset_product_item: + old_asset_line = line + asset_lines.extend(expense._expense_expand_asset_line(line)) + if asset_lines: + if old_asset_line: + move_line_values_by_expense[expense.id].remove(old_asset_line) + move_line_values_by_expense[expense.id].extend(asset_lines) + return move_line_values_by_expense + + def action_move_create(self): + move_group_by_sheet = super().action_move_create() + for sheet in move_group_by_sheet: + for move in move_group_by_sheet[sheet]: + for aml in move.line_ids.filtered("asset_profile_id"): + vals = move._prepare_asset_vals(aml) + asset_form = Form( + self.env["account.asset"] + .with_company(move.company_id) + .with_context(create_asset_from_move_line=True, move_id=move.id) + ) + for key, val in vals.items(): + setattr(asset_form, key, val) + asset = asset_form.save() + asset.analytic_tag_ids = aml.analytic_tag_ids + aml.with_context(allow_asset=True).asset_id = asset.id + refs = [ + "%s" + % tuple(name_get) + for name_get in move.line_ids.filtered( + "asset_profile_id" + ).asset_id.name_get() + ] + if refs: + message = _("This expense created the asset(s): %s") % ", ".join( + refs + ) + move.message_post(body=message) + return move_group_by_sheet diff --git a/account_asset_from_expense/readme/CONTRIBUTORS.rst b/account_asset_from_expense/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..ea63aa7bc --- /dev/null +++ b/account_asset_from_expense/readme/CONTRIBUTORS.rst @@ -0,0 +1,3 @@ +* `Ecosoft `__: + + * Pimolnat Suntian diff --git a/account_asset_from_expense/readme/DESCRIPTION.rst b/account_asset_from_expense/readme/DESCRIPTION.rst new file mode 100644 index 000000000..de88e63f1 --- /dev/null +++ b/account_asset_from_expense/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +This module is used to create the assets from expense. diff --git a/account_asset_from_expense/security/ir.model.access.csv b/account_asset_from_expense/security/ir.model.access.csv new file mode 100644 index 000000000..da9c0ab8f --- /dev/null +++ b/account_asset_from_expense/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_account_asset_profile_employee,account.asset.profile,account_asset_management.model_account_asset_profile,base.group_user,1,0,0,0 diff --git a/account_asset_from_expense/static/description/icon.png b/account_asset_from_expense/static/description/icon.png new file mode 100644 index 000000000..3a0328b51 Binary files /dev/null and b/account_asset_from_expense/static/description/icon.png differ diff --git a/account_asset_from_expense/static/description/index.html b/account_asset_from_expense/static/description/index.html new file mode 100644 index 000000000..8e76deb46 --- /dev/null +++ b/account_asset_from_expense/static/description/index.html @@ -0,0 +1,424 @@ + + + + + + +Assets from Expenses + + + +
+

Assets from Expenses

+ + +

Beta License: AGPL-3 OCA/account-financial-tools Translate me on Weblate Try me on Runboat

+

This module is used to create the assets from expense.

+

Table of contents

+ +
+

Bug Tracker

+

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.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Ecosoft
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

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/account-financial-tools project on GitHub.

+

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

+
+
+
+ + diff --git a/account_asset_from_expense/tests/__init__.py b/account_asset_from_expense/tests/__init__.py new file mode 100644 index 000000000..ce34f1a7d --- /dev/null +++ b/account_asset_from_expense/tests/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import test_account_asset_from_expense diff --git a/account_asset_from_expense/tests/test_account_asset_from_expense.py b/account_asset_from_expense/tests/test_account_asset_from_expense.py new file mode 100644 index 000000000..ecdfd4c2a --- /dev/null +++ b/account_asset_from_expense/tests/test_account_asset_from_expense.py @@ -0,0 +1,93 @@ +# Copyright 2022 Ecosoft Co., Ltd. (http://ecosoft.co.th) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + + +from odoo.tests import tagged +from odoo.tests.common import Form + +from odoo.addons.account.tests.common import AccountTestInvoicingCommon + + +@tagged("post_install", "-at_install") +class TestAccountAssetFromExpense(AccountTestInvoicingCommon): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.asset_profile_model = cls.env["account.asset.profile"] + cls.expense_sheet_model = cls.env["hr.expense.sheet"] + cls.product_1 = cls.env.ref("product.product_delivery_01") + # New Employee + 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} + ) + # Profile normal asset + cls.profile_asset = cls.asset_profile_model.create( + { + "account_expense_depreciation_id": cls.company_data[ + "default_account_expense" + ].id, + "asset_product_item": True, + "account_asset_id": cls.company_data["default_account_assets"].id, + "account_depreciation_id": cls.company_data[ + "default_account_assets" + ].id, + "journal_id": cls.company_data["default_journal_purchase"].id, + "name": "Room - 5 Years", + "method_time": "year", + "method_number": 5, + "method_period": "year", + } + ) + + def _create_expense( + self, + description, + employee, + product, + amount, + asset_profile=False, + payment_mode="own_account", + account=False, + ): + with Form(self.env["hr.expense"]) as expense: + expense.name = description + expense.employee_id = employee + expense.product_id = product + expense.unit_amount = amount + expense.payment_mode = payment_mode + if account: + expense.account_id = account + if asset_profile: + expense.asset_profile_id = asset_profile + expense = expense.save() + expense.tax_ids = False # Test no vat + return expense + + def test_01_create_asset_from_expense(self): + """Create asset from expenses post journal entry""" + expense = self._create_expense( + "Test - Room Office", + self.employee, + self.product_1, + 1000.0, + asset_profile=self.profile_asset, + ) + # check account and asset profile must be equal + self.assertEqual( + expense.account_id, self.company_data["default_account_assets"] + ) + sheet_dict = expense.action_submit_expenses() + sheet = self.expense_sheet_model.search([("id", "=", sheet_dict["res_id"])]) + sheet.action_submit_sheet() + sheet.approve_expense_sheets() + sheet.action_sheet_move_create() + # check asset + assets = ( + self.env["account.asset.line"] + .search([("move_id", "=", sheet.account_move_id.id)]) + .mapped("asset_id") + ) + self.assertEqual(sheet.account_move_id.asset_count, 1) + self.assertEqual(len(assets), 1) + self.assertEqual(assets.state, "draft") diff --git a/account_asset_from_expense/views/hr_expense_views.xml b/account_asset_from_expense/views/hr_expense_views.xml new file mode 100644 index 000000000..977dd7e36 --- /dev/null +++ b/account_asset_from_expense/views/hr_expense_views.xml @@ -0,0 +1,32 @@ + + + + + hr.expense.view.form + hr.expense + + + + + + + + + + hr.expense.sheet.form + hr.expense.sheet + + + + + + + + diff --git a/account_asset_low_value/README.rst b/account_asset_low_value/README.rst index a97dfbff0..a21b59e6b 100644 --- a/account_asset_low_value/README.rst +++ b/account_asset_low_value/README.rst @@ -2,10 +2,13 @@ Assets Management - Low Value Asset =================================== -.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:a18d0cb54c4c5ae977a5eb3208fe563feb9b57480fcf68e47b56baf539aace1d + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png :target: https://odoo-community.org/page/development-status @@ -19,11 +22,11 @@ Assets Management - Low Value Asset .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png :target: https://translation.odoo-community.org/projects/account-financial-tools-14-0/account-financial-tools-14-0-account_asset_low_value :alt: Translate me on Weblate -.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/92/14.0 - :alt: Try me on Runbot +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/account-financial-tools&target_branch=14.0 + :alt: Try me on Runboat -|badge1| |badge2| |badge3| |badge4| |badge5| +|badge1| |badge2| |badge3| |badge4| |badge5| Low-Value Asset (LVA) are typically asset with low values and was booked as expense on vendor bill. In essence, the low value asset is not really and asset but an expense need to tracke as asset. @@ -49,7 +52,7 @@ Bug Tracker 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 smashing it by providing a detailed and welcomed +If you spotted it first, help us to smash it by providing a detailed and welcomed `feedback `_. Do not contact contributors directly about support or help with technical issues. diff --git a/account_asset_low_value/static/description/index.html b/account_asset_low_value/static/description/index.html index c3b425564..0f785e94a 100644 --- a/account_asset_low_value/static/description/index.html +++ b/account_asset_low_value/static/description/index.html @@ -1,20 +1,20 @@ - + - + Assets Management - Low Value Asset + + +
+

Account Move Line Landed Cost Info

+ + +

Beta License: AGPL-3 OCA/account-financial-tools Translate me on Weblate Try me on Runboat

+

This module will add the landed cost info to journal items.

+

The ultimate goal is to establish the landed cost adjustments as one of the key +fields to reconcile the Goods Delviered Not Invoiced accrual account.

+

Table of contents

+ +
+

Usage

+

The adjustment line of the landed cost will be automatically copied to the journal +items when validating a landed cost.

+
+
+

Bug Tracker

+

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.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • ForgeFlow
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

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/account-financial-tools project on GitHub.

+

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

+
+
+
+ + diff --git a/account_move_line_landed_cost_info/views/account_move_view.xml b/account_move_line_landed_cost_info/views/account_move_view.xml new file mode 100644 index 000000000..573b88d7b --- /dev/null +++ b/account_move_line_landed_cost_info/views/account_move_view.xml @@ -0,0 +1,56 @@ + + + + account.move.line.form + account.move.line + + + + + + + + + account.move.line.tree + account.move.line + + + + + + + + + + Journal Items + account.move.line + + + + + + + + + + + + account.move.form + account.move + + + + + + + + + diff --git a/account_move_line_menu/README.rst b/account_move_line_menu/README.rst index 0b65c5f45..7d82fb8f8 100644 --- a/account_move_line_menu/README.rst +++ b/account_move_line_menu/README.rst @@ -2,10 +2,13 @@ Account Move Line Menu ====================== -.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:d614dd1b8cae5a4897feb27c968d4ccaf6b4e17bec45d974a5470b03b51e9048 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status @@ -19,11 +22,11 @@ Account Move Line Menu .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png :target: https://translation.odoo-community.org/projects/account-financial-tools-14-0/account-financial-tools-14-0-account_move_line_menu :alt: Translate me on Weblate -.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/92/14.0 - :alt: Try me on Runbot +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/account-financial-tools&target_branch=14.0 + :alt: Try me on Runboat -|badge1| |badge2| |badge3| |badge4| |badge5| +|badge1| |badge2| |badge3| |badge4| |badge5| The Journal items menu is visible only with the developer enabled. This feature makes it available without the developer mode enabled. @@ -44,7 +47,7 @@ Bug Tracker 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 smashing it by providing a detailed and welcomed +If you spotted it first, help us to smash it by providing a detailed and welcomed `feedback `_. Do not contact contributors directly about support or help with technical issues. diff --git a/account_move_line_menu/static/description/index.html b/account_move_line_menu/static/description/index.html index 3714687f9..7932f2c22 100644 --- a/account_move_line_menu/static/description/index.html +++ b/account_move_line_menu/static/description/index.html @@ -1,20 +1,20 @@ - + - + Account Move Line Menu + + +
+

Account Move Line Repair Info

+ + +

Beta License: AGPL-3 OCA/account-financial-tools Translate me on Weblate Try me on Runboat

+

This module will add the repair order to journal items.

+

Table of contents

+ +
+

Usage

+

The repair order will be automatically copied to the journal items.

+
    +
  • When Invoice(s) is made from repair order, field repair_order_id
  • +
  • The journal entries created by the consumption of materials and the repaired product, are associated with the repair order
  • +
+
+
+

Bug Tracker

+

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.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • ForgeFlow S.L.
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

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/account-financial-tools project on GitHub.

+

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

+
+
+
+ + diff --git a/account_move_line_repair_info/tests/__init__.py b/account_move_line_repair_info/tests/__init__.py new file mode 100644 index 000000000..ceb307b61 --- /dev/null +++ b/account_move_line_repair_info/tests/__init__.py @@ -0,0 +1 @@ +from . import test_account_move_line_repair_info diff --git a/account_move_line_repair_info/tests/test_account_move_line_repair_info.py b/account_move_line_repair_info/tests/test_account_move_line_repair_info.py new file mode 100644 index 000000000..a81a2ba39 --- /dev/null +++ b/account_move_line_repair_info/tests/test_account_move_line_repair_info.py @@ -0,0 +1,398 @@ +# Copyright 2022 ForgeFlow S.L. +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +# flake8: noqa: B950 + +from odoo import fields +from odoo.tests.common import TransactionCase + + +class TestAccountMoveLineRepairInfo(TransactionCase): + def setUp(self): + super().setUp() + self.aml_model = self.env["account.move.line"] + self.am_model = self.env["account.move"] + self.chart_template = self.env["account.chart.template"].create( + { + "name": "Test chart", + "currency_id": self.env.ref("base.EUR").id, + "code_digits": 6, + "cash_account_code_prefix": "570", + "bank_account_code_prefix": "572", + "transfer_account_code_prefix": "100000", + "use_anglo_saxon": True, + } + ) + self.chart_template.try_loading(company=self.env.user.company_id) + self.valuation_account = self.env["account.account"].create( + { + "name": "Test stock valuation", + "code": "tv", + "user_type_id": self.env["account.account.type"].search([], limit=1).id, + "reconcile": True, + "company_id": self.env.ref("base.main_company").id, + } + ) + self.payable_account = self.env["account.account"].create( + { + "name": "Test Payable", + "code": "tpayable", + "user_type_id": self.env["account.account.type"] + .search([("type", "=", "payable")], limit=1) + .id, + "reconcile": True, + "company_id": self.env.ref("base.main_company").id, + } + ) + self.receivable_account = self.env["account.account"].create( + { + "name": "Test Receivable", + "code": "treceivable", + "user_type_id": self.env["account.account.type"] + .search([("type", "=", "receivable")], limit=1) + .id, + "reconcile": True, + "company_id": self.env.ref("base.main_company").id, + } + ) + + self.stock_input_account = self.env["account.account"].create( + { + "name": "Test stock input", + "code": "tsti", + "user_type_id": self.env["account.account.type"].search([], limit=1).id, + "reconcile": True, + "company_id": self.env.ref("base.main_company").id, + } + ) + self.stock_output_account = self.env["account.account"].create( + { + "name": "Test stock output", + "code": "tout", + "user_type_id": self.env["account.account.type"].search([], limit=1).id, + "reconcile": True, + "company_id": self.env.ref("base.main_company").id, + } + ) + self.stock_income_account = self.env["account.account"].create( + { + "name": "Test stock income", + "code": "tincome", + "user_type_id": self.env["account.account.type"] + .search([("internal_group", "=", "income")], limit=1) + .id, + "reconcile": True, + "company_id": self.env.ref("base.main_company").id, + } + ) + self.stock_expense_account = self.env["account.account"].create( + { + "name": "Test stock outcome", + "code": "texpense", + "user_type_id": self.env["account.account.type"] + .search([("internal_group", "=", "expense")], limit=1) + .id, + "reconcile": True, + "company_id": self.env.ref("base.main_company").id, + } + ) + self.stock_journal = self.env["account.journal"].create( + {"name": "Stock Journal", "code": "STJTEST", "type": "general"} + ) + self.categ_real = self.env["product.category"].create( + { + "name": "REAL", + "property_cost_method": "fifo", + "property_valuation": "real_time", + "property_stock_valuation_account_id": self.valuation_account.id, + "property_stock_account_input_categ_id": self.stock_input_account.id, + "property_stock_account_output_categ_id": self.stock_output_account.id, + "property_account_expense_categ_id": self.stock_expense_account.id, + "property_account_income_categ_id": self.stock_income_account.id, + "property_stock_journal": self.stock_journal.id, + } + ) + self.res_partner_1 = self.env["res.partner"].create( + { + "name": "Wood Corner", + "property_account_payable_id": self.payable_account.id, + "property_account_receivable_id": self.receivable_account.id, + } + ) + self.res_partner_address_1 = self.env["res.partner"].create( + {"name": "Willie Burke", "parent_id": self.res_partner_1.id} + ) + self.res_partner_12 = self.env["res.partner"].create( + { + "name": "Partner 12", + "property_account_payable_id": self.payable_account.id, + "property_account_receivable_id": self.receivable_account.id, + } + ) + + # Products + self.product_product_3 = self.env["product.product"].create( + { + "name": "Desk Combination", + "categ_id": self.categ_real.id, + "standard_price": 1.0, + "type": "product", + } + ) + self.product_product_11 = self.env["product.product"].create( + { + "name": "Conference Chair", + "categ_id": self.categ_real.id, + "standard_price": 1.0, + "type": "product", + } + ) + self.product_product_5 = self.env["product.product"].create( + { + "name": "Product 5", + "categ_id": self.categ_real.id, + "standard_price": 1.0, + "type": "product", + } + ) + self.product_product_6 = self.env["product.product"].create( + { + "name": "Large Cabinet", + "categ_id": self.categ_real.id, + "standard_price": 1.0, + "type": "product", + } + ) + self.product_product_12 = self.env["product.product"].create( + { + "name": "Office Chair Black", + "categ_id": self.categ_real.id, + "standard_price": 1.0, + "type": "product", + } + ) + self.product_product_13 = self.env["product.product"].create( + { + "name": "Corner Desk Left Sit", + "categ_id": self.categ_real.id, + "standard_price": 1.0, + "type": "product", + } + ) + self.product_product_2 = self.env["product.product"].create( + { + "name": "Virtual Home Staging", + "categ_id": self.categ_real.id, + "standard_price": 1.0, + "type": "product", + } + ) + self.product_service_order_repair = self.env["product.product"].create( + { + "name": "Repair Services", + "type": "service", + "categ_id": self.categ_real.id, + } + ) + + # Location + self.stock_warehouse = self.env["stock.warehouse"].search( + [("company_id", "=", self.env.company.id)], limit=1 + ) + self.stock_location_14 = self.env["stock.location"].create( + { + "name": "Shelf 2", + "location_id": self.stock_warehouse.lot_stock_id.id, + } + ) + + # Repair Orders + self.repair1 = self.env["repair.order"].create( + { + "address_id": self.res_partner_address_1.id, + "guarantee_limit": fields.Date.today(), + "invoice_method": "none", + "user_id": False, + "product_id": self.product_product_3.id, + "product_uom": self.env.ref("uom.product_uom_unit").id, + "partner_invoice_id": self.res_partner_address_1.id, + "location_id": self.stock_warehouse.lot_stock_id.id, + "operations": [ + ( + 0, + 0, + { + "location_dest_id": self.product_product_11.property_stock_production.id, + "location_id": self.stock_warehouse.lot_stock_id.id, + "name": self.product_product_11.get_product_multiline_description_sale(), + "product_id": self.product_product_11.id, + "product_uom": self.env.ref("uom.product_uom_unit").id, + "product_uom_qty": 1.0, + "price_unit": 50.0, + "state": "draft", + "type": "add", + "company_id": self.env.company.id, + }, + ) + ], + "fees_lines": [ + ( + 0, + 0, + { + "name": self.product_service_order_repair.get_product_multiline_description_sale(), + "product_id": self.product_service_order_repair.id, + "product_uom_qty": 1.0, + "product_uom": self.env.ref("uom.product_uom_unit").id, + "price_unit": 50.0, + "company_id": self.env.company.id, + }, + ) + ], + "partner_id": self.res_partner_12.id, + } + ) + + self.repair0 = self.env["repair.order"].create( + { + "product_id": self.product_product_5.id, + "product_uom": self.env.ref("uom.product_uom_unit").id, + "address_id": self.res_partner_address_1.id, + "guarantee_limit": fields.Date.today(), + "invoice_method": "after_repair", + "user_id": False, + "partner_invoice_id": self.res_partner_address_1.id, + "location_id": self.stock_warehouse.lot_stock_id.id, + "operations": [ + ( + 0, + 0, + { + "location_dest_id": self.product_product_12.property_stock_production.id, + "location_id": self.stock_warehouse.lot_stock_id.id, + "name": self.product_product_12.get_product_multiline_description_sale(), + "price_unit": 50.0, + "product_id": self.product_product_12.id, + "product_uom": self.env.ref("uom.product_uom_unit").id, + "product_uom_qty": 1.0, + "state": "draft", + "type": "add", + "company_id": self.env.company.id, + }, + ) + ], + "fees_lines": [ + ( + 0, + 0, + { + "name": self.product_service_order_repair.get_product_multiline_description_sale(), + "product_id": self.product_service_order_repair.id, + "product_uom_qty": 1.0, + "product_uom": self.env.ref("uom.product_uom_unit").id, + "price_unit": 50.0, + "company_id": self.env.company.id, + }, + ) + ], + "partner_id": self.res_partner_12.id, + } + ) + + self.repair2 = self.env["repair.order"].create( + { + "product_id": self.product_product_6.id, + "product_uom": self.env.ref("uom.product_uom_unit").id, + "address_id": self.res_partner_address_1.id, + "guarantee_limit": fields.Date.today(), + "invoice_method": "b4repair", + "user_id": False, + "partner_invoice_id": self.res_partner_address_1.id, + "location_id": self.stock_location_14.id, + "operations": [ + ( + 0, + 0, + { + "location_dest_id": self.product_product_13.property_stock_production.id, + "location_id": self.stock_warehouse.lot_stock_id.id, + "name": self.product_product_13.get_product_multiline_description_sale(), + "price_unit": 50.0, + "product_id": self.product_product_13.id, + "product_uom": self.env.ref("uom.product_uom_unit").id, + "product_uom_qty": 1.0, + "state": "draft", + "type": "add", + "company_id": self.env.company.id, + }, + ) + ], + "fees_lines": [ + ( + 0, + 0, + { + "name": self.product_service_order_repair.get_product_multiline_description_sale(), + "product_id": self.product_service_order_repair.id, + "product_uom_qty": 1.0, + "product_uom": self.env.ref("uom.product_uom_unit").id, + "price_unit": 50.0, + "company_id": self.env.company.id, + }, + ) + ], + "partner_id": self.res_partner_12.id, + } + ) + + self.env.user.groups_id |= self.env.ref("stock.group_stock_user") + + def test_move_line_repair_info(self): + self.product_product_3.write({"categ_id": self.categ_real.id}) + self.product_product_11.write({"categ_id": self.categ_real.id}) + self.product_product_5.write({"categ_id": self.categ_real.id}) + self.product_product_6.write({"categ_id": self.categ_real.id}) + self.product_product_12.write({"categ_id": self.categ_real.id}) + self.product_product_13.write({"categ_id": self.categ_real.id}) + self.product_product_2.write({"categ_id": self.categ_real.id}) + repairs = self.repair0 + self.repair1 + self.repair2 + for repair in repairs: + repair.action_repair_confirm() + if repair.state != "2binvoiced": + repair.action_repair_start() + repair.action_repair_end() + for operation in repairs.filtered( + lambda x: x.state == "done" and x.move_id + ).mapped("operations"): + aml = self.aml_model.search( + [("move_id.stock_move_id", "=", operation.move_id.id)] + ) + if aml: + self.assertEqual( + aml.mapped("repair_order_id").ids, operation.repair_id.ids + ) + make_invoice = self.env["repair.order.make_invoice"].create({"group": True}) + context = { + "active_model": "repair.order", + "active_ids": repairs.ids, + } + res = make_invoice.with_context(context).make_invoices() + invoices = res.get("domain", []) and self.am_model.browse( + res.get("domain", [])[0][2] + ) + for invoice in invoices: + if invoice.state == "draft": + invoice.action_post() + for fee in repairs.mapped("fees_lines"): + invoice_lines = fee.repair_id.invoice_id.invoice_line_ids.filtered( + lambda x: fee.id in x.repair_fee_ids.ids + ) + if invoice_lines: + self.assertEqual(fee.repair_id.id, invoice_lines.repair_order_id.id) + for operation in repairs.mapped("operations"): + invoice_lines = operation.repair_id.invoice_id.invoice_line_ids.filtered( + lambda x: operation.id in x.repair_line_ids.ids + ) + if invoice_lines: + self.assertEqual( + operation.repair_id.id, invoice_lines.repair_order_id.id + ) diff --git a/account_move_line_repair_info/views/account_move_view.xml b/account_move_line_repair_info/views/account_move_view.xml new file mode 100644 index 000000000..af6cca51c --- /dev/null +++ b/account_move_line_repair_info/views/account_move_view.xml @@ -0,0 +1,52 @@ + + + + account.move.line.form + account.move.line + + + + + + + + + account.move.line.tree + account.move.line + + + + + + + + + Journal Items + account.move.line + + + + + + + + + + + diff --git a/account_move_line_sale_info/__manifest__.py b/account_move_line_sale_info/__manifest__.py index f5cc1e728..05da8acc4 100644 --- a/account_move_line_sale_info/__manifest__.py +++ b/account_move_line_sale_info/__manifest__.py @@ -4,7 +4,7 @@ { "name": "Account Move Line Sale Info", "summary": "Introduces the purchase order line to the journal items", - "version": "14.0.1.0.3", + "version": "14.0.1.0.4", "author": "ForgeFlow S.L., " "Odoo Community Association (OCA)", "website": "https://github.com/OCA/account-financial-tools", "category": "Generic", diff --git a/account_move_line_sale_info/hooks.py b/account_move_line_sale_info/hooks.py index 86fb30877..d48fa41f5 100644 --- a/account_move_line_sale_info/hooks.py +++ b/account_move_line_sale_info/hooks.py @@ -12,7 +12,20 @@ def post_init_hook(cr, registry): FROM account_move_line aml2 INNER JOIN stock_move sm ON aml2.stock_move_id = sm.id - WHERE aml.id = aml2.id; + WHERE aml.id = aml2.id + AND sm.sale_line_id IS NOT NULL; + """ + ) + cr.execute( + """ + UPDATE account_move_line aml SET sale_line_id = sm.sale_line_id + FROM account_move_line aml2 + INNER JOIN account_move am + ON am.id = aml2.move_id + INNER JOIN stock_move sm ON + am.stock_move_id = sm.id + WHERE aml.id = aml2.id + AND sm.sale_line_id IS NOT NULL; """ ) # FOR invoices diff --git a/account_move_line_sale_info/i18n/fr_FR.po b/account_move_line_sale_info/i18n/fr_FR.po new file mode 100644 index 000000000..198da10de --- /dev/null +++ b/account_move_line_sale_info/i18n/fr_FR.po @@ -0,0 +1,82 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_move_line_sale_info +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-05-09 13:42+0000\n" +"Last-Translator: LESTRAT21 \n" +"Language-Team: none\n" +"Language: fr_FR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 4.14.1\n" + +#. module: account_move_line_sale_info +#: model:ir.model.fields,field_description:account_move_line_sale_info.field_account_move__display_name +#: model:ir.model.fields,field_description:account_move_line_sale_info.field_account_move_line__display_name +#: model:ir.model.fields,field_description:account_move_line_sale_info.field_sale_order_line__display_name +#: model:ir.model.fields,field_description:account_move_line_sale_info.field_stock_move__display_name +msgid "Display Name" +msgstr "Nom affiché" + +#. module: account_move_line_sale_info +#: model:ir.model.fields,field_description:account_move_line_sale_info.field_account_move__id +#: model:ir.model.fields,field_description:account_move_line_sale_info.field_account_move_line__id +#: model:ir.model.fields,field_description:account_move_line_sale_info.field_sale_order_line__id +#: model:ir.model.fields,field_description:account_move_line_sale_info.field_stock_move__id +msgid "ID" +msgstr "ID" + +#. module: account_move_line_sale_info +#: model:ir.model,name:account_move_line_sale_info.model_account_move +msgid "Journal Entry" +msgstr "Pièce comptable" + +#. module: account_move_line_sale_info +#: model:ir.model,name:account_move_line_sale_info.model_account_move_line +msgid "Journal Item" +msgstr "Ecriture comptable" + +#. module: account_move_line_sale_info +#: model:ir.model.fields,field_description:account_move_line_sale_info.field_account_move____last_update +#: model:ir.model.fields,field_description:account_move_line_sale_info.field_account_move_line____last_update +#: model:ir.model.fields,field_description:account_move_line_sale_info.field_sale_order_line____last_update +#: model:ir.model.fields,field_description:account_move_line_sale_info.field_stock_move____last_update +msgid "Last Modified on" +msgstr "Date de dernière modification" + +#. module: account_move_line_sale_info +#: model_terms:ir.ui.view,arch_db:account_move_line_sale_info.view_account_move_line_filter +msgid "Sale Order" +msgstr "Commande de vente" + +#. module: account_move_line_sale_info +#: model:ir.model.fields,field_description:account_move_line_sale_info.field_account_move_line__sale_line_id +#: model_terms:ir.ui.view,arch_db:account_move_line_sale_info.view_account_move_line_filter +msgid "Sale Order Line" +msgstr "Ligne de vente" + +#. module: account_move_line_sale_info +#: model:res.groups,name:account_move_line_sale_info.group_account_move_sale_info +msgid "Sale info in Journal Items" +msgstr "Info vente dans l'écriture comptable" + +#. module: account_move_line_sale_info +#: model:ir.model.fields,field_description:account_move_line_sale_info.field_account_move_line__sale_order_id +msgid "Sales Order" +msgstr "Commande de vente" + +#. module: account_move_line_sale_info +#: model:ir.model,name:account_move_line_sale_info.model_sale_order_line +msgid "Sales Order Line" +msgstr "Ligne de vente" + +#. module: account_move_line_sale_info +#: model:ir.model,name:account_move_line_sale_info.model_stock_move +msgid "Stock Move" +msgstr "Transfert de stock" diff --git a/account_move_line_sale_info/i18n/sl.po b/account_move_line_sale_info/i18n/sl.po new file mode 100644 index 000000000..f3adf9a85 --- /dev/null +++ b/account_move_line_sale_info/i18n/sl.po @@ -0,0 +1,83 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_move_line_sale_info +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-03-30 12:22+0000\n" +"Last-Translator: Matjaz Mozetic \n" +"Language-Team: none\n" +"Language: sl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n" +"%100==4 ? 2 : 3;\n" +"X-Generator: Weblate 4.14.1\n" + +#. module: account_move_line_sale_info +#: model:ir.model.fields,field_description:account_move_line_sale_info.field_account_move__display_name +#: model:ir.model.fields,field_description:account_move_line_sale_info.field_account_move_line__display_name +#: model:ir.model.fields,field_description:account_move_line_sale_info.field_sale_order_line__display_name +#: model:ir.model.fields,field_description:account_move_line_sale_info.field_stock_move__display_name +msgid "Display Name" +msgstr "Prikazani naziv" + +#. module: account_move_line_sale_info +#: model:ir.model.fields,field_description:account_move_line_sale_info.field_account_move__id +#: model:ir.model.fields,field_description:account_move_line_sale_info.field_account_move_line__id +#: model:ir.model.fields,field_description:account_move_line_sale_info.field_sale_order_line__id +#: model:ir.model.fields,field_description:account_move_line_sale_info.field_stock_move__id +msgid "ID" +msgstr "ID" + +#. module: account_move_line_sale_info +#: model:ir.model,name:account_move_line_sale_info.model_account_move +msgid "Journal Entry" +msgstr "Dnevniški vnos" + +#. module: account_move_line_sale_info +#: model:ir.model,name:account_move_line_sale_info.model_account_move_line +msgid "Journal Item" +msgstr "Dnevniška postavka" + +#. module: account_move_line_sale_info +#: model:ir.model.fields,field_description:account_move_line_sale_info.field_account_move____last_update +#: model:ir.model.fields,field_description:account_move_line_sale_info.field_account_move_line____last_update +#: model:ir.model.fields,field_description:account_move_line_sale_info.field_sale_order_line____last_update +#: model:ir.model.fields,field_description:account_move_line_sale_info.field_stock_move____last_update +msgid "Last Modified on" +msgstr "Zadnjič spremenjeno" + +#. module: account_move_line_sale_info +#: model_terms:ir.ui.view,arch_db:account_move_line_sale_info.view_account_move_line_filter +msgid "Sale Order" +msgstr "Prodajni nalog" + +#. module: account_move_line_sale_info +#: model:ir.model.fields,field_description:account_move_line_sale_info.field_account_move_line__sale_line_id +#: model_terms:ir.ui.view,arch_db:account_move_line_sale_info.view_account_move_line_filter +msgid "Sale Order Line" +msgstr "Postavka prodajnega naloga" + +#. module: account_move_line_sale_info +#: model:res.groups,name:account_move_line_sale_info.group_account_move_sale_info +msgid "Sale info in Journal Items" +msgstr "Podatki o prodaji na vknjižbah" + +#. module: account_move_line_sale_info +#: model:ir.model.fields,field_description:account_move_line_sale_info.field_account_move_line__sale_order_id +msgid "Sales Order" +msgstr "Prodajni nalog" + +#. module: account_move_line_sale_info +#: model:ir.model,name:account_move_line_sale_info.model_sale_order_line +msgid "Sales Order Line" +msgstr "Postavka prodajnega naloga" + +#. module: account_move_line_sale_info +#: model:ir.model,name:account_move_line_sale_info.model_stock_move +msgid "Stock Move" +msgstr "Premik zaloge" diff --git a/account_move_line_sale_info/migrations/14.0.1.0.2/pre-migration.py b/account_move_line_sale_info/migrations/14.0.1.0.2/pre-migration.py new file mode 100644 index 000000000..7395950c4 --- /dev/null +++ b/account_move_line_sale_info/migrations/14.0.1.0.2/pre-migration.py @@ -0,0 +1,21 @@ +# Copyright 2022 ForgeFlow, S.L. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +import logging + +_logger = logging.getLogger(__name__) + + +def migrate(cr, version): + _logger.info("Update account move lines with sale order line") + cr.execute( + """ + UPDATE account_move_line aml SET sale_line_id = sm.sale_line_id + FROM account_move_line aml2 + INNER JOIN account_move am + ON am.id = aml2.move_id + INNER JOIN stock_move sm ON + am.stock_move_id = sm.id + WHERE aml.id = aml2.id + AND sm.sale_line_id IS NOT NULL; + """ + ) diff --git a/account_move_line_tax_editable/README.rst b/account_move_line_tax_editable/README.rst index 7f0c40958..2654b3052 100644 --- a/account_move_line_tax_editable/README.rst +++ b/account_move_line_tax_editable/README.rst @@ -2,10 +2,13 @@ Account Move Line Tax Editable ============================== -.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:92e996fa8ee6d33b5c39b0463dfe10e79a9258140e1fb84ea672722d12f98dad + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status @@ -19,11 +22,11 @@ Account Move Line Tax Editable .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png :target: https://translation.odoo-community.org/projects/account-financial-tools-14-0/account-financial-tools-14-0-account_move_line_tax_editable :alt: Translate me on Weblate -.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/92/14.0 - :alt: Try me on Runbot +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/account-financial-tools&target_branch=14.0 + :alt: Try me on Runboat -|badge1| |badge2| |badge3| |badge4| |badge5| +|badge1| |badge2| |badge3| |badge4| |badge5| Allows to edit taxes on account move lines. @@ -37,7 +40,7 @@ Bug Tracker 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 smashing it by providing a detailed and welcomed +If you spotted it first, help us to smash it by providing a detailed and welcomed `feedback `_. Do not contact contributors directly about support or help with technical issues. diff --git a/account_move_line_tax_editable/static/description/index.html b/account_move_line_tax_editable/static/description/index.html index c6029720a..3a8d894d2 100644 --- a/account_move_line_tax_editable/static/description/index.html +++ b/account_move_line_tax_editable/static/description/index.html @@ -1,20 +1,20 @@ - + - + Account Move Line Tax Editable + + +
+

Account Move Transfer Partner

+ + +

Alpha License: AGPL-3 OCA/account-financial-tools Translate me on Weblate Try me on Runboat

+

Add wizard to make transfer amount due from invoice / refund documents to specific partner

+
+

Important

+

This is an alpha version, the data model and design can change at any time without warning. +Only for development or testing purpose, do not use in production. +More details on development status

+
+

Table of contents

+ +
+

Usage

+

This wizard just can be used on invoice / refund documents

+
+
+

Bug Tracker

+

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.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • ForgeFlow S.L.
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

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.

+

Current maintainer:

+

ChrisOForgeFlow

+

This module is part of the OCA/account-financial-tools project on GitHub.

+

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

+
+
+
+ + diff --git a/account_move_transfer_partner/tests/__init__.py b/account_move_transfer_partner/tests/__init__.py new file mode 100644 index 000000000..a895df890 --- /dev/null +++ b/account_move_transfer_partner/tests/__init__.py @@ -0,0 +1 @@ +from . import test_account_move_transfer_partner diff --git a/account_move_transfer_partner/tests/test_account_move_transfer_partner.py b/account_move_transfer_partner/tests/test_account_move_transfer_partner.py new file mode 100644 index 000000000..3c52ece1f --- /dev/null +++ b/account_move_transfer_partner/tests/test_account_move_transfer_partner.py @@ -0,0 +1,352 @@ +# Copyright 2022 ForgeFlow S.L. +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +from odoo import _, fields +from odoo.exceptions import ValidationError +from odoo.tests.common import Form, TransactionCase + +CURRENCY_RATE = 0.5 + + +class TestAccountMoveTransferPartner(TransactionCase): + def setUp(self): + super().setUp() + self.company = self.env.ref("base.main_company") + self.partner_1 = self.env.ref("base.res_partner_1") + self.partner_2 = self.env.ref("base.res_partner_2") + self.partner_3 = self.env.ref("base.res_partner_3") + self.today = fields.Date.today() + + self.AccountJournal = self.env["account.journal"] + self.wizard_model = self.env["wizard.account.move.transfer.partner"] + self.sale_journal = self.AccountJournal.create( + { + "name": "Sale journal", + "code": "SALE", + "type": "sale", + } + ) + self.purchase_journal = self.AccountJournal.create( + { + "name": "Purchase journal", + "code": "PURCHASE", + "type": "purchase", + } + ) + self.general_journal = self.AccountJournal.create( + { + "name": "General journal", + "code": "GENERAL", + "type": "general", + } + ) + + self.ProductProduct = self.env["product.product"] + self.product = self.ProductProduct.create( + {"name": "Product", "price": 100.0, "standard_price": 100.0} + ) + charts = self.env["account.chart.template"].search([]) + if charts: + self.chart = charts[0] + else: + raise ValidationError(_("No Chart of Account Template has been defined !")) + self.AccountMove = self.env["account.move"] + with Form( + self.AccountMove.with_context(default_move_type="out_invoice") + ) as invoice_form: + invoice_form.invoice_date = self.today + invoice_form.partner_id = self.partner_2 + invoice_form.journal_id = self.sale_journal + with invoice_form.invoice_line_ids.new() as line_form: + line_form.product_id = self.product + self.invoice_1 = invoice_form.save() + self.invoice_2 = self.invoice_1.copy() + self.invoice_3 = self.invoice_1.copy() + invoice_form = Form(self.invoice_3) + invoice_form.partner_id = self.partner_2 + self.invoice_3 = invoice_form.save() + self.invoice_1.action_post() + self.invoice_2.action_post() + self.invoice_3.action_post() + + with Form( + self.AccountMove.with_context(default_move_type="in_invoice") + ) as invoice_form: + invoice_form.invoice_date = self.today + invoice_form.partner_id = self.partner_1 + invoice_form.journal_id = self.purchase_journal + with invoice_form.invoice_line_ids.new() as line_form: + line_form.product_id = self.product + self.in_invoice = invoice_form.save() + self.in_invoice.action_post() + + with Form( + self.AccountMove.with_context(default_move_type="out_refund") + ) as invoice_form: + invoice_form.invoice_date = self.today + invoice_form.partner_id = self.partner_1 + invoice_form.journal_id = self.sale_journal + with invoice_form.invoice_line_ids.new() as line_form: + line_form.product_id = self.product + self.out_refund = invoice_form.save() + self.out_refund.action_post() + with Form( + self.AccountMove.with_context(default_move_type="in_refund") + ) as invoice_form: + invoice_form.invoice_date = self.today + invoice_form.partner_id = self.partner_1 + invoice_form.journal_id = self.purchase_journal + with invoice_form.invoice_line_ids.new() as line_form: + line_form.product_id = self.product + self.in_refund = invoice_form.save() + self.in_refund.action_post() + + self.general_move = self.AccountMove.create( + { + "journal_id": self.general_journal.id, + "ref": "sample move", + "line_ids": [ + ( + 0, + 0, + { + "debit": 100.0, + "credit": 0, + "account_id": self.env["account.account"] + .search([("user_type_id.type", "=", "other")], limit=1) + .id, + }, + ), + ( + 0, + 0, + { + "debit": 0.0, + "credit": 100.0, + "account_id": self.env["account.account"] + .search([("user_type_id.type", "=", "other")], limit=1) + .id, + }, + ), + ], + } + ) + self.general_move.action_post() + self.payment_term = self.env["account.payment.term"].create( + { + "name": "Pay in 2 installments", + "line_ids": [ + # Pay 50% immediately + ( + 0, + 0, + { + "value": "percent", + "value_amount": 50, + }, + ), + # Pay the rest after 14 days + ( + 0, + 0, + { + "value": "balance", + "days": 14, + }, + ), + ], + } + ) + self.currency_2 = self.env["res.currency"].create( + { + "name": "test", + "symbol": "TEST", + "rate_ids": [ + ( + 0, + 0, + { + "name": fields.Date.today(), + "rate": CURRENCY_RATE, + }, + ) + ], + } + ) + self.AccountMoveReversal = self.env["account.move.reversal"] + + def test_01_account_move_transfer_partner(self): + self.assertEqual(self.invoice_1.payment_state, "not_paid") + self.assertEqual(self.invoice_2.payment_state, "not_paid") + self.assertEqual(self.invoice_3.payment_state, "not_paid") + all_invoices = self.invoice_1 + self.invoice_2 + self.invoice_3 + total_residual = sum(i.amount_residual for i in all_invoices) + wizard_form = Form( + self.wizard_model.with_context( + {"active_ids": self.invoice_1.ids, "active_model": "account.move"} + ) + ) + self.assertTrue(wizard_form.allow_edit_amount_to_transfer) + wizard_form.amount_to_transfer = self.invoice_1.amount_residual + 1 + wizard_form.destination_partner_id = self.partner_3 + wizard = wizard_form.save() + with self.assertRaises(ValidationError): + wizard.action_create_move() + wizard.write( + { + "amount_to_transfer": 0, + } + ) + with self.assertRaises(ValidationError): + wizard.action_create_move() + wizard_form = Form( + self.wizard_model.with_context( + {"active_ids": all_invoices.ids, "active_model": "account.move"} + ) + ) + with self.assertRaises(AssertionError): + wizard_form.amount_to_transfer = total_residual + 1 + wizard_form.destination_partner_id = self.partner_3 + self.assertFalse(wizard_form.allow_edit_amount_to_transfer) + wizard = wizard_form.save() + action = wizard.action_create_move() + self.assertEqual(self.invoice_1.payment_state, "paid") + self.assertEqual(self.invoice_2.payment_state, "paid") + self.assertEqual(self.invoice_3.payment_state, "paid") + new_moves = action.get("domain", []) and self.AccountMove.browse( + action.get("domain", [])[0][2] + ) + unreconciled_lines = new_moves.mapped("line_ids").filtered( + lambda x: not x.reconciled + ) + self.assertEqual( + unreconciled_lines.mapped("partner_id").ids, self.partner_3.ids + ) + + def test_02_account_move_transfer_partner(self): + wizard_form = Form( + self.wizard_model.with_context( + {"active_ids": self.in_invoice.ids, "active_model": "account.move"} + ) + ) + self.assertTrue(wizard_form.allow_edit_amount_to_transfer) + current_residual_amount = self.invoice_1.amount_residual + wizard_form.amount_to_transfer = current_residual_amount - 1 + wizard_form.destination_partner_id = self.partner_3 + wizard = wizard_form.save() + action = wizard.action_create_move() + self.assertEqual(self.in_invoice.amount_residual, 1.0) + new_moves = action.get("domain", []) and self.AccountMove.browse( + action.get("domain", [])[0][2] + ) + partner_1_aml = new_moves.mapped("line_ids").filtered( + lambda x: x.partner_id.id == self.partner_1.id + ) + self.assertEqual(abs(partner_1_aml.amount_residual), 0.0) + partner_3_aml = new_moves.mapped("line_ids").filtered( + lambda x: x.partner_id.id == self.partner_3.id + ) + self.assertEqual( + abs(partner_3_aml.amount_residual), current_residual_amount - 1 + ) + + def test_03_account_move_transfer_partner(self): + wizard_form = Form( + self.wizard_model.with_context( + {"active_ids": self.out_refund.ids, "active_model": "account.move"} + ) + ) + self.assertTrue(wizard_form.allow_edit_amount_to_transfer) + wizard_form.destination_partner_id = self.partner_3 + wizard = wizard_form.save() + wizard.action_create_move() + self.assertEqual(self.out_refund.amount_residual, 0.0) + + def test_04_account_move_transfer_partner(self): + wizard_form = Form( + self.wizard_model.with_context( + {"active_ids": self.in_refund.ids, "active_model": "account.move"} + ) + ) + self.assertTrue(wizard_form.allow_edit_amount_to_transfer) + wizard_form.destination_partner_id = self.partner_3 + wizard = wizard_form.save() + wizard.action_create_move() + self.assertEqual(self.in_refund.amount_residual, 0.0) + + def test_05_account_move_transfer_partner(self): + wizard_form = Form( + self.wizard_model.with_context( + {"active_ids": self.general_move.ids, "active_model": "account.move"} + ) + ) + self.assertFalse(wizard_form.allow_edit_amount_to_transfer) + self.assertTrue(wizard_form.no_invoice_documents) + wizard_form.destination_partner_id = self.partner_3 + wizard = wizard_form.save() + with self.assertRaises(ValidationError): + wizard.action_create_move() + + def test_06_account_move_transfer_partner(self): + with Form( + self.AccountMove.with_context(default_move_type="out_invoice") + ) as invoice_form: + invoice_form.invoice_date = self.today + invoice_form.partner_id = self.partner_2 + invoice_form.journal_id = self.sale_journal + invoice_form.currency_id = self.currency_2 + with invoice_form.invoice_line_ids.new() as line_form: + line_form.product_id = self.product + self.invoice_with_payment_term = invoice_form.save() + self.invoice_with_payment_term.action_post() + wizard_form = Form( + self.wizard_model.with_context( + { + "active_ids": self.invoice_with_payment_term.ids, + "active_model": "account.move", + } + ) + ) + self.assertTrue(wizard_form.allow_edit_amount_to_transfer) + wizard_form.destination_partner_id = self.partner_3 + self.assertEqual( + wizard_form.total_amount_due, + self.invoice_with_payment_term.currency_id.compute( + self.invoice_with_payment_term.amount_residual, + self.env.company.currency_id, + ), + ) + wizard_form.currency_id = self.currency_2 + self.assertEqual( + round(wizard_form.total_amount_due, 2), + round(self.invoice_with_payment_term.amount_residual, 2), + ) + + def test_07_account_move_transfer_partner(self): + with Form( + self.AccountMove.with_context(default_move_type="out_invoice") + ) as invoice_form: + invoice_form.invoice_date = self.today + invoice_form.partner_id = self.partner_2 + invoice_form.journal_id = self.sale_journal + invoice_form.invoice_payment_term_id = self.payment_term + with invoice_form.invoice_line_ids.new() as line_form: + line_form.product_id = self.product + self.invoice_with_payment_term = invoice_form.save() + self.invoice_with_payment_term.action_post() + wizard_form = Form( + self.wizard_model.with_context( + { + "active_ids": self.invoice_with_payment_term.ids, + "active_model": "account.move", + } + ) + ) + self.assertTrue(wizard_form.allow_edit_amount_to_transfer) + wizard_form.destination_partner_id = self.partner_3 + wizard = wizard_form.save() + action = wizard.action_create_move() + self.assertEqual(self.invoice_with_payment_term.amount_residual, 0.0) + new_moves = action.get("domain", []) and self.AccountMove.browse( + action.get("domain", [])[0][2] + ) + self.assertEqual(len(new_moves.mapped("line_ids")), 4) diff --git a/account_move_transfer_partner/wizard/__init__.py b/account_move_transfer_partner/wizard/__init__.py new file mode 100644 index 000000000..4d833f77d --- /dev/null +++ b/account_move_transfer_partner/wizard/__init__.py @@ -0,0 +1 @@ +from . import wizard_account_move_transfer_partner diff --git a/account_move_transfer_partner/wizard/wizard_account_move_transfer_partner.py b/account_move_transfer_partner/wizard/wizard_account_move_transfer_partner.py new file mode 100644 index 000000000..ea95b8758 --- /dev/null +++ b/account_move_transfer_partner/wizard/wizard_account_move_transfer_partner.py @@ -0,0 +1,234 @@ +# Copyright 2022 ForgeFlow S.L. +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError +from odoo.tools import float_compare + + +class WizardAccountMoveTransferPartner(models.TransientModel): + + _name = "wizard.account.move.transfer.partner" + _description = "Wizard to transfer due amount to another partner" + + origin_partner_ids = fields.Many2many( + comodel_name="res.partner", string="Origin Partner", readonly=True + ) + currency_id = fields.Many2one( + comodel_name="res.currency", + string="Currency", + default=lambda self: self.env.company.currency_id.id, + ) + move_ids = fields.Many2many( + comodel_name="account.move", string="Moves Selected", readonly=True + ) + destination_partner_id = fields.Many2one( + comodel_name="res.partner", string="Destination partner", required=True + ) + journal_id = fields.Many2one( + comodel_name="account.journal", + string="Journal", + required=True, + domain=[("type", "=", "general")], + default=lambda self: self.env["account.journal"] + .search([("type", "=", "general")], limit=1) + .id, + ) + account_date = fields.Date( + string="Account date", required=True, default=fields.Date.today() + ) + total_amount_due = fields.Monetary( + string="Total Amount Due", + readonly=True, + currency_field="currency_id", + ) + allow_edit_amount_to_transfer = fields.Boolean( + string="Allow edit amount to transfer?", + readonly=True, + ) + no_invoice_documents = fields.Boolean(string="No invoice documents?", readonly=True) + amount_to_transfer = fields.Monetary( + string="Amount to transfer", + required=True, + currency_field="currency_id", + ) + + @api.onchange("currency_id", "account_date") + def _onchange_currency_id(self): + if self.currency_id: + total_amount_due = 0 + for move in self.move_ids: + if move._origin: + real_move = move._origin + else: + real_move = move + total_amount_due += real_move.currency_id.with_context( + date=self.account_date or fields.Date.today() + ).compute(real_move.amount_residual, self.currency_id) + if real_move.payment_id: + ( + liquidity_lines, + counterpart_lines, + writeoff_lines, + ) = real_move.payment_id._seek_for_lines() + payment_amount_due = abs( + sum(counterpart_lines.mapped("amount_residual")) + ) + total_amount_due += real_move.payment_id.currency_id.with_context( + date=self.account_date or fields.Date.today() + ).compute(payment_amount_due, self.currency_id) + self.total_amount_due = total_amount_due + self.amount_to_transfer = self.total_amount_due + + @api.model + def default_get(self, fields_list): + values = super(WizardAccountMoveTransferPartner, self).default_get(fields_list) + current_model = self.env.context.get("active_model") + moves = self.env["account.move"].browse() + records = self.env[current_model].browse(self.env.context.get("active_ids")) + if current_model == "account.payment": + moves = records.mapped("move_id") + elif current_model == "account.move": + moves = records + moves = moves.filtered(lambda x: x.state == "posted") + allowed_moves = moves.filtered(lambda x: x.is_invoice() or x.payment_id) + values["origin_partner_ids"] = moves.mapped("partner_id").ids + values["move_ids"] = allowed_moves.ids + values["no_invoice_documents"] = len(moves - allowed_moves) >= 1 + due_amount = abs(sum(allowed_moves.mapped("amount_residual"))) + for payment in allowed_moves.mapped("payment_id"): + ( + liquidity_lines, + counterpart_lines, + writeoff_lines, + ) = payment._seek_for_lines() + due_amount += abs(sum(counterpart_lines.mapped("amount_residual"))) + values["total_amount_due"] = due_amount + values["amount_to_transfer"] = due_amount + values["allow_edit_amount_to_transfer"] = len(allowed_moves) == 1 + return values + + def action_create_move(self): + am_model = self.env["account.move"] + aml_model = self.env["account.move.line"].with_context( + check_move_validity=False + ) + if self.amount_to_transfer <= 0: + raise ValidationError(_("Amount to transfer should be bigger than zero")) + if ( + float_compare( + self.amount_to_transfer, + self.total_amount_due, + precision_rounding=self.env.company.currency_id.rounding or 0.01, + ) + == 1 + ): + raise ValidationError( + _( + "Amount to transfer %s should be equal or lower than total amount due %s" + ) + % (self.amount_to_transfer, self.total_amount_due) + ) + new_moves = am_model.browse() + for move in self.move_ids: + new_move = am_model.create( + { + "date": self.account_date, + "journal_id": self.journal_id.id, + "ref": _("Transfer amount due from %s") % (move.display_name), + "state": "draft", + "move_type": "entry", + } + ) + reconcilable_account = move.line_ids.mapped("account_id").filtered( + lambda x: x.user_type_id.type in ("receivable", "payable") + ) + if move.payment_id: + ( + liquidity_lines, + counterpart_lines, + writeoff_lines, + ) = move.payment_id._seek_for_lines() + lines = counterpart_lines.filtered(lambda x: not x.reconciled) + else: + lines = move.line_ids.filtered( + lambda line: line.account_id == reconcilable_account + and not line.reconciled + ) + common_data = { + "account_id": reconcilable_account.id, + "move_id": new_move.id, + "currency_id": self.currency_id.id, + "ref": _("Transfer due amount from %s") % move.display_name, + } + amount_to_apply = ( + self.allow_edit_amount_to_transfer + and self.amount_to_transfer + or move.amount_residual + ) + credit_aml = aml_model.browse() + debit_aml = aml_model.browse() + for line in lines: + amount = min(amount_to_apply, abs(line.amount_residual)) + amount_to_apply -= amount + amount_currency = ( + move.currency_id.id != self.currency_id.id and amount or 0.0 + ) + amount = self.currency_id.with_context(date=self.account_date).compute( + amount, move.currency_id + ) + credit_line_data = common_data.copy() + debit_line_data = common_data.copy() + is_inbound = ( + move.is_inbound() or move.payment_id.partner_type == "supplier" + ) + is_outbound = ( + move.is_outbound() or move.payment_id.partner_type == "customer" + ) + partner = line.move_id.payment_id.partner_id or line.move_id.partner_id + credit_line_data.update( + { + "partner_id": is_inbound + and partner.id + or is_outbound + and self.destination_partner_id.id, + "credit": amount, + "debit": 0.0, + "amount_currency": -amount_currency, + "date_maturity": line.date_maturity, + } + ) + debit_line_data.update( + { + "partner_id": is_inbound + and self.destination_partner_id.id + or is_outbound + and partner.id, + "credit": 0.0, + "debit": amount, + "amount_currency": amount_currency, + "date_maturity": line.date_maturity, + } + ) + credit_aml += aml_model.create(credit_line_data) + debit_aml += aml_model.create(debit_line_data) + new_move.action_post() + if is_inbound: + if move.payment_id: + lines_not_reconciled = lines.filtered(lambda x: not x.reconciled) + lines_not_reconciled |= credit_aml + lines_not_reconciled.reconcile() + else: + for aml in credit_aml: + move.js_assign_outstanding_line(aml.id) + if is_outbound: + if move.payment_id: + lines_not_reconciled = lines.filtered(lambda x: not x.reconciled) + lines_not_reconciled |= debit_aml + lines_not_reconciled.reconcile() + else: + for aml in debit_aml: + move.js_assign_outstanding_line(aml.id) + new_moves |= new_move + action = self.env.ref("account.action_move_journal_line").read()[0] + action.update({"domain": [("id", "in", new_moves.ids)]}) + return action diff --git a/account_move_transfer_partner/wizard/wizard_account_move_transfer_partner_view.xml b/account_move_transfer_partner/wizard/wizard_account_move_transfer_partner_view.xml new file mode 100644 index 000000000..5ed76a599 --- /dev/null +++ b/account_move_transfer_partner/wizard/wizard_account_move_transfer_partner_view.xml @@ -0,0 +1,110 @@ + + + + + + wizard_account_move_transfer_partner_view_form + wizard.account.move.transfer.partner + +
+ + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ + + Transfer amount due to another partner + ir.actions.act_window + wizard.account.move.transfer.partner + form + new + + + + + Transfer amount due to another partner + ir.actions.act_window + wizard.account.move.transfer.partner + form + new + + + +
+
diff --git a/account_netting/README.rst b/account_netting/README.rst index 149084403..5fa33f135 100644 --- a/account_netting/README.rst +++ b/account_netting/README.rst @@ -2,10 +2,13 @@ Account netting =============== -.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:f881f38e10e03a046f8d6b17366261bc482854db689c27b0e54c91beca68dd25 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status @@ -19,11 +22,11 @@ Account netting .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png :target: https://translation.odoo-community.org/projects/account-financial-tools-14-0/account-financial-tools-14-0-account_netting :alt: Translate me on Weblate -.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/92/14.0 - :alt: Try me on Runbot +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/account-financial-tools&target_branch=14.0 + :alt: Try me on Runboat -|badge1| |badge2| |badge3| |badge4| |badge5| +|badge1| |badge2| |badge3| |badge4| |badge5| This module allows to compensate the balance of a receivable account with the balance of a payable account for the same partner, creating a journal item @@ -60,7 +63,7 @@ Bug Tracker 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 smashing it by providing a detailed and welcomed +If you spotted it first, help us to smash it by providing a detailed and welcomed `feedback `_. Do not contact contributors directly about support or help with technical issues. diff --git a/account_netting/i18n/it.po b/account_netting/i18n/it.po index efb2f722e..6145f3236 100644 --- a/account_netting/i18n/it.po +++ b/account_netting/i18n/it.po @@ -9,15 +9,15 @@ msgstr "" "Project-Id-Version: Odoo Server 10.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2017-12-03 03:46+0000\n" -"PO-Revision-Date: 2022-04-12 18:05+0000\n" -"Last-Translator: Francesco Foresti \n" +"PO-Revision-Date: 2023-03-30 12:22+0000\n" +"Last-Translator: mymage \n" "Language-Team: Italian (https://www.transifex.com/oca/teams/23907/it/)\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.3.2\n" +"X-Generator: Weblate 4.14.1\n" #. module: account_netting #: code:addons/account_netting/wizards/account_move_make_netting.py:0 @@ -83,7 +83,7 @@ msgstr "Creato il" #. module: account_netting #: model:ir.model.fields,field_description:account_netting.field_account_move_make_netting__display_name msgid "Display Name" -msgstr "Nome da visualizzare" +msgstr "Nome visualizzato" #. module: account_netting #: model:ir.model.fields,field_description:account_netting.field_account_move_make_netting__id diff --git a/account_netting/i18n/sl.po b/account_netting/i18n/sl.po index cd0add640..5e2a5530e 100644 --- a/account_netting/i18n/sl.po +++ b/account_netting/i18n/sl.po @@ -9,15 +9,16 @@ msgstr "" "Project-Id-Version: Odoo Server 10.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2017-12-03 03:46+0000\n" -"PO-Revision-Date: 2017-12-03 03:46+0000\n" -"Last-Translator: OCA Transbot , 2017\n" +"PO-Revision-Date: 2023-03-31 21:24+0000\n" +"Last-Translator: Matjaz Mozetic \n" "Language-Team: Slovenian (https://www.transifex.com/oca/teams/23907/sl/)\n" "Language: sl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" -"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n" -"%100==4 ? 2 : 3);\n" +"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n" +"%100==4 ? 2 : 3;\n" +"X-Generator: Weblate 4.14.1\n" #. module: account_netting #: code:addons/account_netting/wizards/account_move_make_netting.py:0 @@ -83,7 +84,7 @@ msgstr "Ustvarjeno" #. module: account_netting #: model:ir.model.fields,field_description:account_netting.field_account_move_make_netting__display_name msgid "Display Name" -msgstr "Prikazni naziv" +msgstr "Prikazani naziv" #. module: account_netting #: model:ir.model.fields,field_description:account_netting.field_account_move_make_netting__id diff --git a/account_netting/static/description/index.html b/account_netting/static/description/index.html index c5d6b2082..367bdd501 100644 --- a/account_netting/static/description/index.html +++ b/account_netting/static/description/index.html @@ -1,20 +1,20 @@ - + - + Account netting + + +
+

Cost-Revenue Spread Extra Features

+ + +

Beta License: AGPL-3 OCA/account-financial-tools Translate me on Weblate Try me on Runboat

+

This module aim to address more business cases by adding extra technical function.

+
    +
  1. +
    Add action to direct link with journal item (account.move.line) from spread cost/revenue sheet.
    +
    This is useful when user want to link spread cost/revenue sheet with journal entry (not with invoice)
    +
    +
  2. +
  3. From spread cost/revenue sheet, allow Create Entry as Invoice (not just entry)
  4. +
+

Note: extra feature in this module is not included in account_spread_cost_revenue to avoid complexity.

+

Table of contents

+ +
+

Bug Tracker

+

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.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Ecosoft
  • +
+
+ +
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

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.

+

Current maintainer:

+

kittiu

+

This module is part of the OCA/account-financial-tools project on GitHub.

+

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

+
+
+
+ + diff --git a/account_spread_cost_revenue_enhanced/views/account_spread.xml b/account_spread_cost_revenue_enhanced/views/account_spread.xml new file mode 100644 index 000000000..6cad79c3e --- /dev/null +++ b/account_spread_cost_revenue_enhanced/views/account_spread.xml @@ -0,0 +1,16 @@ + + + + view.account.spread + account.spread + + + + + + + + diff --git a/account_spread_cost_revenue_enhanced/wizards/__init__.py b/account_spread_cost_revenue_enhanced/wizards/__init__.py new file mode 100644 index 000000000..8eb52ce6c --- /dev/null +++ b/account_spread_cost_revenue_enhanced/wizards/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import account_spread_link_move_line diff --git a/account_spread_cost_revenue_enhanced/wizards/account_spread_link_move_line.py b/account_spread_cost_revenue_enhanced/wizards/account_spread_link_move_line.py new file mode 100644 index 000000000..f129b9ba8 --- /dev/null +++ b/account_spread_cost_revenue_enhanced/wizards/account_spread_link_move_line.py @@ -0,0 +1,37 @@ +# Copyright 2021 Ecosoft Co., Ltd (http://ecosoft.co.th/) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) + +from odoo import _, api, fields, models +from odoo.exceptions import UserError + + +class AccountSpreadLinkMoveLine(models.TransientModel): + _name = "account.spread.link.move.line" + _description = "Link spread cost/revenue sheet with journal item" + + move_id = fields.Many2one( + comodel_name="account.move", + string="Journal Entry", + required=True, + ) + move_line_id = fields.Many2one( + comodel_name="account.move.line", + string="Journal Item", + domain="[('move_id', '=', move_id), ('spread_id', '=', False)]", + required=True, + ) + + @api.onchange("move_id") + def _onchange_move_id(self): + self.move_line_id = False + + def link_move_line(self): + active_id = self.env.context.get("active_id") + spread = self.env["account.spread"].browse(active_id) + if spread.invoice_line_id: + raise UserError( + _( + "Already linked with a journal item, please unlink the existing one first." + ) + ) + spread.invoice_line_id = self.move_line_id diff --git a/account_spread_cost_revenue_enhanced/wizards/account_spread_link_move_line.xml b/account_spread_cost_revenue_enhanced/wizards/account_spread_link_move_line.xml new file mode 100644 index 000000000..6a71d4cf5 --- /dev/null +++ b/account_spread_cost_revenue_enhanced/wizards/account_spread_link_move_line.xml @@ -0,0 +1,41 @@ + + + + view.account.spread.link.move.line.form + account.spread.link.move.line + +
+

+ Please choose the Journal Entry, and then the Journal Item you want to link with this spread costs/revenues sheet. +

+ + + + +
+
+
+
+
+ + + Link with Journal Item + account.spread.link.move.line + form + + new + + form + +
diff --git a/account_template_active/README.rst b/account_template_active/README.rst index 421153808..6b5d3967c 100644 --- a/account_template_active/README.rst +++ b/account_template_active/README.rst @@ -2,10 +2,13 @@ Disable Account Template Items ============================== -.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:562c81a21170958494f956f5123a75d960c66da4f9d9f8918f00bb07ae25ff44 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status @@ -19,11 +22,11 @@ Disable Account Template Items .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png :target: https://translation.odoo-community.org/projects/account-financial-tools-14-0/account-financial-tools-14-0-account_template_active :alt: Translate me on Weblate -.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/92/14.0 - :alt: Try me on Runbot +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/account-financial-tools&target_branch=14.0 + :alt: Try me on Runboat -|badge1| |badge2| |badge3| |badge4| |badge5| +|badge1| |badge2| |badge3| |badge4| |badge5| This module allows to disable account template items, adding an ``active`` field on the following models: @@ -82,7 +85,7 @@ Bug Tracker 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 smashing it by providing a detailed and welcomed +If you spotted it first, help us to smash it by providing a detailed and welcomed `feedback `_. Do not contact contributors directly about support or help with technical issues. diff --git a/account_template_active/static/description/index.html b/account_template_active/static/description/index.html index ef7583251..126e5fdbf 100644 --- a/account_template_active/static/description/index.html +++ b/account_template_active/static/description/index.html @@ -1,20 +1,20 @@ - + - + Disable Account Template Items