diff --git a/.docker_files/main/__manifest__.py b/.docker_files/main/__manifest__.py
index 1fa24a63..00e518fb 100644
--- a/.docker_files/main/__manifest__.py
+++ b/.docker_files/main/__manifest__.py
@@ -50,7 +50,8 @@
"canada_bank_transfer",
"hr_expense_tax_adjustment",
"invoice_currency_validation",
- # "invoice_fiscal_position_required", # FIX ME: Conflict with UT of account_invoice_constraint_chronology OCA Module
+ # FIX ME: Conflict with UT of account_invoice_constraint_chronology OCA Module
+ # "invoice_fiscal_position_required",
"invoice_intercompany_compatible",
"invoice_list_email",
"invoice_mass_mailing_with_layout",
diff --git a/.flake8 b/.flake8
new file mode 100644
index 00000000..15d225b7
--- /dev/null
+++ b/.flake8
@@ -0,0 +1,12 @@
+[flake8]
+max-line-length = 88
+max-complexity = 16
+# B = bugbear
+# B9 = bugbear opinionated (incl line length)
+select = C,E,F,W,B,B9
+# E203: whitespace before ':' (black behaviour)
+# E501: flake8 line length (covered by bugbear B950)
+# W503: line break before binary operator (black behaviour)
+ignore = E203,E501,W503,F821
+per-file-ignores=
+ __init__.py:F401
\ No newline at end of file
diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml
new file mode 100644
index 00000000..2894822e
--- /dev/null
+++ b/.github/workflows/pre-commit.yml
@@ -0,0 +1,36 @@
+name: pre-commit
+
+on:
+ pull_request:
+ branches:
+ - "14.0*"
+ push:
+ branches:
+ - "14.0"
+
+jobs:
+ pre-commit:
+ runs-on: ubuntu-22.04
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-python@v2
+ with:
+ python-version: "3.11"
+ - name: Get python version
+ run: echo "PY=$(python -VV | sha256sum | cut -d' ' -f1)" >> $GITHUB_ENV
+ - uses: actions/cache@v1
+ with:
+ path: ~/.cache/pre-commit
+ key: pre-commit|${{ env.PY }}|${{ hashFiles('.pre-commit-config.yaml') }}
+ - name: Install pre-commit
+ run: pip install pre-commit
+ - name: Run pre-commit
+ run: pre-commit run --all-files --show-diff-on-failure --color=always
+ - name: Check that all files generated by pre-commit are in git
+ run: |
+ newfiles="$(git ls-files --others --exclude-from=.gitignore)"
+ if [ "$newfiles" != "" ] ; then
+ echo "Please check-in the following files:"
+ echo "$newfiles"
+ exit 1
+ fi
\ No newline at end of file
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 00000000..004b7146
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,30 @@
+exclude: |
+ (?x)
+ # NOT INSTALLABLE ADDONS
+ # END NOT INSTALLABLE ADDONS
+ # Files and folders generated by bots, to avoid loops
+ ^setup/|/static/description/index\.html$|
+ # We don't want to mess with tool-generated files
+ .svg$|/tests/([^/]+/)?cassettes/|^.copier-answers.yml$|^.github/|
+ # Maybe reactivate this when all README files include prettier ignore tags?
+ ^README\.md$|
+ # Library files can have extraneous formatting (even minimized)
+ /static/(src/)?lib/|
+ # Repos using Sphinx to generate docs don't need prettying
+ ^docs/_templates/.*\.html$|
+ # Don't bother non-technical authors with formatting issues in docs
+ readme/.*\.(rst|md)$|
+ # Ignore build and dist directories in addons
+ /build/|/dist/|
+ # You don't usually want a bot to modify your legal texts
+ (LICENSE.*|COPYING.*)
+default_language_version:
+ python: python3
+ node: "14.13.0"
+repos:
+ - repo: https://github.com/PyCQA/flake8
+ rev: 3.8.3
+ hooks:
+ - id: flake8
+ name: flake8
+ additional_dependencies: ["flake8-bugbear==20.1.4"]
\ No newline at end of file
diff --git a/.unported_addons/account_budget_balance/README.rst b/.unported_addons/account_budget_balance/README.rst
deleted file mode 100644
index b8bdc9ea..00000000
--- a/.unported_addons/account_budget_balance/README.rst
+++ /dev/null
@@ -1,19 +0,0 @@
-Account Budget Balance
-======================
-This module adds a `Balance` column to the budget lines.
-
-.. image:: static/description/budget_form.png
-
-The field is computed as follow:
-
-..
-
- Planned Amount - Practical Amount = Balance Amount
-
-The field is available in the `Budget Analysis` report.
-
-.. image:: static/description/budget_line_pivot.png
-
-Contributors
-------------
-* Numigi (tm) and all its contributors (https://bit.ly/numigiens)
diff --git a/.unported_addons/account_budget_balance/__init__.py b/.unported_addons/account_budget_balance/__init__.py
deleted file mode 100644
index 21228467..00000000
--- a/.unported_addons/account_budget_balance/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# © 2019 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-from . import models
diff --git a/.unported_addons/account_budget_balance/__manifest__.py b/.unported_addons/account_budget_balance/__manifest__.py
deleted file mode 100644
index 1f5c04d8..00000000
--- a/.unported_addons/account_budget_balance/__manifest__.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# © 2019 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-{
- 'name': 'Account Budget Balance',
- 'version': '1.0.0',
- 'author': 'Numigi',
- 'maintainer': 'Numigi',
- 'website': 'https://www.numigi.com',
- 'license': 'LGPL-3',
- 'category': 'Accounting',
- 'summary': 'Add the balance amount to the budget lines',
- 'depends': [
- 'account_budget',
- ],
- 'data': [
- 'views/crossovered_budget.xml',
- 'views/crossovered_budget_lines.xml',
- ],
- 'installable': False,
-}
diff --git a/.unported_addons/account_budget_balance/i18n/fr.po b/.unported_addons/account_budget_balance/i18n/fr.po
deleted file mode 100644
index b5fcfbd3..00000000
--- a/.unported_addons/account_budget_balance/i18n/fr.po
+++ /dev/null
@@ -1,32 +0,0 @@
-# Translation of Odoo Server.
-# This file contains the translation of the following modules:
-# * account_budget_balance
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: Odoo Server 12.0+e\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-06-13 19:47+0000\n"
-"PO-Revision-Date: 2019-06-13 19:47+0000\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_budget_balance
-#: model:ir.model.fields,field_description:account_budget_balance.field_crossovered_budget_lines__balance
-#: model_terms:ir.ui.view,arch_db:account_budget_balance.budget_form_with_balance
-msgid "Balance"
-msgstr "Balance"
-
-#. module: account_budget_balance
-#: model:ir.model,name:account_budget_balance.model_crossovered_budget_lines
-msgid "Budget Line"
-msgstr ""
-
-#. module: account_budget_balance
-#: model:ir.model.fields,help:account_budget_balance.field_crossovered_budget_lines__balance
-msgid "The balance amount is equal to the planned amount minus the practical amount."
-msgstr "Le montant de balance est égal au montant prévu moins le montant réel."
diff --git a/.unported_addons/account_budget_balance/models/__init__.py b/.unported_addons/account_budget_balance/models/__init__.py
deleted file mode 100644
index 639ad51b..00000000
--- a/.unported_addons/account_budget_balance/models/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# © 2019 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-from . import crossovered_budget_lines
diff --git a/.unported_addons/account_budget_balance/models/crossovered_budget_lines.py b/.unported_addons/account_budget_balance/models/crossovered_budget_lines.py
deleted file mode 100644
index 32f58aad..00000000
--- a/.unported_addons/account_budget_balance/models/crossovered_budget_lines.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# © 2019 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-from odoo import api, fields, models
-
-
-class CrossoveredBudgetLines(models.Model):
-
- _inherit = "crossovered.budget.lines"
-
- balance = fields.Monetary(
- compute="_compute_balance_amount",
- string="Balance",
- help="The balance amount is equal to the planned amount "
- "minus the practical amount."
- )
-
- @api.depends('planned_amount', 'practical_amount')
- def _compute_balance_amount(self):
- for line in self:
- line.balance = line.planned_amount - line.practical_amount
-
- @api.model
- def read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True):
- """Allow reading the balance amount with group read.
-
- This is inspired by what is done in the module account_budget with the fields
- practical_amount, theoritical_amount and percentage.
- """
- result = super().read_group(
- domain, fields, groupby,
- offset=offset, limit=limit, orderby=orderby, lazy=lazy
- )
- if 'balance' in fields:
- for group_line in result:
- group_domain = group_line.get('__domain') or domain
- lines_that_compose_group = self.search(group_domain)
- group_line['balance'] = sum(lines_that_compose_group.mapped('balance'))
-
- return result
diff --git a/.unported_addons/account_budget_balance/static/description/budget_form.png b/.unported_addons/account_budget_balance/static/description/budget_form.png
deleted file mode 100644
index 27e09857..00000000
Binary files a/.unported_addons/account_budget_balance/static/description/budget_form.png and /dev/null differ
diff --git a/.unported_addons/account_budget_balance/static/description/budget_line_pivot.png b/.unported_addons/account_budget_balance/static/description/budget_line_pivot.png
deleted file mode 100644
index ac57b3dc..00000000
Binary files a/.unported_addons/account_budget_balance/static/description/budget_line_pivot.png and /dev/null differ
diff --git a/.unported_addons/account_budget_balance/static/description/icon.png b/.unported_addons/account_budget_balance/static/description/icon.png
deleted file mode 100644
index 92a86b10..00000000
Binary files a/.unported_addons/account_budget_balance/static/description/icon.png and /dev/null differ
diff --git a/.unported_addons/account_budget_balance/tests/__init__.py b/.unported_addons/account_budget_balance/tests/__init__.py
deleted file mode 100644
index d2ac44f2..00000000
--- a/.unported_addons/account_budget_balance/tests/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-# © 2019 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
diff --git a/.unported_addons/account_budget_balance/tests/test_balance_read_group.py b/.unported_addons/account_budget_balance/tests/test_balance_read_group.py
deleted file mode 100644
index abfd6f71..00000000
--- a/.unported_addons/account_budget_balance/tests/test_balance_read_group.py
+++ /dev/null
@@ -1,93 +0,0 @@
-# © 2019 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-from datetime import datetime, timedelta
-from odoo.tests import common
-
-
-class TestBalanceReadGroup(common.SavepointCase):
-
- @classmethod
- def setUpClass(cls):
- super().setUpClass()
- cls.budget_1 = cls.env['crossovered.budget'].create({
- 'name': 'Budget Test 1',
- 'date_from': datetime.now(),
- 'date_to': datetime.now() + timedelta(365),
- })
-
- cls.budget_2 = cls.env['crossovered.budget'].create({
- 'name': 'Budget Test 2',
- 'date_from': datetime.now(),
- 'date_to': datetime.now() + timedelta(365),
- })
-
- cls.account_1 = cls.env['account.analytic.account'].create({'name': 'Account 1'})
- cls.account_2 = cls.env['account.analytic.account'].create({'name': 'Account 2'})
- cls.account_3 = cls.env['account.analytic.account'].create({'name': 'Account 3'})
-
- cls.budget_line_1 = cls.env['crossovered.budget.lines'].create({
- 'crossovered_budget_id': cls.budget_1.id,
- 'analytic_account_id': cls.account_1.id,
- 'planned_amount': 1000,
- 'date_from': cls.budget_1.date_from,
- 'date_to': cls.budget_1.date_to,
- })
-
- cls.budget_line_2 = cls.env['crossovered.budget.lines'].create({
- 'crossovered_budget_id': cls.budget_1.id,
- 'analytic_account_id': cls.account_2.id,
- 'planned_amount': 2000,
- 'date_from': cls.budget_1.date_from,
- 'date_to': cls.budget_1.date_to,
- })
-
- cls.budget_line_3 = cls.env['crossovered.budget.lines'].create({
- 'crossovered_budget_id': cls.budget_2.id,
- 'analytic_account_id': cls.account_3.id,
- 'planned_amount': 5000,
- 'date_from': cls.budget_2.date_from,
- 'date_to': cls.budget_2.date_to,
- })
-
- cls.line_1 = cls.env['account.analytic.line'].create({
- 'account_id': cls.account_1.id,
- 'name': '/',
- 'amount': 100,
- })
-
- cls.line_2 = cls.env['account.analytic.line'].create({
- 'account_id': cls.account_2.id,
- 'name': '/',
- 'amount': 200,
- })
-
- cls.line_3 = cls.env['account.analytic.line'].create({
- 'account_id': cls.account_3.id,
- 'name': '/',
- 'amount': 500,
- })
-
- cls.budget_lines = cls.budget_line_1 | cls.budget_line_2 | cls.budget_line_3
- cls.search_domain = [('id', 'in', cls.budget_lines.ids)]
-
- def test_read_group_by_budget(self):
- result = self.env['crossovered.budget.lines'].read_group(
- self.search_domain, ['balance'], ['crossovered_budget_id'],
- orderby='crossovered_budget_id asc'
- )
-
- assert len(result) == 2
- assert result[0]['balance'] == 2700 # 1000 + 2000 - 100 - 200
- assert result[1]['balance'] == 4500 # 5000 - 500
-
- def test_read_group_by_analytic_account(self):
- result = self.env['crossovered.budget.lines'].read_group(
- self.search_domain, ['balance'], ['analytic_account_id'],
- orderby='analytic_account_id asc'
- )
-
- assert len(result) == 3
- assert result[0]['balance'] == 900 # 1000 - 100
- assert result[1]['balance'] == 1800 # 2000 - 200
- assert result[2]['balance'] == 4500 # 5000 - 500
diff --git a/.unported_addons/account_budget_balance/views/crossovered_budget.xml b/.unported_addons/account_budget_balance/views/crossovered_budget.xml
deleted file mode 100644
index 7ece170f..00000000
--- a/.unported_addons/account_budget_balance/views/crossovered_budget.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
- Budget Form: add balance amount
- crossovered.budget
-
-
-
-
-
-
-
-
-
diff --git a/.unported_addons/account_budget_balance/views/crossovered_budget_lines.xml b/.unported_addons/account_budget_balance/views/crossovered_budget_lines.xml
deleted file mode 100644
index 94a577f6..00000000
--- a/.unported_addons/account_budget_balance/views/crossovered_budget_lines.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
-
-
- Budget Line Form: add balance amount
- crossovered.budget.lines
-
-
-
-
-
-
-
-
-
- Budget Line List: add balance amount
- crossovered.budget.lines
-
-
-
-
-
-
-
-
-
- Budget Line Pivot: add balance amount
- crossovered.budget.lines
-
-
-
-
-
-
-
-
-
- Budget Line Graph: add balance amount
- crossovered.budget.lines
-
-
-
-
-
-
-
-
-
diff --git a/.unported_addons/account_manual_entry_restricted/README.rst b/.unported_addons/account_manual_entry_restricted/README.rst
deleted file mode 100644
index 1661ea68..00000000
--- a/.unported_addons/account_manual_entry_restricted/README.rst
+++ /dev/null
@@ -1,51 +0,0 @@
-Account Manual Entry Restricted
-===============================
-
-.. contents:: Table of Contents
-
-Context
--------
-In vanilla Odoo, a user with basic access may create and post journal entries manually.
-
-As accountant / controller, you might want to keep control over some specific accounts.
-You do not want people to accidentaly write in these accounts.
-
-Summary
--------
-This module adds a field `Entry Restriction` on accounts.
-
-.. image:: static/description/account_form.png
-
-This field allows to select one or many user groups.
-
-These groups are allowed to post manual journal entries with this account.
-Other groups are forbidden.
-
-If the field is empty, then no restriction is applied on this account.
-
-Automatic Entries
-~~~~~~~~~~~~~~~~~
-These restrictions do not apply for journal entries generated automatically
-for invoices, payments, expenses, etc.
-
-Usage
------
-As member of the group `Accounting / Advisor`, I go to the form view of an account.
-
-I select the group `Accounting / Advisor`.
-
-.. image:: static/description/account_form.png
-
-Manual Entries
-~~~~~~~~~~~~~~
-As member of the group `Accounting / User`, I create a new journal entry with the restricted account.
-
-.. image:: static/description/journal_entry.png
-
-When I click on `Post`, a blocking message appears.
-
-.. image:: static/description/journal_entry_message.png
-
-Contributors
-------------
-* Numigi (tm) and all its contributors (https://bit.ly/numigiens)
diff --git a/.unported_addons/account_manual_entry_restricted/__init__.py b/.unported_addons/account_manual_entry_restricted/__init__.py
deleted file mode 100644
index 21228467..00000000
--- a/.unported_addons/account_manual_entry_restricted/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# © 2019 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-from . import models
diff --git a/.unported_addons/account_manual_entry_restricted/__manifest__.py b/.unported_addons/account_manual_entry_restricted/__manifest__.py
deleted file mode 100644
index ee9f9d07..00000000
--- a/.unported_addons/account_manual_entry_restricted/__manifest__.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# © 2019 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-{
- 'name': 'Account Manual Entry Restricted',
- 'version': '1.0.0',
- 'author': 'Numigi',
- 'maintainer': 'Numigi',
- 'website': 'https://www.numigi.com',
- 'license': 'LGPL-3',
- 'category': 'Accounting',
- 'summary': 'Restrict manual journal entries per account',
- 'depends': [
- 'account',
- ],
- 'data': [
- 'views/account.xml',
- ],
- 'installable': False,
-}
diff --git a/.unported_addons/account_manual_entry_restricted/i18n/fr.po b/.unported_addons/account_manual_entry_restricted/i18n/fr.po
deleted file mode 100644
index 966f94be..00000000
--- a/.unported_addons/account_manual_entry_restricted/i18n/fr.po
+++ /dev/null
@@ -1,49 +0,0 @@
-# Translation of Odoo Server.
-# This file contains the translation of the following modules:
-# * account_manual_entry_restricted
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: Odoo Server 12.0+e\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-06-10 21:29+0000\n"
-"PO-Revision-Date: 2019-06-10 21:29+0000\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_manual_entry_restricted
-#: code:addons/account_manual_entry_restricted/models.py:33
-#, python-format
-msgid "Access right error:\n"
-"\n"
-"Only the following user group(s) are authorized to post in the account {account}:\n"
-"\n"
-"{groups}\n"
-"\n"
-"Please contact your administrator."
-msgstr "Erreur de droits d'accès :\n"
-"\n"
-"Seul(s) le(s) groupe(s) de droits suivant(s) sont autorisés à saisir dans le compte {account} :\n"
-"\n"
-"{groups}\n"
-"\n"
-"Veuillez contacter votre administrateur."
-
-#. module: account_manual_entry_restricted
-#: model:ir.model,name:account_manual_entry_restricted.model_account_account
-msgid "Account"
-msgstr ""
-
-#. module: account_manual_entry_restricted
-#: model:ir.model.fields,field_description:account_manual_entry_restricted.field_account_account__manual_entry_group_ids
-msgid "Entry Restriction"
-msgstr "Restriction saisie"
-
-#. module: account_manual_entry_restricted
-#: model:ir.model,name:account_manual_entry_restricted.model_account_move
-msgid "Journal Entries"
-msgstr ""
diff --git a/.unported_addons/account_manual_entry_restricted/models.py b/.unported_addons/account_manual_entry_restricted/models.py
deleted file mode 100644
index 1a0e8d3f..00000000
--- a/.unported_addons/account_manual_entry_restricted/models.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# © 2019 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-from odoo import api, fields, models, _
-from odoo.exceptions import ValidationError
-
-
-class Account(models.Model):
-
- _inherit = 'account.account'
-
- manual_entry_group_ids = fields.Many2many(
- 'res.groups',
- 'account_manual_entry_group_rel',
- 'account_id',
- 'group_id',
- 'Entry Restriction',
- )
-
-
-class JournalEntry(models.Model):
-
- _inherit = 'account.move'
-
- def _check_manual_entry_restrictions(self):
- restricted_accounts = self.mapped('line_ids.account_id').filtered(
- lambda a: a.manual_entry_group_ids)
-
- for account in restricted_accounts:
- allowed_groups = account.manual_entry_group_ids
- user_is_forbidden = not (allowed_groups & self.env.user.groups_id)
- if user_is_forbidden:
- raise ValidationError(_(
- 'Access right error:\n\n'
- 'Only the following user group(s) are authorized to post in the account '
- '{account}:\n\n'
- '{groups}'
- '\n\n'
- 'Please contact your administrator.'
- ).format(
- account=account.display_name,
- groups='\n'.join(['- {}'.format(g.display_name) for g in allowed_groups])
- ))
-
- def action_post(self):
- """Verify the contrains on manual journal entries.
-
- This method is a wrapper around the method post.
-
- It is only called by the button from the form
- view of account.move.
-
- The method post is called directly for automatted entries
- (invoices, payments, expenses, etc).
- """
- self._check_manual_entry_restrictions()
- return super().action_post()
diff --git a/.unported_addons/account_manual_entry_restricted/static/description/account_form.png b/.unported_addons/account_manual_entry_restricted/static/description/account_form.png
deleted file mode 100644
index 7c8514e3..00000000
Binary files a/.unported_addons/account_manual_entry_restricted/static/description/account_form.png and /dev/null differ
diff --git a/.unported_addons/account_manual_entry_restricted/static/description/icon.png b/.unported_addons/account_manual_entry_restricted/static/description/icon.png
deleted file mode 100644
index 92a86b10..00000000
Binary files a/.unported_addons/account_manual_entry_restricted/static/description/icon.png and /dev/null differ
diff --git a/.unported_addons/account_manual_entry_restricted/static/description/journal_entry.png b/.unported_addons/account_manual_entry_restricted/static/description/journal_entry.png
deleted file mode 100644
index 2e9578f9..00000000
Binary files a/.unported_addons/account_manual_entry_restricted/static/description/journal_entry.png and /dev/null differ
diff --git a/.unported_addons/account_manual_entry_restricted/static/description/journal_entry_message.png b/.unported_addons/account_manual_entry_restricted/static/description/journal_entry_message.png
deleted file mode 100644
index 737cb455..00000000
Binary files a/.unported_addons/account_manual_entry_restricted/static/description/journal_entry_message.png and /dev/null differ
diff --git a/.unported_addons/account_manual_entry_restricted/tests/__init__.py b/.unported_addons/account_manual_entry_restricted/tests/__init__.py
deleted file mode 100644
index d2ac44f2..00000000
--- a/.unported_addons/account_manual_entry_restricted/tests/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-# © 2019 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
diff --git a/.unported_addons/account_manual_entry_restricted/tests/test_manual_entry_restriction.py b/.unported_addons/account_manual_entry_restricted/tests/test_manual_entry_restriction.py
deleted file mode 100644
index c10b32ce..00000000
--- a/.unported_addons/account_manual_entry_restricted/tests/test_manual_entry_restriction.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# © 2019 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-import pytest
-from odoo.tests import common
-from odoo.exceptions import ValidationError
-
-
-class TestManualEntryRestriction(common.SavepointCase):
-
- @classmethod
- def setUpClass(cls):
- super().setUpClass()
- cls.group_1 = cls.env['res.groups'].create({'name': 'Group 1'})
- cls.group_2 = cls.env['res.groups'].create({'name': 'Group 2'})
- cls.journal = cls.env['account.journal'].search([], limit=1)
- cls.account_1 = cls.env['account.account'].create({
- 'name': 'Account 1',
- 'code': '111111',
- 'user_type_id': cls.env.ref('account.data_account_type_fixed_assets').id,
- })
- cls.account_2 = cls.env['account.account'].create({
- 'name': 'Account 2',
- 'code': '111112',
- 'user_type_id': cls.env.ref('account.data_account_type_fixed_assets').id,
- })
- cls.move = cls.env['account.move'].create({
- 'journal_id': cls.journal.id,
- 'line_ids': [
- (0, 0, {
- 'account_id': cls.account_1.id,
- 'name': '/',
- 'debit': 100,
- }),
- (0, 0, {
- 'account_id': cls.account_2.id,
- 'name': '/',
- 'credit': 100,
- })
- ]
- })
-
- def test_if_no_restriction__constraint_not_raised(self):
- self.move.action_post()
- assert self.move.state == 'posted'
-
- def test_if_user_not_member_of_group__constraint_raised(self):
- self.account_1.manual_entry_group_ids = self.group_1
- with pytest.raises(ValidationError):
- self.move.action_post()
-
- def test_if_user_member_of_group__constraint_not_raised(self):
- self.env.user.groups_id = self.group_1
- self.account_1.manual_entry_group_ids = self.group_1
- self.move.action_post()
- assert self.move.state == 'posted'
-
- def test_if_multiple_groups__user_must_be_member_of_one_group(self):
- self.env.user.groups_id = self.group_1
- self.account_1.manual_entry_group_ids = self.group_1 | self.group_2
- self.move.action_post()
- assert self.move.state == 'posted'
-
- def test_if_post_called_directly__constraint_not_raised(self):
- """Test that automatic entries are not restricted."""
- self.account_1.manual_entry_group_ids = self.group_1
- self.move.post()
- assert self.move.state == 'posted'
diff --git a/.unported_addons/account_manual_entry_restricted/views/account.xml b/.unported_addons/account_manual_entry_restricted/views/account.xml
deleted file mode 100644
index 6e1980e1..00000000
--- a/.unported_addons/account_manual_entry_restricted/views/account.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
- Account Form: add Entry Restriction
- account.account
-
-
-
-
-
-
-
-
-
diff --git a/.unported_addons/account_payment_from_move_line/README.rst b/.unported_addons/account_payment_from_move_line/README.rst
deleted file mode 100644
index 071b1c1c..00000000
--- a/.unported_addons/account_payment_from_move_line/README.rst
+++ /dev/null
@@ -1,96 +0,0 @@
-Account Payment From Move Line
-==============================
-This modules allows to generate a payment from an existing journal item (account.move.line).
-
-.. contents:: Table of Contents
-
-Context
--------
-In vanilla Odoo, a payment can be registered directly from an invoice.
-
-.. image:: static/description/invoice_payment_wizard.png
-
-This allows to automatically fill the payment values based on the invoice.
-
-However, a journal entry can be created manually to recognize a receivable item.
-
-.. image:: static/description/receivable_item_list.png
-
-In such case, prefilling a payment from the receivable item is not possible (in vanilla Odoo).
-
-Usage
------
-As member of the group ``Accounting / Billing``, I go to the list view of journal items.
-
-I filter to display the receivable items for a given customer.
-
-.. image:: static/description/receivable_item_list.png
-
-I select the items and click on ``Register a payment``.
-
-.. image:: static/description/receivable_item_list_register_payment.png
-
-A wizard is opened.
-
-.. image:: static/description/payment_from_move_line_wizard.png
-
-I notice that:
-
-* The payment is prefilled with the sum of amounts from the selected receivables.
-* The date of payment is ``Today`` (by default).
-* The payment journal is not filled (a default value can be parametrized per company).
-
-Then, I replace the prefilled amount with a partial payment amount and select a journal.
-
-The system asks what to do with the balance; either ``Keep Open`` or ``Mark as Fully Paid``.
-
-.. image:: static/description/wizard_partial_amount.png
-
-I select ``Mark as Fully Paid`` and select a ``Difference Account``.
-
-.. image:: static/description/wizard_difference_account.png
-
-I click on ``Validate``.
-
-.. image:: static/description/wizard_validate_button.png
-
-The form view of the new payment is open.
-
-.. image:: static/description/payment_form.png
-
-I notice that the selected receivable items are now reconciled.
-
-.. image:: static/description/journal_items_reconciled.png
-
-Constraints
------------
-The journal items selected for registering payments must comply with the following constraints.
-If one constraint fails, a detailled error message will be displayed.
-
-Same Currency, Account and Partner
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Selected items must have the same currency, GL account and commercial partner.
-This is required so that the payment can be reconciled with the selected journal items.
-
-Unreconciled
-~~~~~~~~~~~~
-Selected items must not be fully reconciled.
-
-Posted
-~~~~~~
-Selected items must be posted.
-
-Known Issues
-------------
-For now, this module does not support payable journal items and outbound payments.
-It only supports receivables and inbound payments.
-
-The reason is that supporting payables and outbound payments adds extra complexity.
-This complexity is not required by Numigi's clients.
-
-A constraint is implemented to prevent users from selecting non-receivable journal items
-for registering payments.
-
-Contributors
-------------
-* Numigi (tm) and all its contributors (https://bit.ly/numigiens)
diff --git a/.unported_addons/account_payment_from_move_line/__init__.py b/.unported_addons/account_payment_from_move_line/__init__.py
deleted file mode 100644
index 4c6365d4..00000000
--- a/.unported_addons/account_payment_from_move_line/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# © 2019 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-from . import models, wizard
diff --git a/.unported_addons/account_payment_from_move_line/__manifest__.py b/.unported_addons/account_payment_from_move_line/__manifest__.py
deleted file mode 100644
index 35de5d85..00000000
--- a/.unported_addons/account_payment_from_move_line/__manifest__.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# © 2019 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-{
- 'name': 'Account Payment From Move Line',
- 'version': '1.0.0',
- 'author': 'Numigi',
- 'maintainer': 'Numigi',
- 'website': 'https://www.numigi.com',
- 'license': 'LGPL-3',
- 'category': 'Accounting',
- 'summary': 'Generate payment from receivable journal item',
- 'depends': [
- 'account',
- ],
- 'data': [
- 'views/account_move_line.xml',
- 'wizard/account_payment_from_move_line.xml',
- ],
- 'installable': True,
-}
diff --git a/.unported_addons/account_payment_from_move_line/i18n/fr.po b/.unported_addons/account_payment_from_move_line/i18n/fr.po
deleted file mode 100644
index 2478f342..00000000
--- a/.unported_addons/account_payment_from_move_line/i18n/fr.po
+++ /dev/null
@@ -1,271 +0,0 @@
-# Translation of Odoo Server.
-# This file contains the translation of the following modules:
-# * account_payment_from_move_line
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: Odoo Server 12.0+e\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-10-08 18:42+0000\n"
-"PO-Revision-Date: 2019-10-08 14:42-0400\n"
-"Last-Translator: <>\n"
-"Language-Team: \n"
-"Language: fr\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: \n"
-"X-Generator: Poedit 2.0.6\n"
-
-#. module: account_payment_from_move_line
-#: model_terms:ir.ui.view,arch_db:account_payment_from_move_line.account_payment_from_move_line_form
-msgid "Cancel"
-msgstr "Annuler"
-
-#. module: account_payment_from_move_line
-#: model:ir.model.fields,field_description:account_payment_from_move_line.field_account_payment_from_move_line__company_currency_id
-msgid "Company Currency"
-msgstr ""
-
-#. module: account_payment_from_move_line
-#: model:ir.model.fields,field_description:account_payment_from_move_line.field_account_payment_from_move_line__counterpart_account_id
-msgid "Counterpart Account"
-msgstr ""
-
-#. module: account_payment_from_move_line
-#: model:ir.model.fields,field_description:account_payment_from_move_line.field_account_payment_from_move_line__create_uid
-msgid "Created by"
-msgstr ""
-
-#. module: account_payment_from_move_line
-#: model:ir.model.fields,field_description:account_payment_from_move_line.field_account_payment_from_move_line__create_date
-msgid "Created on"
-msgstr ""
-
-#. module: account_payment_from_move_line
-#: model:ir.model.fields,field_description:account_payment_from_move_line.field_account_payment_from_move_line__currency_id
-msgid "Currency"
-msgstr "Devise"
-
-#. module: account_payment_from_move_line
-#: model:ir.model.fields,field_description:account_payment_from_move_line.field_account_payment_from_move_line__writeoff_account_id
-msgid "Difference Account"
-msgstr "Compte de différence"
-
-#. module: account_payment_from_move_line
-#: model:ir.model.fields,field_description:account_payment_from_move_line.field_account_payment_from_move_line__display_name
-msgid "Display Name"
-msgstr ""
-
-#. module: account_payment_from_move_line
-#: model:ir.model.fields,field_description:account_payment_from_move_line.field_account_payment_from_move_line__id
-msgid "ID"
-msgstr ""
-
-#. module: account_payment_from_move_line
-#: model:ir.model,name:account_payment_from_move_line.model_account_move_line
-msgid "Journal Item"
-msgstr ""
-
-#. module: account_payment_from_move_line
-#: selection:account.payment.from.move.line,payment_difference_handling:0
-msgid "Keep open"
-msgstr "Laisser ouvert"
-
-#. module: account_payment_from_move_line
-#: model:ir.model.fields,field_description:account_payment_from_move_line.field_account_payment_from_move_line____last_update
-msgid "Last Modified on"
-msgstr ""
-
-#. module: account_payment_from_move_line
-#: model:ir.model.fields,field_description:account_payment_from_move_line.field_account_payment_from_move_line__write_uid
-msgid "Last Updated by"
-msgstr ""
-
-#. module: account_payment_from_move_line
-#: model:ir.model.fields,field_description:account_payment_from_move_line.field_account_payment_from_move_line__write_date
-msgid "Last Updated on"
-msgstr ""
-
-#. module: account_payment_from_move_line
-#: selection:account.payment.from.move.line,payment_difference_handling:0
-msgid "Mark as fully paid"
-msgstr "Solder la balance"
-
-#. module: account_payment_from_move_line
-#: model:ir.model.fields,field_description:account_payment_from_move_line.field_account_payment_from_move_line__communication
-msgid "Memo"
-msgstr "Mémo"
-
-#. module: account_payment_from_move_line
-#: model:ir.model.fields,field_description:account_payment_from_move_line.field_account_payment_from_move_line__move_line_ids
-msgid "Move Lines"
-msgstr ""
-
-#. module: account_payment_from_move_line
-#: model:ir.model.fields,field_description:account_payment_from_move_line.field_account_payment_from_move_line__move_lines_currency_id
-msgid "Move Lines Currency"
-msgstr ""
-
-#. module: account_payment_from_move_line
-#: code:addons/account_payment_from_move_line/models/account_move_line.py:17
-#, python-format
-msgid ""
-"Only journal items with a receivable account can be selected to register a "
-"payment."
-msgstr ""
-"Seules les écritures ayant un compte recevable peuvent être sélectionnées "
-"pour enregistrer un paiement."
-
-#. module: account_payment_from_move_line
-#: code:addons/account_payment_from_move_line/models/account_move_line.py:25
-#, python-format
-msgid "Only posted journal items can be selected to register a payment."
-msgstr ""
-"Seules les écritures comptabilisées peuvent être sélectionnées pour "
-"enregistrer un paiement."
-
-#. module: account_payment_from_move_line
-#: model:ir.model.fields,field_description:account_payment_from_move_line.field_account_payment_from_move_line__partner_id
-msgid "Partner"
-msgstr "Partenaire"
-
-#. module: account_payment_from_move_line
-#: model:ir.model.fields,field_description:account_payment_from_move_line.field_account_payment_from_move_line__amount
-msgid "Payment Amount"
-msgstr "Montant du paiement"
-
-#. module: account_payment_from_move_line
-#: model:ir.model.fields,field_description:account_payment_from_move_line.field_account_payment_from_move_line__payment_date
-msgid "Payment Date"
-msgstr "Date de paiement"
-
-#. module: account_payment_from_move_line
-#: model:ir.model.fields,field_description:account_payment_from_move_line.field_account_payment_from_move_line__payment_difference
-msgid "Payment Difference"
-msgstr "Différence de paiement"
-
-#. module: account_payment_from_move_line
-#: model:ir.model.fields,field_description:account_payment_from_move_line.field_account_payment_from_move_line__payment_difference_handling
-msgid "Payment Difference Handling"
-msgstr ""
-
-#. module: account_payment_from_move_line
-#: model:ir.model.fields,field_description:account_payment_from_move_line.field_account_payment_from_move_line__writeoff_label
-msgid "Payment Difference Label"
-msgstr ""
-
-#. module: account_payment_from_move_line
-#: model:ir.model.fields,field_description:account_payment_from_move_line.field_account_payment_from_move_line__journal_id
-msgid "Payment Journal"
-msgstr "Journal de paiement"
-
-#. module: account_payment_from_move_line
-#: model:ir.model.fields,field_description:account_payment_from_move_line.field_account_payment_from_move_line__payment_method_id
-msgid "Payment Method"
-msgstr "Méthode de paiement"
-
-#. module: account_payment_from_move_line
-#: model:ir.model,name:account_payment_from_move_line.model_account_payment_from_move_line
-msgid "Payment from Move Line Wizard"
-msgstr "Wizard de paiement depuis ligne d'écriture"
-
-#. module: account_payment_from_move_line
-#: model:ir.model,name:account_payment_from_move_line.model_account_payment
-msgid "Payments"
-msgstr "Paiements"
-
-#. module: account_payment_from_move_line
-#: model_terms:ir.ui.view,arch_db:account_payment_from_move_line.account_payment_from_move_line_form
-msgid "Post Difference In"
-msgstr "Comptabiliser la différence dans"
-
-#. module: account_payment_from_move_line
-#: code:addons/account_payment_from_move_line/models/account_move_line.py:129
-#: model:ir.actions.server,name:account_payment_from_move_line.action_open_payment_wizard
-#: model_terms:ir.ui.view,arch_db:account_payment_from_move_line.account_payment_from_move_line_form
-#, python-format
-msgid "Register Payment"
-msgstr "Enregistrer un paiement"
-
-#. module: account_payment_from_move_line
-#: model:ir.model.fields,field_description:account_payment_from_move_line.field_account_payment_from_move_line__move_lines_residual_amount
-msgid "Residual Amount"
-msgstr "Montant résiduel"
-
-#. module: account_payment_from_move_line
-#: code:addons/account_payment_from_move_line/models/account_move_line.py:10
-#, python-format
-msgid "The journal item has no partner."
-msgstr "L'écriture n'a aucun partenaire."
-
-#. module: account_payment_from_move_line
-#: code:addons/account_payment_from_move_line/models/account_move_line.py:33
-#, python-format
-msgid "The journal item is already reconciled."
-msgstr "L'écriture est déjà réconciliée."
-
-#. module: account_payment_from_move_line
-#: code:addons/account_payment_from_move_line/models/account_move_line.py:45
-#, python-format
-msgid ""
-"The journal item {item} can not be selected to register a payment.\n"
-"{error}"
-msgstr ""
-"L'écriture {item} ne peut pas être sélectionnée pour enregistrer un "
-"paiement.\n"
-"{error}"
-
-#. module: account_payment_from_move_line
-#: model:ir.model.fields,help:account_payment_from_move_line.field_account_payment_from_move_line__writeoff_label
-msgid "The label of the counterpart that will hold the payment difference."
-msgstr ""
-
-#. module: account_payment_from_move_line
-#: code:addons/account_payment_from_move_line/models/account_move_line.py:54
-#, python-format
-msgid ""
-"The selected journal items are bound to multiple commercial partners:\n"
-"\t * {partners}\n"
-"A payment can only be registered for a single commercial partner."
-msgstr ""
-"Les écritures sélectionnées sont liées à plusieurs partenaires "
-"commerciaux:\n"
-"\t * {partners}\n"
-"Un paiement ne peut être enregistrer que pour un seul partenaire commercial."
-
-#. module: account_payment_from_move_line
-#: code:addons/account_payment_from_move_line/models/account_move_line.py:66
-#, python-format
-msgid ""
-"The selected journal items are bound to multiple journal accounts:\n"
-"\t * {accounts}\n"
-"A payment can only be registered for a single account."
-msgstr ""
-"Les écritures sélectionnées sont liées à plusieurs comptes de grand livre:\n"
-"\t * {accounts}\n"
-"Un paiement ne peut être enregistrer que pour un seul compte."
-
-#. module: account_payment_from_move_line
-#: code:addons/account_payment_from_move_line/models/account_move_line.py:83
-#, python-format
-msgid ""
-"The selected journal items are in multiple currencies:\n"
-"\t * {currencies}\n"
-"A payment can only be registered for a single account."
-msgstr ""
-"Les écritures sélectionnées sont en différentes devises:\n"
-"\t * {accounts}\n"
-"Un paiement ne peut être enregistrer que pour une seule devise."
-
-#. module: account_payment_from_move_line
-#: model_terms:ir.ui.view,arch_db:account_payment_from_move_line.account_payment_from_move_line_form
-msgid "Validate"
-msgstr "Valider"
-
-#. module: account_payment_from_move_line
-#: code:addons/account_payment_from_move_line/models/account_move_line.py:94
-#, python-format
-msgid "You must select at least one journal item to generate payments."
-msgstr ""
-"Vous devez sélectionner au moins une écriture pour générer un paiement."
diff --git a/.unported_addons/account_payment_from_move_line/models/__init__.py b/.unported_addons/account_payment_from_move_line/models/__init__.py
deleted file mode 100644
index 91ee3d59..00000000
--- a/.unported_addons/account_payment_from_move_line/models/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# © 2019 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-from . import (
- account_move_line,
- account_payment,
-)
diff --git a/.unported_addons/account_payment_from_move_line/models/account_move_line.py b/.unported_addons/account_payment_from_move_line/models/account_move_line.py
deleted file mode 100644
index 961af51d..00000000
--- a/.unported_addons/account_payment_from_move_line/models/account_move_line.py
+++ /dev/null
@@ -1,130 +0,0 @@
-# © 2019 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-from odoo import models, _
-from odoo.exceptions import UserError
-
-
-def _check_has_partner(line: 'account.move.line', context: dict):
- if not line.partner_id:
- raise UserError(_(
- 'The journal item has no partner.'
- ))
-
-
-def _check_has_receivable_account(line: 'account.move.line', context: dict):
- if line.account_id.internal_type != 'receivable':
- raise UserError(_(
- 'Only journal items with a receivable account '
- 'can be selected to register a payment.'
- ))
-
-
-def _check_is_posted(line: 'account.move.line', context: dict):
- if line.move_id.state != 'posted':
- raise UserError(_(
- 'Only posted journal items '
- 'can be selected to register a payment.'
- ))
-
-
-def _check_is_not_reconciled(line: 'account.move.line', context: dict):
- if line.full_reconcile_id:
- raise UserError(_(
- 'The journal item is already reconciled.'
- ))
-
-
-def _check_single_line_is_selectable(line: 'account.move.line', context: dict):
- try:
- _check_has_receivable_account(line, context)
- _check_is_posted(line, context)
- _check_is_not_reconciled(line, context)
- _check_has_partner(line, context)
- except UserError as err:
- raise UserError(_(
- 'The journal item {item} can not be selected to register a payment.\n'
- '{error}'
- ).format(item=line.display_name, error=err.name))
-
-
-def _check_lines_have_common_commercial_partner(lines: 'account.move.line', context: dict):
- partners = lines.mapped('partner_id.commercial_partner_id')
- if len(partners) > 1:
- raise UserError(_(
- 'The selected journal items are bound to multiple commercial partners:'
- '\n'
- '\t * {partners}'
- '\n'
- 'A payment can only be registered for a single commercial partner.'
- ).format(partners='\n\t * '.join(partners.mapped('display_name'))))
-
-
-def _check_lines_have_common_account(lines: 'account.move.line', context: dict):
- accounts = lines.mapped('account_id')
- if len(accounts) > 1:
- raise UserError(_(
- 'The selected journal items are bound to multiple journal accounts:'
- '\n'
- '\t * {accounts}'
- '\n'
- 'A payment can only be registered for a single account.'
- ).format(accounts='\n\t * '.join(accounts.mapped('display_name'))))
-
-
-def _check_lines_have_common_currency(lines: 'account.move.line', context: dict):
- currencies = lines.mapped('currency_id')
-
- lines_without_currency = lines.filtered(lambda l: not l.currency_id)
- if lines_without_currency:
- currencies |= lines_without_currency.mapped('company_id.currency_id')
-
- if len(currencies) > 1:
- raise UserError(_(
- 'The selected journal items are in multiple currencies:'
- '\n'
- '\t * {currencies}'
- '\n'
- 'A payment can only be registered for a single account.'
- ).format(currencies='\n\t * '.join(currencies.mapped('display_name'))))
-
-
-def _check_at_least_one_line_selected(lines: 'account.move.line', context: dict):
- if not lines:
- raise UserError(_(
- 'You must select at least one journal item to generate payments.'
- ))
-
-
-def _check_lines_are_selectable(lines: 'account.move.line', context: dict):
- user_errors = []
- for line in lines:
- try:
- _check_single_line_is_selectable(line, context)
- except UserError as err:
- user_errors.append(err)
-
- if user_errors:
- raise UserError('\n\n'.join([e.name for e in user_errors]))
-
-
-class AccountMoveLine(models.Model):
-
- _inherit = 'account.move.line'
-
- def open_payment_from_move_line_wizard(self):
- _check_at_least_one_line_selected(self, self._context)
- _check_lines_have_common_commercial_partner(self, self._context)
- _check_lines_have_common_account(self, self._context)
- _check_lines_have_common_currency(self, self._context)
- _check_lines_are_selectable(self, self._context)
-
- wizard = self.env['account.payment.from.move.line'].create({})
- wizard.move_line_ids = self
- wizard.compute_amount_and_currency()
- wizard.compute_communication()
-
- action = wizard.get_formview_action()
- action['target'] = 'new'
- action['name'] = _('Register Payment')
- return action
diff --git a/.unported_addons/account_payment_from_move_line/models/account_payment.py b/.unported_addons/account_payment_from_move_line/models/account_payment.py
deleted file mode 100644
index a2289272..00000000
--- a/.unported_addons/account_payment_from_move_line/models/account_payment.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# © 2019 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-from odoo import api, models
-
-
-class AccountPayment(models.Model):
-
- _inherit = 'account.payment'
-
- @api.one
- @api.depends('invoice_ids', 'payment_type', 'partner_type', 'partner_id')
- def _compute_destination_account_id(self):
- """Allow to make the destination (counterpart) account explicit.
-
- In vanilla implementations of payments, the counterpart account is
- deduced from either the invoices to pay or the partner selected on the payment.
-
- In the case of this module, when opening the wizard, we already know
- against which counterpart account the payment must registered.
- This is the account of the selected journal items (account.move.line).
-
- Therefore, when posting the payment from the new wizard, the counterpart account
- is forced to the expected value.
- """
- forced_account_id = self._context.get('force_payment_destination_account_id')
- if forced_account_id:
- self.destination_account_id = self.env['account.account'].browse(forced_account_id)
- else:
- super()._compute_destination_account_id()
diff --git a/.unported_addons/account_payment_from_move_line/static/description/icon.png b/.unported_addons/account_payment_from_move_line/static/description/icon.png
deleted file mode 100644
index 92a86b10..00000000
Binary files a/.unported_addons/account_payment_from_move_line/static/description/icon.png and /dev/null differ
diff --git a/.unported_addons/account_payment_from_move_line/static/description/invoice_payment_wizard.png b/.unported_addons/account_payment_from_move_line/static/description/invoice_payment_wizard.png
deleted file mode 100644
index a46182ae..00000000
Binary files a/.unported_addons/account_payment_from_move_line/static/description/invoice_payment_wizard.png and /dev/null differ
diff --git a/.unported_addons/account_payment_from_move_line/static/description/journal_items_reconciled.png b/.unported_addons/account_payment_from_move_line/static/description/journal_items_reconciled.png
deleted file mode 100644
index 99171b09..00000000
Binary files a/.unported_addons/account_payment_from_move_line/static/description/journal_items_reconciled.png and /dev/null differ
diff --git a/.unported_addons/account_payment_from_move_line/static/description/payment_form.png b/.unported_addons/account_payment_from_move_line/static/description/payment_form.png
deleted file mode 100644
index 54b40eb5..00000000
Binary files a/.unported_addons/account_payment_from_move_line/static/description/payment_form.png and /dev/null differ
diff --git a/.unported_addons/account_payment_from_move_line/static/description/payment_from_move_line_wizard.png b/.unported_addons/account_payment_from_move_line/static/description/payment_from_move_line_wizard.png
deleted file mode 100644
index 17bff3ed..00000000
Binary files a/.unported_addons/account_payment_from_move_line/static/description/payment_from_move_line_wizard.png and /dev/null differ
diff --git a/.unported_addons/account_payment_from_move_line/static/description/receivable_item_list.png b/.unported_addons/account_payment_from_move_line/static/description/receivable_item_list.png
deleted file mode 100644
index b191c0a0..00000000
Binary files a/.unported_addons/account_payment_from_move_line/static/description/receivable_item_list.png and /dev/null differ
diff --git a/.unported_addons/account_payment_from_move_line/static/description/receivable_item_list_register_payment.png b/.unported_addons/account_payment_from_move_line/static/description/receivable_item_list_register_payment.png
deleted file mode 100644
index d70ef02f..00000000
Binary files a/.unported_addons/account_payment_from_move_line/static/description/receivable_item_list_register_payment.png and /dev/null differ
diff --git a/.unported_addons/account_payment_from_move_line/static/description/wizard_difference_account.png b/.unported_addons/account_payment_from_move_line/static/description/wizard_difference_account.png
deleted file mode 100644
index d6e8e7ba..00000000
Binary files a/.unported_addons/account_payment_from_move_line/static/description/wizard_difference_account.png and /dev/null differ
diff --git a/.unported_addons/account_payment_from_move_line/static/description/wizard_partial_amount.png b/.unported_addons/account_payment_from_move_line/static/description/wizard_partial_amount.png
deleted file mode 100644
index 615916a0..00000000
Binary files a/.unported_addons/account_payment_from_move_line/static/description/wizard_partial_amount.png and /dev/null differ
diff --git a/.unported_addons/account_payment_from_move_line/static/description/wizard_validate_button.png b/.unported_addons/account_payment_from_move_line/static/description/wizard_validate_button.png
deleted file mode 100644
index 8330aa85..00000000
Binary files a/.unported_addons/account_payment_from_move_line/static/description/wizard_validate_button.png and /dev/null differ
diff --git a/.unported_addons/account_payment_from_move_line/tests/__init__.py b/.unported_addons/account_payment_from_move_line/tests/__init__.py
deleted file mode 100644
index 6ef2df91..00000000
--- a/.unported_addons/account_payment_from_move_line/tests/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-# © 2019 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
diff --git a/.unported_addons/account_payment_from_move_line/tests/test_payment_wizard.py b/.unported_addons/account_payment_from_move_line/tests/test_payment_wizard.py
deleted file mode 100644
index 1d5cc520..00000000
--- a/.unported_addons/account_payment_from_move_line/tests/test_payment_wizard.py
+++ /dev/null
@@ -1,334 +0,0 @@
-# © 2019 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-import pytest
-from ddt import ddt, data
-from odoo.exceptions import UserError
-from odoo.tests.common import SavepointCase
-
-
-class PaymentWizardCase(SavepointCase):
-
- @classmethod
- def setUpClass(cls):
- super().setUpClass()
- cls.user = cls.env['res.users'].create({
- 'name': 'My Employee',
- 'login': 'employee@example.com',
- 'email': 'employee@example.com',
- 'groups_id': [
- (5, 0),
- (4, cls.env.ref('base.group_user').id),
- ],
- })
-
- cls.payment_journal = cls.env['account.journal'].create({
- 'name': 'My Bank Account',
- 'code': 'BNK1',
- 'type': 'bank',
- })
-
- cls.customer_a = cls.env['res.partner'].create({
- 'name': 'Customer A',
- 'customer': True,
- 'is_company': True,
- })
-
- cls.contact_a1 = cls.env['res.partner'].create({
- 'name': 'Contact A1',
- 'customer': True,
- 'parent_id': cls.customer_a.id,
- 'type': 'contact',
- })
-
- cls.contact_a2 = cls.env['res.partner'].create({
- 'name': 'Contact A2',
- 'customer': True,
- 'parent_id': cls.customer_a.id,
- 'type': 'contact',
- })
-
- cls.customer_b = cls.env['res.partner'].create({
- 'name': 'Customer B',
- 'customer': True,
- 'is_company': True,
- })
-
- cls.payment_method = cls.env.ref('account.account_payment_method_manual_in')
- cls.sale_journal = cls.env['account.journal'].search([('type', '=', 'sale')], limit=1)
- cls.receivable_account = cls.env['account.account'].create({
- 'name': 'Receivable',
- 'code': '111211',
- 'user_type_id': cls.env.ref('account.data_account_type_receivable').id,
- 'reconcile': True,
- })
- cls.revenue_account = cls.env['account.account'].create({
- 'name': 'Revenue',
- 'code': '444144',
- 'user_type_id': cls.env.ref('account.data_account_type_revenue').id,
- })
- cls.writeoff_account = cls.env['account.account'].create({
- 'name': 'Write-Off',
- 'code': '511555',
- 'user_type_id': cls.env.ref('account.data_account_type_expenses').id,
- })
- cls.payable_account = cls.env['account.account'].create({
- 'name': 'Payable',
- 'code': '222222',
- 'user_type_id': cls.env.ref('account.data_account_type_payable').id,
- 'reconcile': True,
- })
-
- @classmethod
- def _generate_receivable(
- cls, amount, amount_currency=None, currency=None, account=None,
- partner=None, no_partner=False
- ):
- receivable_account = account or cls.receivable_account
- partner = partner or cls.customer_a
- move = cls.env['account.move'].create({
- 'journal_id': cls.sale_journal.id,
- 'line_ids': [
- (0, 0, {
- 'partner_id': None if no_partner else partner.id,
- 'account_id': receivable_account.id,
- 'name': '/',
- 'debit': amount if amount > 0 else 0,
- 'credit': -amount if amount < 0 else 0,
- 'amount_currency': amount_currency,
- 'currency_id': currency.id if currency else None,
- }),
- (0, 0, {
- 'account_id': cls.revenue_account.id,
- 'name': '/',
- 'debit': -amount if amount < 0 else 0,
- 'credit': amount if amount > 0 else 0,
- })
- ]
- })
- move.post()
- return move.line_ids.filtered(lambda l: l.account_id == receivable_account)
-
- def _open_wizard(self, move_lines):
- action = move_lines.open_payment_from_move_line_wizard()
- return self.env['account.payment.from.move.line'].browse(action['res_id'])
-
- def _validate_wizard(self, wizard):
- wizard.journal_id = self.payment_journal
- wizard.payment_method_id = self.payment_method
- action = wizard.validate()
- return self.env['account.payment'].browse(action['res_id'])
-
- @staticmethod
- def _is_reconciled(move_line):
- return bool(move_line.full_reconcile_id)
-
-
-@ddt
-class TestPaymentWizard(PaymentWizardCase):
-
- def test_if_payment_amount_is_sum_of_debits(self):
- move_1 = self._generate_receivable(100)
- move_2 = self._generate_receivable(200)
- wizard = self._open_wizard(move_1 | move_2)
- assert wizard.amount == 300
-
- def test_if_credit_in_receivable_move_lines__credit_amount_deduced(self):
- move_1 = self._generate_receivable(100)
- move_2 = self._generate_receivable(-25)
- wizard = self._open_wizard(move_1 | move_2)
- assert wizard.amount == 75
-
- @data('base.CAD', 'base.EUR')
- def test_if_receivable_in_foreign_currency__payment_in_foreign_currency(self, currency_ref):
- currency = self.env.ref(currency_ref)
- move_1 = self._generate_receivable(100, amount_currency=150, currency=currency)
- move_2 = self._generate_receivable(200, amount_currency=250, currency=currency)
- wizard = self._open_wizard(move_1 | move_2)
- assert wizard.amount == 400
- assert wizard.currency_id == currency
-
- @data('base.CAD', 'base.EUR')
- def test_if_credit_receivable_in_foreign_currency__credit_amount_deduced(self, currency_ref):
- currency = self.env.ref(currency_ref)
- move_1 = self._generate_receivable(100, amount_currency=150, currency=currency)
- move_2 = self._generate_receivable(-20, amount_currency=-25, currency=currency)
- wizard = self._open_wizard(move_1 | move_2)
- assert wizard.amount == 125
- assert wizard.currency_id == currency
-
- def test_payment_difference_with_debits_in_company_currency(self):
- move_1 = self._generate_receivable(100)
- move_2 = self._generate_receivable(200)
- wizard = self._open_wizard(move_1 | move_2)
- wizard.amount = 175
- assert wizard.payment_difference == 125
-
- @data('base.CAD', 'base.EUR')
- def test_payment_difference_in_foreign_currency(self, currency_ref):
- currency = self.env.ref(currency_ref)
- move_1 = self._generate_receivable(100, amount_currency=150, currency=currency)
- move_2 = self._generate_receivable(200, amount_currency=250, currency=currency)
- wizard = self._open_wizard(move_1 | move_2)
- wizard.amount = 175
- assert wizard.payment_difference == 225
-
- def test_after_validate__payment_is_reconciled(self):
- receivable = self._generate_receivable(100)
- wizard = self._open_wizard(receivable)
- self._validate_wizard(wizard)
- assert self._is_reconciled(receivable)
-
- def test_after_validate__if_open_difference__payment_is_not_reconciled(self):
- receivable = self._generate_receivable(100)
- wizard = self._open_wizard(receivable)
- wizard.amount = 75
- wizard.payment_difference_handling = 'open'
- self._validate_wizard(wizard)
- assert not self._is_reconciled(receivable)
-
- def test_after_validate__if_reconcile_difference__payment_is_not_reconciled(self):
- receivable = self._generate_receivable(100)
- wizard = self._open_wizard(receivable)
- wizard.amount = 75
- wizard.payment_difference_handling = 'reconcile'
- wizard.writeoff_account_id = self.writeoff_account
- self._validate_wizard(wizard)
- assert self._is_reconciled(receivable)
-
-
-class TestSelectableMoveLineConstraints(PaymentWizardCase):
-
- @classmethod
- def setUpClass(cls):
- super().setUpClass()
- cls.receivable_1 = cls._generate_receivable(100)
- cls.receivable_2 = cls._generate_receivable(200)
-
- def test_if_no_line_selected__raise_error(self):
- with pytest.raises(UserError):
- self._open_wizard(self.env['account.move.line'])
-
- def test_if_not_posted__raise_error(self):
- self.sale_journal.update_posted = True
- self.receivable_1.move_id.button_cancel()
-
- with pytest.raises(UserError):
- self._open_wizard(self.receivable_1)
-
- def test_if_not_receivable_account__raise_error(self):
- payable = self._generate_receivable(100, account=self.payable_account)
-
- with pytest.raises(UserError):
- self._open_wizard(payable)
-
- def test_if_no_partner__raise_error(self):
- receivable_1 = self._generate_receivable(100, no_partner=True)
-
- with pytest.raises(UserError):
- self._open_wizard(receivable_1)
-
- def test_if_reconciled__raise_error(self):
- wizard = self._open_wizard(self.receivable_1)
- self._validate_wizard(wizard)
- assert self._is_reconciled(self.receivable_1)
-
- with pytest.raises(UserError):
- self._open_wizard(self.receivable_1 | self.receivable_2)
-
- def test_if_different_partners__raise_error(self):
- receivable_1 = self._generate_receivable(100, partner=self.customer_a)
- receivable_2 = self._generate_receivable(200, partner=self.customer_b)
-
- with pytest.raises(UserError):
- self._open_wizard(receivable_1 | receivable_2)
-
- def test_if_same_commercial_partner__payment_can_be_generated(self):
- receivable_1 = self._generate_receivable(100, partner=self.customer_a)
- receivable_2 = self._generate_receivable(200, partner=self.contact_a1)
- receivable_3 = self._generate_receivable(300, partner=self.contact_a2)
-
- receivables = receivable_1 | receivable_2 | receivable_3
-
- wizard = self._open_wizard(receivables)
- self._validate_wizard(wizard)
-
- for item in receivables:
- assert self._is_reconciled(item)
-
- def test_if_different_accounts__raise_error(self):
- account_2 = self.receivable_account.copy({'code': '111212'})
- receivable_1 = self._generate_receivable(100, account=self.receivable_account)
- receivable_2 = self._generate_receivable(200, account=account_2)
-
- with pytest.raises(UserError):
- self._open_wizard(receivable_1 | receivable_2)
-
- def test_if_different_currencies_accounts__raise_error(self):
- receivable_1 = self._generate_receivable(100)
- receivable_2 = self._generate_receivable(200, currency=self.env.ref('base.CAD'))
-
- with pytest.raises(UserError):
- self._open_wizard(receivable_1 | receivable_2)
-
- def test_multiple_lines_with_validation_errors(self):
- payable_1 = self._generate_receivable(100, account=self.payable_account)
- payable_2 = self._generate_receivable(200, account=self.payable_account)
-
- with pytest.raises(UserError):
- self._open_wizard(payable_1 | payable_2)
-
-
-class TestPaymentInDifferentCurrency(PaymentWizardCase):
-
- @classmethod
- def setUpClass(cls):
- super().setUpClass()
- cls.cad = cls.env.ref('base.CAD')
- cls.eur = cls.env.ref('base.EUR')
-
- cls.env['res.currency.rate'].search([]).unlink()
- cls._add_currency_rate(cls.cad, 2)
- cls._add_currency_rate(cls.eur, 3)
-
- cls.revenue_account.currency_id = cls.cad
- cls.payment_journal.currency_id = cls.eur
-
- @classmethod
- def _add_currency_rate(cls, currency, rate):
- cls.env['res.currency.rate'].create({
- 'currency_id': currency.id,
- 'rate': rate,
- })
-
- def test_payment_difference_with_payment_in_different_currency(self):
- move_1 = self._generate_receivable(100, amount_currency=200, currency=self.cad)
- move_2 = self._generate_receivable(200, amount_currency=600, currency=self.cad)
-
- wizard = self._open_wizard(move_1 | move_2)
- wizard.amount = 100
- wizard.currency_id = self.eur
- assert wizard.payment_difference == 1100 # (200 + 600) * 3 / 2 - 100
-
- def test_reconcile_difference_with_payment_in_different_currency(self):
- receivable = self._generate_receivable(300, amount_currency=600, currency=self.cad)
-
- wizard = self._open_wizard(receivable)
- wizard.amount = 100
- wizard.currency_id = self.eur
- wizard.payment_difference_handling = 'reconcile'
- wizard.writeoff_account_id = self.writeoff_account
-
- self._validate_wizard(wizard)
- assert self._is_reconciled(receivable)
-
- def test_open_difference_with_payment_in_different_currency(self):
- receivable = self._generate_receivable(300, amount_currency=600, currency=self.cad)
-
- wizard = self._open_wizard(receivable)
- wizard.amount = 150
- wizard.currency_id = self.eur
-
- self._validate_wizard(wizard)
- assert receivable.amount_residual == 250 # 300 - (150 / 3)
- assert receivable.amount_residual_currency == 500 # 600 - (150 * 2 / 3)
diff --git a/.unported_addons/account_payment_from_move_line/views/account_move_line.xml b/.unported_addons/account_payment_from_move_line/views/account_move_line.xml
deleted file mode 100644
index fc337ac4..00000000
--- a/.unported_addons/account_payment_from_move_line/views/account_move_line.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
- Register Payment
-
-
- ir.actions.server
- code
-
-action = records.open_payment_from_move_line_wizard()
-
-
-
-
diff --git a/.unported_addons/account_payment_from_move_line/wizard/__init__.py b/.unported_addons/account_payment_from_move_line/wizard/__init__.py
deleted file mode 100644
index 358b1b43..00000000
--- a/.unported_addons/account_payment_from_move_line/wizard/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# © 2019 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-from . import account_payment_from_move_line
diff --git a/.unported_addons/account_payment_from_move_line/wizard/account_payment_from_move_line.py b/.unported_addons/account_payment_from_move_line/wizard/account_payment_from_move_line.py
deleted file mode 100644
index b836e94c..00000000
--- a/.unported_addons/account_payment_from_move_line/wizard/account_payment_from_move_line.py
+++ /dev/null
@@ -1,182 +0,0 @@
-# © 2019 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-from odoo import api, fields, models
-
-
-class PaymentFromMoveLineWizard(models.TransientModel):
-
- _name = 'account.payment.from.move.line'
- _description = "Payment from Move Line Wizard"
-
- move_line_ids = fields.Many2many(
- 'account.move.line',
- 'account_payment_from_move_line_rel',
- 'wizard_id',
- 'move_line_id',
- string='Move Lines',
- )
-
- partner_id = fields.Many2one(
- 'res.partner',
- 'Partner',
- compute='_compute_partner',
- )
-
- @api.depends('move_line_ids')
- def _compute_partner(self):
- for wizard in self:
- wizard.partner_id = wizard.move_line_ids.mapped(
- 'partner_id.commercial_partner_id',
- )
-
- counterpart_account_id = fields.Many2one(
- 'account.account',
- 'Counterpart Account',
- compute='_compute_receivable_account',
- )
-
- @api.depends('move_line_ids')
- def _compute_receivable_account(self):
- for wizard in self:
- wizard.counterpart_account_id = wizard.move_line_ids.mapped('account_id')
-
- company_currency_id = fields.Many2one(
- 'res.currency',
- compute='_compute_currencies',
- )
-
- move_lines_currency_id = fields.Many2one(
- 'res.currency',
- compute='_compute_currencies',
- )
-
- @api.depends('move_line_ids')
- def _compute_currencies(self):
- for wizard in self:
- wizard.company_currency_id = wizard.move_line_ids.mapped('company_id.currency_id')
- wizard.move_lines_currency_id = (
- wizard.move_line_ids.mapped('currency_id') or
- wizard.company_currency_id
- )
-
- amount = fields.Monetary('Payment Amount')
-
- move_lines_residual_amount = fields.Monetary(
- 'Residual Amount',
- currency_field='move_lines_currency_id',
- compute='_compute_move_lines_residual_amount'
- )
-
- @api.depends('move_lines_currency_id', 'company_currency_id', 'move_line_ids')
- def _compute_move_lines_residual_amount(self):
- for wizard in self:
- if wizard.move_lines_currency_id == wizard.company_currency_id:
- wizard.move_lines_residual_amount = sum(
- l.amount_residual for l in wizard.move_line_ids
- )
- else:
- wizard.move_lines_residual_amount = sum(
- l.amount_residual_currency for l in wizard.move_line_ids
- )
-
- currency_id = fields.Many2one('res.currency', 'Currency')
- journal_id = fields.Many2one(
- 'account.journal', string='Payment Journal',
- domain=[('type', 'in', ('bank', 'cash'))],
- )
- payment_method_id = fields.Many2one('account.payment.method', 'Payment Method')
- communication = fields.Char('Memo')
- payment_date = fields.Date(string='Payment Date', default=fields.Date.context_today)
-
- payment_difference = fields.Monetary(compute='_compute_payment_difference')
- payment_difference_handling = fields.Selection([
- ('open', 'Keep open'),
- ('reconcile', 'Mark as fully paid'),
- ], default='open')
- writeoff_account_id = fields.Many2one(
- 'account.account', string="Difference Account",
- domain=[('deprecated', '=', False)]
- )
- writeoff_label = fields.Char(
- string='Payment Difference Label',
- help='The label of the counterpart that will hold the payment difference.',
- default='Write-Off'
- )
-
- def _get_available_payment_methods(self):
- return self.journal_id.inbound_payment_method_ids
-
- @api.onchange('journal_id')
- def _onchange_journal_set_available_payment_methods(self):
- available_methods = self._get_available_payment_methods()
- self.payment_method_id = available_methods and available_methods[0] or False
- return {
- 'domain': {'payment_method_id': [('id', 'in', available_methods.ids)]}
- }
-
- @api.depends('move_line_ids', 'amount', 'payment_date', 'currency_id')
- def _compute_payment_difference(self):
- wizards_with_move_lines = self.filtered(lambda w: w.move_line_ids)
-
- for wizard in wizards_with_move_lines:
- residual_amount = wizard.move_lines_residual_amount
- residual_amount_currency = wizard.move_lines_currency_id
- payment_currency = wizard.currency_id
- company = wizard.move_line_ids.mapped('company_id')
- residual_amount_in_payment_currency = residual_amount_currency._convert(
- residual_amount, payment_currency, company,
- wizard.payment_date or fields.Date.today()
- )
- wizard.payment_difference = residual_amount_in_payment_currency - wizard.amount
-
- def compute_amount_and_currency(self):
- """Compute the amount and currency for the wizard.
-
- The computation of these fields must be triggered manually,
- so that the user may override these values.
- """
- self.amount = self.move_lines_residual_amount
- self.currency_id = self.move_lines_currency_id
-
- def compute_communication(self):
- lines_with_reference = self.move_line_ids.filtered(lambda l: l.ref)
- self.communication = ' '.join(sorted(lines_with_reference.mapped('ref')))
-
- def _get_payment_vals(self):
- return {
- 'amount': self.amount,
- 'currency_id': self.currency_id.id,
- 'journal_id': self.journal_id.id,
- 'partner_id': self.partner_id.id,
- 'partner_type': 'customer',
- 'payment_method_id': self.payment_method_id.id,
- 'payment_type': 'inbound',
- 'communication': self.communication,
- 'payment_date': self.payment_date,
- }
-
- def _get_payment_post_context(self):
- return {
- 'force_payment_destination_account_id': self.counterpart_account_id.id,
- }
-
- def _reconcile_payment(self, payment):
- payment_move_line = payment.move_line_ids.filtered(
- lambda l: l.account_id == self.counterpart_account_id
- )
- lines_to_reconcile = (self.move_line_ids | payment_move_line)
-
- if self.payment_difference and self.payment_difference_handling == 'reconcile':
- lines_to_reconcile.reconcile(
- writeoff_acc_id=self.writeoff_account_id,
- writeoff_journal_id=self.journal_id,
- )
- else:
- lines_to_reconcile.reconcile()
-
- def validate(self):
- payment = self.env['account.payment'].create(self._get_payment_vals())
- payment.with_context(**self._get_payment_post_context()).post()
- self._reconcile_payment(payment)
- return payment.get_formview_action()
diff --git a/.unported_addons/account_payment_from_move_line/wizard/account_payment_from_move_line.xml b/.unported_addons/account_payment_from_move_line/wizard/account_payment_from_move_line.xml
deleted file mode 100644
index 2cab76f6..00000000
--- a/.unported_addons/account_payment_from_move_line/wizard/account_payment_from_move_line.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-
-
-
-
- Payment From Move Line Wizard
- account.payment.from.move.line
-
-
-
-
-
-
diff --git a/.unported_addons/account_report_line_menu/README.rst b/.unported_addons/account_report_line_menu/README.rst
deleted file mode 100644
index ded231a0..00000000
--- a/.unported_addons/account_report_line_menu/README.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-Account Report Line Menu
-========================
-This module adds a menu entry to configure the report lines of HTML accounting reports (Balance Sheet, Income Statement, etc).
-
-.. image:: static/description/menu.png
-
-.. image:: static/description/report_line_list.png
-
-Contributors
-------------
-* Numigi (tm) and all its contributors (https://bit.ly/numigiens)
diff --git a/.unported_addons/account_report_line_menu/__init__.py b/.unported_addons/account_report_line_menu/__init__.py
deleted file mode 100644
index d2ac44f2..00000000
--- a/.unported_addons/account_report_line_menu/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-# © 2019 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
diff --git a/.unported_addons/account_report_line_menu/__manifest__.py b/.unported_addons/account_report_line_menu/__manifest__.py
deleted file mode 100644
index 88e7ee1f..00000000
--- a/.unported_addons/account_report_line_menu/__manifest__.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# © 2019 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-{
- 'name': 'Account Report Line Menu',
- 'version': '1.0.0',
- 'author': 'Numigi',
- 'maintainer': 'Numigi',
- 'website': 'https://www.numigi.com',
- 'license': 'LGPL-3',
- 'category': 'Accounting',
- 'summary': 'Add menu entry to configure accounting report lines',
- 'depends': [
- 'account_reports',
- ],
- 'data': [
- 'menu.xml',
- ],
- 'installable': True,
-}
diff --git a/.unported_addons/account_report_line_menu/i18n/fr.po b/.unported_addons/account_report_line_menu/i18n/fr.po
deleted file mode 100644
index 75cd1eb7..00000000
--- a/.unported_addons/account_report_line_menu/i18n/fr.po
+++ /dev/null
@@ -1,22 +0,0 @@
-# Translation of Odoo Server.
-# This file contains the translation of the following modules:
-# * account_report_line_menu
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: Odoo Server 12.0+e\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-05-13 19:15+0000\n"
-"PO-Revision-Date: 2019-05-13 19:15+0000\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_report_line_menu
-#: model:ir.actions.act_window,name:account_report_line_menu.report_line_action
-#: model:ir.ui.menu,name:account_report_line_menu.report_line_menu
-msgid "Financial Report Lines"
-msgstr "Lignes de rapports financiers"
diff --git a/.unported_addons/account_report_line_menu/menu.xml b/.unported_addons/account_report_line_menu/menu.xml
deleted file mode 100644
index 0e9488b6..00000000
--- a/.unported_addons/account_report_line_menu/menu.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/.unported_addons/account_report_line_menu/static/description/icon.png b/.unported_addons/account_report_line_menu/static/description/icon.png
deleted file mode 100644
index 92a86b10..00000000
Binary files a/.unported_addons/account_report_line_menu/static/description/icon.png and /dev/null differ
diff --git a/.unported_addons/account_report_line_menu/static/description/menu.png b/.unported_addons/account_report_line_menu/static/description/menu.png
deleted file mode 100644
index 2da56e1e..00000000
Binary files a/.unported_addons/account_report_line_menu/static/description/menu.png and /dev/null differ
diff --git a/.unported_addons/account_report_line_menu/static/description/report_line_list.png b/.unported_addons/account_report_line_menu/static/description/report_line_list.png
deleted file mode 100644
index 9c4e1f45..00000000
Binary files a/.unported_addons/account_report_line_menu/static/description/report_line_list.png and /dev/null differ
diff --git a/.unported_addons/analytic_source/README.rst b/.unported_addons/analytic_source/README.rst
deleted file mode 100644
index 2af85fa6..00000000
--- a/.unported_addons/analytic_source/README.rst
+++ /dev/null
@@ -1,14 +0,0 @@
-===============
-Analytic Source
-===============
-
-Add a field source on account.analytic.line.
-
-When an invoice is opened, all analytic lines generated will have this invoice as origin.
-
-This module is intended to be inherited in order to add multiple types of source
-for an analytic line.
-
-Contributors
-------------
-* David Dufresne (david.dufresne@numigi.com)
diff --git a/.unported_addons/analytic_source/__init__.py b/.unported_addons/analytic_source/__init__.py
deleted file mode 100644
index fc8d60fb..00000000
--- a/.unported_addons/analytic_source/__init__.py
+++ /dev/null
@@ -1,5 +0,0 @@
-# © 2017 Savoir-faire Linux
-# © 2018 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-from . import models
diff --git a/.unported_addons/analytic_source/__manifest__.py b/.unported_addons/analytic_source/__manifest__.py
deleted file mode 100644
index 4e26d798..00000000
--- a/.unported_addons/analytic_source/__manifest__.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# © 2017 Savoir-faire Linux
-# © 2018 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-{
- 'name': 'Analytic Source',
- 'version': '1.0.0',
- 'author': 'Savoir-faire Linux',
- 'maintainer': 'Numigi',
- 'website': 'http://www.savoirfairelinux.com',
- 'license': 'LGPL-3',
- 'category': 'Accounting',
- 'summary': 'Add field source to analytic lines.',
- 'depends': [
- 'account',
- ],
- 'data': [
- 'views/account_analytic_line.xml',
- ],
- 'installable': True,
- 'application': False,
-}
diff --git a/.unported_addons/analytic_source/i18n/fr.po b/.unported_addons/analytic_source/i18n/fr.po
deleted file mode 100644
index d50cbb09..00000000
--- a/.unported_addons/analytic_source/i18n/fr.po
+++ /dev/null
@@ -1,29 +0,0 @@
-# Translation of Odoo Server.
-# This file contains the translation of the following modules:
-# * analytic_source
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: Odoo Server 10.0e\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-11-22 13:33-0500\n"
-"PO-Revision-Date: 2017-11-22 13:38-0500\n"
-"Last-Translator: David Dufresne \n"
-"Language-Team: \n"
-"Language: fr\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: \n"
-"X-Generator: Poedit 1.8.7.1\n"
-
-#. module: analytic_source
-#: model:ir.model.fields,field_description:analytic_source.field_account_analytic_line_source
-msgid "Source"
-msgstr "Source"
-
-#. module: analytic_source
-#: selection:account.analytic.line,source:0
-#: model:ir.model.fields,field_description:analytic_source.field_account_analytic_line_invoice_id
-msgid "Invoice"
-msgstr "Facture"
diff --git a/.unported_addons/analytic_source/models/__init__.py b/.unported_addons/analytic_source/models/__init__.py
deleted file mode 100644
index 6b891568..00000000
--- a/.unported_addons/analytic_source/models/__init__.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# © 2017 Savoir-faire Linux
-# © 2018 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-from . import (
- account_analytic_line,
- account_invoice,
-)
diff --git a/.unported_addons/analytic_source/models/account_analytic_line.py b/.unported_addons/analytic_source/models/account_analytic_line.py
deleted file mode 100644
index 31362328..00000000
--- a/.unported_addons/analytic_source/models/account_analytic_line.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# © 2017 Savoir-faire Linux
-# © 2018 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-from odoo import fields, models
-
-
-class AccountAnalyticLine(models.Model):
-
- _inherit = 'account.analytic.line'
-
- source = fields.Reference(selection=[
- ('account.invoice', 'Invoice'),
- ], readonly=True, string="Source")
diff --git a/.unported_addons/analytic_source/models/account_invoice.py b/.unported_addons/analytic_source/models/account_invoice.py
deleted file mode 100644
index 15a7821b..00000000
--- a/.unported_addons/analytic_source/models/account_invoice.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# © 2017 Savoir-faire Linux
-# © 2018 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-from odoo import api, models
-
-
-class AccountInvoice(models.Model):
-
- _inherit = 'account.invoice'
-
- def action_invoice_open(self):
- super(AccountInvoice, self).action_invoice_open()
-
- for invoice in self:
- lines = invoice.mapped('move_id.line_ids.analytic_line_ids')
- lines.write({'source': 'account.invoice,%s' % invoice.id})
diff --git a/.unported_addons/analytic_source/views/account_analytic_line.xml b/.unported_addons/analytic_source/views/account_analytic_line.xml
deleted file mode 100644
index 0e06c577..00000000
--- a/.unported_addons/analytic_source/views/account_analytic_line.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
- account.analytic.line.form
- account.analytic.line
-
-
-
-
-
-
-
-
-
-
diff --git a/.unported_addons/budget_analysis_account_move_line/README.rst b/.unported_addons/budget_analysis_account_move_line/README.rst
deleted file mode 100644
index fb4640e9..00000000
--- a/.unported_addons/budget_analysis_account_move_line/README.rst
+++ /dev/null
@@ -1,23 +0,0 @@
-Budget Analysis Account Move Lines
-==================================
-This module allows to open the list of journal entries from a budget line.
-
-Usage
------
-As member of the group ``Accounting & Finance / Accountant``, I go to ``Accounting / Reporting / Budget Analysis``.
-
-.. image:: static/description/budget_analysis_menu.png
-
-I notice that the amounts in the column ``Practical Amount`` are clickable.
-
-.. image:: static/description/budget_line_list.png
-
-If I click on one of these amounts, the list of journal items related to this budget line is displayed.
-
-.. image:: static/description/budget_line_click.png
-
-.. image:: static/description/journal_item_list.png
-
-Contributors
-------------
-* Numigi (tm) and all its contributors (https://bit.ly/numigiens)
diff --git a/.unported_addons/budget_analysis_account_move_line/__init__.py b/.unported_addons/budget_analysis_account_move_line/__init__.py
deleted file mode 100644
index 21228467..00000000
--- a/.unported_addons/budget_analysis_account_move_line/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# © 2019 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-from . import models
diff --git a/.unported_addons/budget_analysis_account_move_line/__manifest__.py b/.unported_addons/budget_analysis_account_move_line/__manifest__.py
deleted file mode 100644
index e3a5e7cb..00000000
--- a/.unported_addons/budget_analysis_account_move_line/__manifest__.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# © 2019 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-{
- 'name': 'Budget Analysis Account Move Lines',
- 'version': '1.0.0',
- 'author': 'Numigi',
- 'maintainer': 'Numigi',
- 'website': 'https://www.numigi.com',
- 'license': 'LGPL-3',
- 'category': 'Accounting',
- 'summary': 'Display the journal entries from the budget analysis report.',
- 'depends': ['account_budget'],
- 'data': [
- 'views/assets.xml',
- 'views/crossovered_budget_lines.xml',
- ],
- 'installable': True,
-}
diff --git a/.unported_addons/budget_analysis_account_move_line/i18n/fr.po b/.unported_addons/budget_analysis_account_move_line/i18n/fr.po
deleted file mode 100644
index 1e99e38f..00000000
--- a/.unported_addons/budget_analysis_account_move_line/i18n/fr.po
+++ /dev/null
@@ -1,26 +0,0 @@
-# Translation of Odoo Server.
-# This file contains the translation of the following modules:
-# * budget_analysis_account_move_line
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: Odoo Server 12.0+e\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-06-19 01:59+0000\n"
-"PO-Revision-Date: 2019-06-19 01:59+0000\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: budget_analysis_account_move_line
-#: model:ir.model,name:budget_analysis_account_move_line.model_crossovered_budget_lines
-msgid "Budget Line"
-msgstr ""
-
-#. module: budget_analysis_account_move_line
-#: model:ir.actions.act_window,name:budget_analysis_account_move_line.action_move_lines_from_budget_lines
-msgid "Journal Items"
-msgstr "Écritures comptables"
diff --git a/.unported_addons/budget_analysis_account_move_line/models/__init__.py b/.unported_addons/budget_analysis_account_move_line/models/__init__.py
deleted file mode 100644
index 639ad51b..00000000
--- a/.unported_addons/budget_analysis_account_move_line/models/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# © 2019 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-from . import crossovered_budget_lines
diff --git a/.unported_addons/budget_analysis_account_move_line/models/crossovered_budget_lines.py b/.unported_addons/budget_analysis_account_move_line/models/crossovered_budget_lines.py
deleted file mode 100644
index 49e524d0..00000000
--- a/.unported_addons/budget_analysis_account_move_line/models/crossovered_budget_lines.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# © 2019 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-from odoo import models
-
-
-class BudgetLine(models.Model):
-
- _inherit = 'crossovered.budget.lines'
-
- def _get_move_line_domain(self):
- """Get the domain to filter the list view of journal items."""
- domain = [
- ('date', '>=', self.date_from),
- ('date', '<=', self.date_to),
- ]
-
- if self.general_budget_id:
- domain.append(('account_id', 'in', self.general_budget_id.account_ids.ids))
-
- if self.analytic_account_id:
- domain.append(('analytic_account_id', '=', self.analytic_account_id.id))
-
- return domain
-
- def action_view_move_lines(self):
- action = self.env.ref(
- 'budget_analysis_account_move_line.action_move_lines_from_budget_lines')
- result = action.read()[0]
- result['display_name'] = '{} ({})'.format(result['name'], self.display_name)
- result['domain'] = self._get_move_line_domain()
- return result
diff --git a/.unported_addons/budget_analysis_account_move_line/static/description/budget_analysis_menu.png b/.unported_addons/budget_analysis_account_move_line/static/description/budget_analysis_menu.png
deleted file mode 100644
index 30979878..00000000
Binary files a/.unported_addons/budget_analysis_account_move_line/static/description/budget_analysis_menu.png and /dev/null differ
diff --git a/.unported_addons/budget_analysis_account_move_line/static/description/budget_line_click.png b/.unported_addons/budget_analysis_account_move_line/static/description/budget_line_click.png
deleted file mode 100644
index 43cbec9a..00000000
Binary files a/.unported_addons/budget_analysis_account_move_line/static/description/budget_line_click.png and /dev/null differ
diff --git a/.unported_addons/budget_analysis_account_move_line/static/description/budget_line_list.png b/.unported_addons/budget_analysis_account_move_line/static/description/budget_line_list.png
deleted file mode 100644
index 3a9c246d..00000000
Binary files a/.unported_addons/budget_analysis_account_move_line/static/description/budget_line_list.png and /dev/null differ
diff --git a/.unported_addons/budget_analysis_account_move_line/static/description/icon.png b/.unported_addons/budget_analysis_account_move_line/static/description/icon.png
deleted file mode 100644
index 92a86b10..00000000
Binary files a/.unported_addons/budget_analysis_account_move_line/static/description/icon.png and /dev/null differ
diff --git a/.unported_addons/budget_analysis_account_move_line/static/description/journal_item_list.png b/.unported_addons/budget_analysis_account_move_line/static/description/journal_item_list.png
deleted file mode 100644
index aad4cacc..00000000
Binary files a/.unported_addons/budget_analysis_account_move_line/static/description/journal_item_list.png and /dev/null differ
diff --git a/.unported_addons/budget_analysis_account_move_line/static/src/js/widget.js b/.unported_addons/budget_analysis_account_move_line/static/src/js/widget.js
deleted file mode 100644
index ad4e2d9b..00000000
--- a/.unported_addons/budget_analysis_account_move_line/static/src/js/widget.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- © 2019 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
- License LGPL-3.0 or later (http://www.gnu.org/licenses/LGPL.html).
-*/
-odoo.define("budget_analysis_account_move_line.link_widget", function(require) {
-"use strict";
-
-var rpc = require("web.rpc");
-var basicFields = require("web.basic_fields");
-var AbstractField = require("web.AbstractField");
-
-var BudgetAnalysisToMoveLines = basicFields.FieldFloat.extend({
- className: "o_field_float o_field_number o_budget_analysis_to_move_lines",
- tagName: "a",
- events: _.extend({}, AbstractField.prototype.events, {
- "click": "_onClick",
- }),
- /**
- * When clicking on the amount, trigger the action to display the list of move lines.
- */
- async _onClick(event){
- event.preventDefault();
- event.stopPropagation();
- var action = await rpc.query({
- model: "crossovered.budget.lines",
- method: "action_view_move_lines",
- args: [this.record.res_id],
- context: this.getSession().user_context,
- });
- this.do_action(action);
- },
- /**
- * Display the field as a clickable link.
- *
- * Because of bootstrap, nodes without href do not appear as clickable links.
- */
- _render(){
- this._super.apply(this, arguments);
- this.$el.attr("href", "#");
- },
- /**
- * Fix the non-break spaces in amounts.
- *
- * When using an node instead of a span, the non-break spaces
- * after or behind the currency symbol is displayed as " ".
- *
- * This function replaces the " " with a real non-break space caracter.
- */
- _formatValue(value){
- var formattedValue = this._super.apply(this, arguments);
- return formattedValue.replace(" ", " ");
- },
-});
-
-var registry = require("web.field_registry");
-registry.add("budget_analysis_to_move_lines", BudgetAnalysisToMoveLines);
-
-});
diff --git a/.unported_addons/budget_analysis_account_move_line/tests/__init__.py b/.unported_addons/budget_analysis_account_move_line/tests/__init__.py
deleted file mode 100644
index d2ac44f2..00000000
--- a/.unported_addons/budget_analysis_account_move_line/tests/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-# © 2019 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
diff --git a/.unported_addons/budget_analysis_account_move_line/tests/test_crossovered_budget_lines.py b/.unported_addons/budget_analysis_account_move_line/tests/test_crossovered_budget_lines.py
deleted file mode 100644
index 12157fc9..00000000
--- a/.unported_addons/budget_analysis_account_move_line/tests/test_crossovered_budget_lines.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# © 2019 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-from datetime import datetime, timedelta
-from odoo.tests import common
-
-
-class TestGetMoveLineDomain(common.SavepointCase):
-
- @classmethod
- def setUpClass(cls):
- super().setUpClass()
- cls.date_from = datetime.now()
- cls.date_to = datetime.now() + timedelta(365)
- cls.budget_1 = cls.env['crossovered.budget'].create({
- 'name': 'Budget Test 1',
- 'date_from': cls.date_from,
- 'date_to': cls.date_to,
- })
-
- cls.analytic_account = cls.env['account.analytic.account'].create({
- 'name': 'Analytic Account 1'
- })
-
- cls.account = cls.env['account.account'].create({
- 'name': 'General Expenses',
- 'code': '510100',
- 'user_type_id': cls.env.ref('account.data_account_type_expenses').id,
- })
-
- cls.budget_position = cls.env['account.budget.post'].create({
- 'name': 'General Expenses',
- 'account_ids': [(4, cls.account.id)],
- })
-
- cls.budget_line_1 = cls.env['crossovered.budget.lines'].create({
- 'crossovered_budget_id': cls.budget_1.id,
- 'analytic_account_id': cls.analytic_account.id,
- 'general_budget_id': cls.budget_position.id,
- 'planned_amount': 1000,
- 'date_from': cls.budget_1.date_from,
- 'date_to': cls.budget_1.date_to,
- })
-
- def _get_move_line_domain(self):
- return self.budget_line_1.action_view_move_lines()['domain']
-
- def test_move_date_between_budget_boundaries(self):
- domain = self._get_move_line_domain()
- assert ('date', '>=', self.budget_1.date_from) in domain
- assert ('date', '<=', self.budget_1.date_to) in domain
-
- def test_if_budget_line_has_budget_position__general_account_filtered(self):
- self.budget_line_1.general_budget_id = self.budget_position
- domain = self._get_move_line_domain()
- assert ('account_id', 'in', [self.account.id]) in domain
-
- def test_if_budget_line_has_analytic_account__analytic_account_filtered(self):
- self.budget_line_1.analytic_account_id = self.analytic_account
- domain = self._get_move_line_domain()
- assert ('analytic_account_id', '=', self.analytic_account.id) in domain
diff --git a/.unported_addons/budget_analysis_account_move_line/views/assets.xml b/.unported_addons/budget_analysis_account_move_line/views/assets.xml
deleted file mode 100644
index d6d4f33b..00000000
--- a/.unported_addons/budget_analysis_account_move_line/views/assets.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/.unported_addons/budget_analysis_account_move_line/views/crossovered_budget_lines.xml b/.unported_addons/budget_analysis_account_move_line/views/crossovered_budget_lines.xml
deleted file mode 100644
index 7911e37d..00000000
--- a/.unported_addons/budget_analysis_account_move_line/views/crossovered_budget_lines.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
- Journal Items
- ir.actions.act_window
- account.move.line
- list,pivot,graph,form
-
-
-
- Budget Line Form: make practical amount clickable to view journal items
- crossovered.budget.lines
-
-
-
- budget_analysis_to_move_lines
-
-
-
-
-
- Budget Line List: make practical amount clickable to view journal items
- crossovered.budget.lines
-
-
-
- budget_analysis_to_move_lines
-
-
-
-
-
diff --git a/.unported_addons/invoice_write_access/README.rst b/.unported_addons/invoice_write_access/README.rst
deleted file mode 100644
index 833331f0..00000000
--- a/.unported_addons/invoice_write_access/README.rst
+++ /dev/null
@@ -1,37 +0,0 @@
-Invoice Write Access
-====================
-This module restricts the access to update/create/delete an invoice to a specific group.
-
-Context
--------
-In vanilla Odoo, any member of ``Sale / User`` or ``Purchase / User`` is allowed to update/create/delete an invoice.
-
-How The Module Works
---------------------
-A new technical group ``Invoice Write Access`` is added.
-
-.. image:: static/description/invoice_group.png
-
-The group ``Accounting / Billing`` inherits this group.
-It is not possible to have ``Accounting / Billing`` without ``Invoice Write Access``.
-
-Hidden Buttons
-~~~~~~~~~~~~~~
-The buttons to create an invoice are hidden on the purchase and sales order for non-members of
-the group ``Invoice Write Access``. See modules ``invoice_write_access_sale`` and ``invoice_write_access_sale``.
-
-Extended Security Rules
-~~~~~~~~~~~~~~~~~~~~~~~
-The module `base_extended_security `_
-is used to prevent non-members of the new group to create/update/delete an invoice.
-
-This mecanism prevents user to create an invoice through the web interface, but does not impact
-the internal behavior of Odoo. This limits the risk to create side effects related to modifying native Odoo ACL.
-
-For example, if an unauthorized user attemps to create an invoice, the following message will be displayed:
-
-.. image:: static/description/invoice_create_message.png
-
-Contributors
-------------
-* Numigi (tm) and all its contributors (https://bit.ly/numigiens)
diff --git a/.unported_addons/invoice_write_access/__init__.py b/.unported_addons/invoice_write_access/__init__.py
deleted file mode 100644
index 6da4fa4e..00000000
--- a/.unported_addons/invoice_write_access/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# © 2019 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-from . import models
diff --git a/.unported_addons/invoice_write_access/__manifest__.py b/.unported_addons/invoice_write_access/__manifest__.py
deleted file mode 100644
index 8b4d8c92..00000000
--- a/.unported_addons/invoice_write_access/__manifest__.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# © 2019 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-{
- 'name': 'Invoice Write Access',
- 'version': '1.0.0',
- 'author': 'Numigi',
- 'maintainer': 'Numigi',
- 'website': 'https://www.numigi.com',
- 'license': 'LGPL-3',
- 'category': 'Accounting',
- 'summary': 'Restrict the creation/update of invoices',
- 'depends': [
- 'account',
- 'base_extended_security',
- ],
- 'data': [
- 'security/res_groups.xml',
- ],
- 'installable': True,
-}
diff --git a/.unported_addons/invoice_write_access/i18n/fr.po b/.unported_addons/invoice_write_access/i18n/fr.po
deleted file mode 100644
index 51eb299c..00000000
--- a/.unported_addons/invoice_write_access/i18n/fr.po
+++ /dev/null
@@ -1,44 +0,0 @@
-# Translation of Odoo Server.
-# This file contains the translation of the following modules:
-# * invoice_write_access
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: Odoo Server 12.0+e\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-08-20 19:15+0000\n"
-"PO-Revision-Date: 2019-08-20 19:15+0000\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: invoice_write_access
-#: model:ir.model,name:invoice_write_access.model_account_invoice
-msgid "Invoice"
-msgstr ""
-
-#. module: invoice_write_access
-#: model:res.groups,name:invoice_write_access.group_invoice
-msgid "Invoice Write Access"
-msgstr "Accès modification de facture"
-
-#. module: invoice_write_access
-#: code:addons/invoice_write_access/models/invoice.py:7
-#, python-format
-msgid "You are not authorized to create an invoice."
-msgstr "Vous n'êtes pas autorisé à créer une facture."
-
-#. module: invoice_write_access
-#: code:addons/invoice_write_access/models/invoice.py:15
-#, python-format
-msgid "You are not authorized to delete an invoice."
-msgstr "Vous n'êtes pas autorisé à supprimer une facture."
-
-#. module: invoice_write_access
-#: code:addons/invoice_write_access/models/invoice.py:11
-#, python-format
-msgid "You are not authorized to update an invoice."
-msgstr "Vous n'êtes pas autorisé à modifier une facture."
diff --git a/.unported_addons/invoice_write_access/models/__init__.py b/.unported_addons/invoice_write_access/models/__init__.py
deleted file mode 100644
index ecfe5c8a..00000000
--- a/.unported_addons/invoice_write_access/models/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# © 2019 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-from . import invoice
diff --git a/.unported_addons/invoice_write_access/models/invoice.py b/.unported_addons/invoice_write_access/models/invoice.py
deleted file mode 100644
index 6e02bd9c..00000000
--- a/.unported_addons/invoice_write_access/models/invoice.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# © 2019 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-from odoo import models, _
-from odoo.exceptions import AccessError
-
-INVOICE_CREATE_ERROR_MESSAGE = _(
- "You are not authorized to create an invoice."
-)
-
-INVOICE_WRITE_ERROR_MESSAGE = _(
- "You are not authorized to update an invoice."
-)
-
-INVOICE_UNLINK_ERROR_MESSAGE = _(
- "You are not authorized to delete an invoice."
-)
-
-
-class Invoice(models.Model):
-
- _inherit = 'account.invoice'
-
- def check_extended_security_write(self):
- super().check_extended_security_write()
- if not self.env.user.has_group('invoice_write_access.group_invoice'):
- raise AccessError(_(INVOICE_WRITE_ERROR_MESSAGE))
-
- def check_extended_security_create(self):
- super().check_extended_security_create()
- if not self.env.user.has_group('invoice_write_access.group_invoice'):
- raise AccessError(_(INVOICE_CREATE_ERROR_MESSAGE))
-
- def check_extended_security_unlink(self):
- super().check_extended_security_unlink()
- if not self.env.user.has_group('invoice_write_access.group_invoice'):
- raise AccessError(_(INVOICE_UNLINK_ERROR_MESSAGE))
diff --git a/.unported_addons/invoice_write_access/security/res_groups.xml b/.unported_addons/invoice_write_access/security/res_groups.xml
deleted file mode 100644
index ce50b619..00000000
--- a/.unported_addons/invoice_write_access/security/res_groups.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
- Invoice Write Access
-
-
-
-
-
-
-
diff --git a/.unported_addons/invoice_write_access/static/description/icon.png b/.unported_addons/invoice_write_access/static/description/icon.png
deleted file mode 100644
index 92a86b10..00000000
Binary files a/.unported_addons/invoice_write_access/static/description/icon.png and /dev/null differ
diff --git a/.unported_addons/invoice_write_access/static/description/invoice_create_message.png b/.unported_addons/invoice_write_access/static/description/invoice_create_message.png
deleted file mode 100644
index f6684caf..00000000
Binary files a/.unported_addons/invoice_write_access/static/description/invoice_create_message.png and /dev/null differ
diff --git a/.unported_addons/invoice_write_access/static/description/invoice_group.png b/.unported_addons/invoice_write_access/static/description/invoice_group.png
deleted file mode 100644
index bd44250b..00000000
Binary files a/.unported_addons/invoice_write_access/static/description/invoice_group.png and /dev/null differ
diff --git a/.unported_addons/invoice_write_access/tests/__init__.py b/.unported_addons/invoice_write_access/tests/__init__.py
deleted file mode 100644
index 6ef2df91..00000000
--- a/.unported_addons/invoice_write_access/tests/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-# © 2019 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
diff --git a/.unported_addons/invoice_write_access/tests/test_invoice_access.py b/.unported_addons/invoice_write_access/tests/test_invoice_access.py
deleted file mode 100644
index fcdc695b..00000000
--- a/.unported_addons/invoice_write_access/tests/test_invoice_access.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# © 2019 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-import pytest
-from odoo.exceptions import AccessError
-from odoo.tests.common import SavepointCase
-
-
-class TestInvoiceAccess(SavepointCase):
-
- @classmethod
- def setUpClass(cls):
- super().setUpClass()
- cls.user = cls.env['res.users'].create({
- 'name': 'My User',
- 'login': 'testinvoice@example.com',
- 'email': 'testinvoice@example.com',
- 'groups_id': [
- (4, cls.env.ref('purchase.group_purchase_user').id),
- (4, cls.env.ref('sales_team.group_sale_salesman').id),
- ],
- })
-
- def test_if_user_unauthorized__on_create__raise_error(self):
- with pytest.raises(AccessError):
- self.env['account.invoice'].sudo(self.user).check_extended_security_create()
-
- def test_if_user_authorized__on_create__error_not_raised(self):
- self.user.groups_id |= self.env.ref('invoice_write_access.group_invoice')
- self.env['account.invoice'].sudo(self.user).check_extended_security_create()
-
- def test_if_user_unauthorized__on_write__raise_error(self):
- with pytest.raises(AccessError):
- self.env['account.invoice'].sudo(self.user).check_extended_security_write()
-
- def test_if_user_authorized__on_write__error_not_raised(self):
- self.user.groups_id |= self.env.ref('invoice_write_access.group_invoice')
- self.env['account.invoice'].sudo(self.user).check_extended_security_write()
-
- def test_if_user_unauthorized__on_unlink__raise_error(self):
- with pytest.raises(AccessError):
- self.env['account.invoice'].sudo(self.user).check_extended_security_unlink()
-
- def test_if_user_authorized__on_unlink__error_not_raised(self):
- self.user.groups_id |= self.env.ref('invoice_write_access.group_invoice')
- self.env['account.invoice'].sudo(self.user).check_extended_security_unlink()
diff --git a/.unported_addons/invoice_write_access_purchase/README.rst b/.unported_addons/invoice_write_access_purchase/README.rst
deleted file mode 100644
index d4f7fe1b..00000000
--- a/.unported_addons/invoice_write_access_purchase/README.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-Invoice Write Access - Purchase
-===============================
-This module is a binding between the modules ``invoice_write_access`` and ``purchase``.
-
-On the form view of a purchase order, the button to create an invoice is hidden for non-members of the group ``Invoice Write Access``.
-
-.. image:: static/description/purchase_order_form.png
-
-Contributors
-------------
-* Numigi (tm) and all its contributors (https://bit.ly/numigiens)
diff --git a/.unported_addons/invoice_write_access_purchase/__init__.py b/.unported_addons/invoice_write_access_purchase/__init__.py
deleted file mode 100644
index 6ef2df91..00000000
--- a/.unported_addons/invoice_write_access_purchase/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-# © 2019 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
diff --git a/.unported_addons/invoice_write_access_purchase/__manifest__.py b/.unported_addons/invoice_write_access_purchase/__manifest__.py
deleted file mode 100644
index e15aefdc..00000000
--- a/.unported_addons/invoice_write_access_purchase/__manifest__.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# © 2019 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-{
- 'name': 'Invoice Write Access / Purchase',
- 'version': '1.0.0',
- 'author': 'Numigi',
- 'maintainer': 'Numigi',
- 'website': 'https://www.numigi.com',
- 'license': 'LGPL-3',
- 'category': 'Accounting',
- 'summary': 'Restrict the creation/update of vendor bills',
- 'depends': [
- 'invoice_write_access',
- 'purchase',
- ],
- 'data': [
- 'views/purchase_order.xml',
- ],
- 'installable': True,
- 'auto_install': True,
-}
diff --git a/.unported_addons/invoice_write_access_purchase/static/description/icon.png b/.unported_addons/invoice_write_access_purchase/static/description/icon.png
deleted file mode 100644
index 92a86b10..00000000
Binary files a/.unported_addons/invoice_write_access_purchase/static/description/icon.png and /dev/null differ
diff --git a/.unported_addons/invoice_write_access_purchase/static/description/purchase_order_form.png b/.unported_addons/invoice_write_access_purchase/static/description/purchase_order_form.png
deleted file mode 100644
index 5cc3d5ed..00000000
Binary files a/.unported_addons/invoice_write_access_purchase/static/description/purchase_order_form.png and /dev/null differ
diff --git a/.unported_addons/invoice_write_access_purchase/views/purchase_order.xml b/.unported_addons/invoice_write_access_purchase/views/purchase_order.xml
deleted file mode 100644
index 5881fee1..00000000
--- a/.unported_addons/invoice_write_access_purchase/views/purchase_order.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
- Purchase Order: restrict button to create invoice
- purchase.order
-
-
-
- invoice_write_access.group_invoice
-
-
- invoice_write_access.group_invoice
-
-
-
-
-
diff --git a/.unported_addons/invoice_write_access_sale/README.rst b/.unported_addons/invoice_write_access_sale/README.rst
deleted file mode 100644
index 422a2d57..00000000
--- a/.unported_addons/invoice_write_access_sale/README.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-Invoice Write Access - Sale
-===========================
-This module is a binding between the modules ``invoice_write_access`` and ``sale``.
-
-On the form view of a sale order, the button to create an invoice is hidden for non-members of the group ``Invoice Write Access``.
-
-.. image:: static/description/sale_order_form.png
-
-Contributors
-------------
-* Numigi (tm) and all its contributors (https://bit.ly/numigiens)
diff --git a/.unported_addons/invoice_write_access_sale/__init__.py b/.unported_addons/invoice_write_access_sale/__init__.py
deleted file mode 100644
index 6ef2df91..00000000
--- a/.unported_addons/invoice_write_access_sale/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-# © 2019 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
diff --git a/.unported_addons/invoice_write_access_sale/__manifest__.py b/.unported_addons/invoice_write_access_sale/__manifest__.py
deleted file mode 100644
index 1444b9b2..00000000
--- a/.unported_addons/invoice_write_access_sale/__manifest__.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# © 2019 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-{
- 'name': 'Invoice Write Access / Sale',
- 'version': '1.0.0',
- 'author': 'Numigi',
- 'maintainer': 'Numigi',
- 'website': 'https://www.numigi.com',
- 'license': 'LGPL-3',
- 'category': 'Accounting',
- 'summary': 'Restrict the creation/update of customer invoices',
- 'depends': [
- 'invoice_write_access',
- 'sale_management',
- ],
- 'data': [
- 'views/sale_order.xml',
- ],
- 'installable': True,
- 'auto_install': True,
-}
diff --git a/.unported_addons/invoice_write_access_sale/static/description/icon.png b/.unported_addons/invoice_write_access_sale/static/description/icon.png
deleted file mode 100644
index 92a86b10..00000000
Binary files a/.unported_addons/invoice_write_access_sale/static/description/icon.png and /dev/null differ
diff --git a/.unported_addons/invoice_write_access_sale/static/description/sale_order_form.png b/.unported_addons/invoice_write_access_sale/static/description/sale_order_form.png
deleted file mode 100644
index a8f8dded..00000000
Binary files a/.unported_addons/invoice_write_access_sale/static/description/sale_order_form.png and /dev/null differ
diff --git a/.unported_addons/invoice_write_access_sale/views/sale_order.xml b/.unported_addons/invoice_write_access_sale/views/sale_order.xml
deleted file mode 100644
index c0cfa8db..00000000
--- a/.unported_addons/invoice_write_access_sale/views/sale_order.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
- Sale Order: restrict button to create invoice
- sale.order
-
-
-
- invoice_write_access.group_invoice
-
-
- invoice_write_access.group_invoice
-
-
-
-
-
-
-
-
-
diff --git a/.unported_addons/payment_workflow/README.rst b/.unported_addons/payment_workflow/README.rst
deleted file mode 100644
index 07d59d47..00000000
--- a/.unported_addons/payment_workflow/README.rst
+++ /dev/null
@@ -1,17 +0,0 @@
-================
-Payment Workflow
-================
-
-This module improves payment management in Odoo with a workflow more similar to invoices.
-
-It adds :
-* 2 new contact type: Customer Payment and Supplier Payment
-* a chatter below the payment form view
-
-It also adds a method that allows to get a partner child that corresponds to the first existant
-address in a list given in parameter, if no child is found, the parent himself is returned
-
-Contributors
-------------
-* David Dufresne (david.dufresne@numigi.com)
-* Yasmine El Mrini (yasmine.elmrini@numigi.com)
diff --git a/.unported_addons/payment_workflow/__init__.py b/.unported_addons/payment_workflow/__init__.py
deleted file mode 100644
index fc8d60fb..00000000
--- a/.unported_addons/payment_workflow/__init__.py
+++ /dev/null
@@ -1,5 +0,0 @@
-# © 2017 Savoir-faire Linux
-# © 2018 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-from . import models
diff --git a/.unported_addons/payment_workflow/__manifest__.py b/.unported_addons/payment_workflow/__manifest__.py
deleted file mode 100644
index e96ea681..00000000
--- a/.unported_addons/payment_workflow/__manifest__.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# © 2017 Savoir-faire Linux
-# © 2018 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-{
- 'name': 'Payment Workflow',
- 'version': '1.0.0',
- 'author': 'Savoir-faire Linux',
- 'maintainer': 'Numigi',
- 'website': 'http://www.savoirfairelinux.com',
- 'license': 'LGPL-3',
- 'category': 'Accounting',
- 'summary': 'Add new contact types.',
- 'depends': [
- 'base',
- 'account',
- ],
- 'data': [
- 'views/account_payment.xml',
- ],
- 'installable': False,
- 'application': False,
-}
diff --git a/.unported_addons/payment_workflow/i18n/fr.po b/.unported_addons/payment_workflow/i18n/fr.po
deleted file mode 100644
index 903d4d65..00000000
--- a/.unported_addons/payment_workflow/i18n/fr.po
+++ /dev/null
@@ -1,31 +0,0 @@
-# Translation of Odoo Server.
-# This file contains the translation of the following modules:
-# * payment_workflow
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: Odoo Server 10.0+e\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-11-17 03:35+0000\n"
-"PO-Revision-Date: 2017-11-17 03:35+0000\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: payment_workflow
-#: model:ir.model,name:payment_workflow.model_res_partner
-msgid "Partner"
-msgstr "Partenaire"
-
-#. module: payment_workflow
-#: selection:res.partner,type:0
-msgid "Supplier Payment"
-msgstr "Paiement fournisseur"
-
-#. module: payment_workflow
-#: selection:res.partner,type:0
-msgid "Customer Payment"
-msgstr "Paiement client"
diff --git a/.unported_addons/payment_workflow/models/__init__.py b/.unported_addons/payment_workflow/models/__init__.py
deleted file mode 100644
index 79a1f43f..00000000
--- a/.unported_addons/payment_workflow/models/__init__.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# © 2017 Savoir-faire Linux
-# © 2018 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-from . import (
- account_payment,
- res_partner,
-)
diff --git a/.unported_addons/payment_workflow/models/account_payment.py b/.unported_addons/payment_workflow/models/account_payment.py
deleted file mode 100644
index 8d52b16a..00000000
--- a/.unported_addons/payment_workflow/models/account_payment.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# © 2017 Savoir-faire Linux
-# © 2018 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-from odoo import fields, models
-
-
-class AccountPayment(models.Model):
-
- _name = 'account.payment'
- _inherit = ['mail.thread', 'account.payment']
-
- payment_type = fields.Selection(track_visibility='onchange')
- payment_method_id = fields.Many2one(track_visibility='onchange')
- partner_type = fields.Selection(track_visibility='onchange')
- partner_id = fields.Many2one(track_visibility='onchange')
- amount = fields.Monetary(track_visibility='onchange')
- currency_id = fields.Many2one(track_visibility='onchange')
- payment_date = fields.Date(track_visibility='onchange')
- communication = fields.Char(track_visibility='onchange')
- journal_id = fields.Many2one(track_visibility='onchange')
- state = fields.Selection(track_visibility='onchange')
- payment_reference = fields.Char(track_visibility='onchange')
- check_amount_in_words = fields.Char(track_visibility='onchange')
- check_number = fields.Integer(track_visibility='onchange')
diff --git a/.unported_addons/payment_workflow/models/res_partner.py b/.unported_addons/payment_workflow/models/res_partner.py
deleted file mode 100644
index 212d8f09..00000000
--- a/.unported_addons/payment_workflow/models/res_partner.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# © 2017 Savoir-faire Linux
-# © 2018 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-from odoo import fields, models
-
-
-class ResPartner(models.Model):
-
- _inherit = 'res.partner'
-
- type = fields.Selection(selection_add=[
- ('supplier_payment', 'Supplier Payment'),
- ('customer_payment', 'Customer Payment'),
- ])
-
- def get_preferred_address(self, contact_types):
- """Get a preferred address from a partner.
-
- This function is meant to be used in a email template.
-
- For example, in a payment notice email, the field partner_to
- could be filled as follow:
-
- ${object.partner_id.get_preferred_address(
- ['supplier_payment', 'invoice']).id|safe}
-
- If the partner has an address of type 'supplier_payment',
- this address will be used in the email. Otherwise, an address
- of type 'invoice' will be selected. If the partner does not have
- an address of type 'invoice' either, the email will be sent
- to the partner himself.
-
- :param list contact_types: The types of address in order of priority
- :rtype: res.partner
- :return: The address
- """
- for contact_type in contact_types:
- contact_id = self.address_get([contact_type])[contact_type]
- if contact_id != self.id:
- return self.browse(contact_id)
-
- return self
diff --git a/.unported_addons/payment_workflow/tests/__init__.py b/.unported_addons/payment_workflow/tests/__init__.py
deleted file mode 100644
index aff185bc..00000000
--- a/.unported_addons/payment_workflow/tests/__init__.py
+++ /dev/null
@@ -1,5 +0,0 @@
-# © 2017 Savoir-faire Linux
-# © 2018 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-from . import test_res_partner
diff --git a/.unported_addons/payment_workflow/tests/test_res_partner.py b/.unported_addons/payment_workflow/tests/test_res_partner.py
deleted file mode 100644
index 0576c1de..00000000
--- a/.unported_addons/payment_workflow/tests/test_res_partner.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# © 2017 Savoir-faire Linux
-# © 2018 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-from openerp.tests import SavepointCase
-
-
-class TestResPartner(SavepointCase):
-
- @classmethod
- def setUpClass(cls):
- super(TestResPartner, cls).setUpClass()
-
- cls.parent = cls.env['res.partner'].create({
- 'name': 'Parent',
- })
-
- cls.invoice_address = cls.env['res.partner'].create({
- 'name': 'Invoice Address',
- 'type': 'invoice',
- 'parent_id': cls.parent.id,
- })
-
- cls.customer_payment = cls.env['res.partner'].create({
- 'name': 'Customer Payment',
- 'type': 'customer_payment',
- 'parent_id': cls.parent.id,
- })
-
- def test_01_get_preferred_address_first_contact_returned(self):
- contact = self.parent.get_preferred_address(
- ['customer_payment', 'invoice'])
- self.assertEquals(contact, self.customer_payment)
-
- def test_02_get_preferred_address_second_contact_returned(self):
- contact = self.parent.get_preferred_address(
- ['supplier_payment', 'invoice'])
- self.assertEquals(contact, self.invoice_address)
-
- def test_03_get_preferred_address_parent_returned(self):
- contact = self.parent.get_preferred_address(
- ['supplier_payment', 'delivery'])
- self.assertEquals(contact, self.parent)
diff --git a/.unported_addons/payment_workflow/views/account_payment.xml b/.unported_addons/payment_workflow/views/account_payment.xml
deleted file mode 100644
index 0f60d9fe..00000000
--- a/.unported_addons/payment_workflow/views/account_payment.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
- account.payment.form
- account.payment
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/.unported_addons/payment_workflow_enterprise/README.rst b/.unported_addons/payment_workflow_enterprise/README.rst
deleted file mode 100644
index a89c204b..00000000
--- a/.unported_addons/payment_workflow_enterprise/README.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-===========================
-Payment Workflow Enterprise
-===========================
-
-This module allows to choose the new contact type Customer Payment if it exists, if it doesn't the invoice address
-is chosen, so that the system set the mails receiver that corresponds to payment orders to the person in charge of them.
-
-Contributors
-------------
-* David Dufresne (david.dufresne@numigi.com)
-* Yasmine El Mrini (yasmine.elmrini@numigi.com)
diff --git a/.unported_addons/payment_workflow_enterprise/__init__.py b/.unported_addons/payment_workflow_enterprise/__init__.py
deleted file mode 100644
index fc8d60fb..00000000
--- a/.unported_addons/payment_workflow_enterprise/__init__.py
+++ /dev/null
@@ -1,5 +0,0 @@
-# © 2017 Savoir-faire Linux
-# © 2018 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-from . import models
diff --git a/.unported_addons/payment_workflow_enterprise/__manifest__.py b/.unported_addons/payment_workflow_enterprise/__manifest__.py
deleted file mode 100644
index 1bf45d5a..00000000
--- a/.unported_addons/payment_workflow_enterprise/__manifest__.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# © 2017 Savoir-faire Linux
-# © 2018 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-{
- 'name': 'Payment Workflow Enterprise',
- 'version': '1.0.0',
- 'author': 'Savoir-faire Linux',
- 'maintainer': 'Numigi',
- 'website': 'http://www.savoirfairelinux.com',
- 'license': 'LGPL-3',
- 'category': 'Accounting',
- 'summary': 'Set customer payment as default invoice address.',
- 'depends': [
- 'payment_workflow',
- 'account_reports',
- ],
- 'installable': False,
- 'application': False,
-}
diff --git a/.unported_addons/payment_workflow_enterprise/models/__init__.py b/.unported_addons/payment_workflow_enterprise/models/__init__.py
deleted file mode 100644
index 4f0d71fe..00000000
--- a/.unported_addons/payment_workflow_enterprise/models/__init__.py
+++ /dev/null
@@ -1,5 +0,0 @@
-# © 2017 Savoir-faire Linux
-# © 2018 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-from . import account_report_context_followup
diff --git a/.unported_addons/payment_workflow_enterprise/models/account_report_context_followup.py b/.unported_addons/payment_workflow_enterprise/models/account_report_context_followup.py
deleted file mode 100644
index 1960d275..00000000
--- a/.unported_addons/payment_workflow_enterprise/models/account_report_context_followup.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# © 2017 Savoir-faire Linux
-# © 2018 Numigi
-# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-
-from odoo import api, models
-
-
-class AccountReportContextFollowup(models.TransientModel):
-
- _inherit = 'account.report.context.followup'
-
- @api.depends('partner_id')
- def _get_invoice_address(self):
- for partner in self:
- if partner.partner_id:
- partner.invoice_address_id = (
- partner.partner_id.get_preferred_address(
- ['customer_payment', 'invoice']))
- else:
- partner.invoice_address_id = False
diff --git a/Dockerfile b/Dockerfile
index 0175a0eb..51ad7ccf 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,5 +1,5 @@
FROM quay.io/numigi/odoo-public:14.latest
-MAINTAINER numigi
+LABEL maintainer="contact@numigi.com"
USER root
diff --git a/account_additional_group/__manifest__.py b/account_additional_group/__manifest__.py
index b72cc00e..fda191c1 100644
--- a/account_additional_group/__manifest__.py
+++ b/account_additional_group/__manifest__.py
@@ -10,7 +10,9 @@
"license": "LGPL-3",
"category": "Accounting",
"summary": "Add additional groups of accounts",
- "depends": ["account",],
+ "depends": [
+ "account",
+ ],
"data": [
"security/ir.model.access.csv",
"views/account_account.xml",
diff --git a/account_additional_group/tests/test_account_additional_group.py b/account_additional_group/tests/test_account_additional_group.py
index 502b199f..e3daf739 100644
--- a/account_additional_group/tests/test_account_additional_group.py
+++ b/account_additional_group/tests/test_account_additional_group.py
@@ -1,7 +1,6 @@
# © 2021 - today Numigi
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-from datetime import datetime, timedelta
from odoo.tests import common
diff --git a/account_analytic_required_forbidden/i18n/fr.po b/account_analytic_required_forbidden/i18n/fr.po
index 880d443c..09377aad 100644
--- a/account_analytic_required_forbidden/i18n/fr.po
+++ b/account_analytic_required_forbidden/i18n/fr.po
@@ -90,7 +90,8 @@ msgstr ""
#, python-format
msgid ""
"The journal entry can not be posted because the line {line} has no analytic "
-"account. The account {account} requires an analytic account."
+"account. The account {account} requires "
+"an analytic account."
msgstr ""
"La pièce comptable ne peut pas être validée, car la ligne {line} n’a pas de "
"compte analytique. Le compte {account} oblige de renseigner le compte "
diff --git a/account_analytic_required_forbidden/models.py b/account_analytic_required_forbidden/models.py
index 2966da8d..70db8c1c 100644
--- a/account_analytic_required_forbidden/models.py
+++ b/account_analytic_required_forbidden/models.py
@@ -38,7 +38,8 @@ def _check_analytic_account_required_or_forbidden(self):
raise ValidationError(
_(
"The journal entry can not be posted because the line {line} "
- "has no analytic account. The account {account} requires an analytic account."
+ "has no analytic account. The account {account} requires "
+ "an analytic account."
).format(
line=_format_account_move_line(self),
account=self.account_id.display_name,
diff --git a/account_closing_journal/__manifest__.py b/account_closing_journal/__manifest__.py
index d8191313..79daa149 100644
--- a/account_closing_journal/__manifest__.py
+++ b/account_closing_journal/__manifest__.py
@@ -10,7 +10,9 @@
"license": "LGPL-3",
"category": "Accounting",
"summary": "Allow to define a fiscal year closing journal",
- "depends": ["account",],
+ "depends": [
+ "account",
+ ],
"data": [
"views/account_journal.xml",
"views/account_move.xml",
diff --git a/account_closing_journal_mis_builder/__manifest__.py b/account_closing_journal_mis_builder/__manifest__.py
index 8b860e0c..0ab6ed54 100644
--- a/account_closing_journal_mis_builder/__manifest__.py
+++ b/account_closing_journal_mis_builder/__manifest__.py
@@ -14,7 +14,9 @@
# OCA/mis-builder
"mis_builder",
],
- "data": ["views/mis_report.xml",],
+ "data": [
+ "views/mis_report.xml",
+ ],
"installable": True,
"auto_install": True,
}
diff --git a/account_closing_wizard/__manifest__.py b/account_closing_wizard/__manifest__.py
index de63e595..e68df428 100644
--- a/account_closing_wizard/__manifest__.py
+++ b/account_closing_wizard/__manifest__.py
@@ -10,7 +10,10 @@
"license": "LGPL-3",
"category": "Accounting",
"summary": "Add a wizard to close an accounting exercise",
- "depends": ["account_closing_journal", "date_range",],
+ "depends": [
+ "account_closing_journal",
+ "date_range",
+ ],
"data": [
"security/ir.model.access.csv",
"views/account_account.xml",
diff --git a/account_closing_wizard/wizard/account_closing_wizard.py b/account_closing_wizard/wizard/account_closing_wizard.py
index 5a63cab2..26c41554 100644
--- a/account_closing_wizard/wizard/account_closing_wizard.py
+++ b/account_closing_wizard/wizard/account_closing_wizard.py
@@ -27,9 +27,12 @@ class AccountClosingWizard(models.TransientModel):
move_id = fields.Many2one("account.move")
def _check_draft_account_move_in_period(self):
- domain = [("state", "=", "draft"), ("move_type", "=", "entry"),
- ("company_id", "=", self.env.company.id),
- ("date", "<=", self.date_to)]
+ domain = [
+ ("state", "=", "draft"),
+ ("move_type", "=", "entry"),
+ ("company_id", "=", self.env.company.id),
+ ("date", "<=", self.date_to),
+ ]
account_ids = self.env["account.move"].search(domain)
if account_ids:
raise ValidationError(
@@ -65,7 +68,7 @@ def _make_account_move(self):
income_lines = self._prepare_income_lines()
earnings_line = self._prepare_earnings_line()
- balance = sum(l["debit"] - l["credit"] for l in income_lines)
+ balance = sum(line["debit"] - line["credit"] for line in income_lines)
earnings_line["debit"] = -balance if balance < 0 else 0
earnings_line["credit"] = balance if balance > 0 else 0
@@ -87,7 +90,8 @@ def _get_account_move_ref(self):
date_from = self.date_from.strftime(DATE_FORMAT)
date_to = self.date_to.strftime(DATE_FORMAT)
return _("Period closing from {date_from} to {date_to}").format(
- date_from=date_from, date_to=date_to,
+ date_from=date_from,
+ date_to=date_to,
)
def _prepare_earnings_line(self):
@@ -110,7 +114,9 @@ def _get_earnings_account(self):
_(
"No account defined under company {company} "
"as the default account for retained earnings."
- ).format(company=self.company_id.display_name,)
+ ).format(
+ company=self.company_id.display_name,
+ )
)
return account
@@ -120,7 +126,7 @@ def _prepare_income_lines(self):
self._prepare_income_line(account)
for account in self._get_income_accounts()
)
- return [l for l in lines if l["debit"] or l["credit"]]
+ return [line for line in lines if line["debit"] or line["credit"]]
def _prepare_income_line(self, account):
balance = self._get_account_balance(account)
diff --git a/account_fr_ca_labels/models.py b/account_fr_ca_labels/models.py
index 18f95a33..fd362d21 100644
--- a/account_fr_ca_labels/models.py
+++ b/account_fr_ca_labels/models.py
@@ -2,26 +2,26 @@
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
import logging
-from odoo import api, models
+from odoo import models
_logger = logging.getLogger(__name__)
ENGLISH_CREDIT_NOTE_TERMS = [
- 'credit note',
- 'credit notes',
- 'Credit Note',
- 'Credit Notes',
- 'Credit note',
- 'Credit notes',
- 'refund',
- 'Refund',
+ "credit note",
+ "credit notes",
+ "Credit Note",
+ "Credit Notes",
+ "Credit note",
+ "Credit notes",
+ "refund",
+ "Refund",
]
class IrTranslation(models.Model):
- _inherit = 'ir.translation'
+ _inherit = "ir.translation"
def _load_module_terms(self, modules, langs, overwrite=False):
result = super()._load_module_terms(modules, langs, overwrite)
@@ -36,7 +36,7 @@ def _update_fr_ca_terms(self):
def _update_credit_note_translations(env):
- u"""Update the term `Avoir` to `Note de crédit`.
+ """Update the term `Avoir` to `Note de crédit`.
The term `Avoir` and all its derivatives (avoir, avoirs, l'avoir, d'avoir)
must not always be updated to `Note de crédit`.
@@ -52,7 +52,6 @@ def _update_credit_note_translations(env):
"""
mapping = [
("Facture de l'avoir", "Note de crédit"),
-
("l'avoir", "la note de crédit"),
("L'avoir", "La note de crédit"),
("d'avoirs", "de notes de crédit"),
@@ -64,21 +63,24 @@ def _update_credit_note_translations(env):
("le prochain avoir", "la prochaine note de crédit"),
("avoir", "note de crédit"),
("Avoir", "Note de crédit"),
-
# Grammatical errors
("Note de crédits", "Notes de crédit"),
("note de crédits", "notes de crédit"),
]
for source, destination in mapping:
translations = _find_translations_term_with_value(env, source)
+ # Fixing it not using lambda function:
+ # lambda t: _translation_contains_credit_note(t)
+ # Use instead _translation_contains_credit_note. It is the same.
credit_note_translations = translations.filtered(
- lambda t: _translation_contains_credit_note(t))
+ _translation_contains_credit_note
+ )
for translation in credit_note_translations:
_replace_term_in_translation(translation, source, destination)
def _update_aged_balance_translations(env):
- u"""Update the term `Balance âgée` to `Âge des comptes`."""
+ """Update the term `Balance âgée` to `Âge des comptes`."""
mapping = [
("Balance agée des clients", "Âge des comptes clients"),
("Balance agée des fournisseurs", "Âge des comptes fournisseurs"),
@@ -90,10 +92,9 @@ def _update_aged_balance_translations(env):
def _update_reconciliation_translations(env):
- u"""Update the term `Lettrage` to `Conciliation`."""
+ """Update the term `Lettrage` to `Conciliation`."""
mapping = [
("Modèles de lettrage", "Modèles de conciliation bancaire"),
-
("de lettrage", "de conciliation"),
("du lettrage", "de la conciliation"),
("le lettrage", "la conciliation"),
@@ -101,9 +102,8 @@ def _update_reconciliation_translations(env):
("Lettrer", "Réconcilier"),
("lettrer", "réconcilier"),
("Lettrage", "Conciliation"),
-
# Grammatical errors
- ("annuler le lettrage l'entrée", "annuler la conciliation")
+ ("annuler le lettrage l'entrée", "annuler la conciliation"),
]
_replace_terms(env, mapping)
@@ -144,23 +144,25 @@ def _find_translations_term_with_value(env, value):
)
AND value like %s
""",
- ('ir.%', '%{}%'.format(value), )
+ (
+ "ir.%",
+ "%{}%".format(value),
+ ),
)
translation_ids = [r[0] for r in env.cr.fetchall()]
- return env['ir.translation'].browse(translation_ids)
+ return env["ir.translation"].browse(translation_ids)
def _translation_contains_credit_note(translation):
"""Evaluate whether the source of the translation contains `credit note`."""
- return any(
- source in translation.src
- for source in ENGLISH_CREDIT_NOTE_TERMS
- )
+ return any(source in translation.src for source in ENGLISH_CREDIT_NOTE_TERMS)
def _replace_term_in_translation(translation, source, dest):
- _logger.info((
- "Replacing the term '{source}' with '{dest}' for the french translation "
- "'{value}'."
- ).format(source=source, dest=dest, value=translation.value))
+ _logger.info(
+ (
+ "Replacing the term '{source}' with '{dest}' for the french translation "
+ "'{value}'."
+ ).format(source=source, dest=dest, value=translation.value)
+ )
translation.value = translation.value.replace(source, dest)
diff --git a/account_invoice_constraint_chronology_forced/i18n/fr.po b/account_invoice_constraint_chronology_forced/i18n/fr.po
index 156862e4..509461aa 100644
--- a/account_invoice_constraint_chronology_forced/i18n/fr.po
+++ b/account_invoice_constraint_chronology_forced/i18n/fr.po
@@ -50,8 +50,8 @@ msgstr ""
#: code:addons/account_invoice_constraint_chronology_forced/models/account_journal.py:0
#, python-format
msgid ""
-"You cannot change the Type of the Journal because there is At Least One "
-"Account Move linked to the Journal."
+"You cannot change the Type of the Journal because there is "
+"At Least One Account Move linked to the Journal."
msgstr ""
"Vous ne pouvez pas modifier le type du journal car au moins "
"une pièce comptable est associée au journal."
diff --git a/account_invoice_constraint_chronology_forced/models/account_journal.py b/account_invoice_constraint_chronology_forced/models/account_journal.py
index 1bda9323..89b0338f 100644
--- a/account_invoice_constraint_chronology_forced/models/account_journal.py
+++ b/account_invoice_constraint_chronology_forced/models/account_journal.py
@@ -22,8 +22,8 @@ def _onchange_type(self):
if moves_count > 0:
raise UserError(
_(
- "You cannot change the Type of the Journal because there is At Least One "
- "Account Move linked to the Journal."
+ "You cannot change the Type of the Journal because there is "
+ "At Least One Account Move linked to the Journal."
)
)
diff --git a/account_move_reversal_access/__manifest__.py b/account_move_reversal_access/__manifest__.py
index b3b4ef04..13c04391 100644
--- a/account_move_reversal_access/__manifest__.py
+++ b/account_move_reversal_access/__manifest__.py
@@ -3,7 +3,10 @@
{
"name": "Account Move Reversal Access",
- "summary": "Restricting access to the function of reversing Journal Entries and resetting to draft ().",
+ "summary": """
+ Restricting access to the function of reversing Journal
+ Entries and resetting to draft ().
+ """,
"version": "14.0.2.0.0",
"website": "https://bit.ly/numigi-com",
"author": "Numigi",
diff --git a/account_move_reversed_entry/tests/test_account_move.py b/account_move_reversed_entry/tests/test_account_move.py
index 714b7d3c..37c027f5 100644
--- a/account_move_reversed_entry/tests/test_account_move.py
+++ b/account_move_reversed_entry/tests/test_account_move.py
@@ -2,7 +2,6 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields
-from odoo.exceptions import UserError
from odoo.tests import common
diff --git a/account_move_unique_reversal/i18n/fr.po b/account_move_unique_reversal/i18n/fr.po
index 91b52a2c..8b140fc9 100644
--- a/account_move_unique_reversal/i18n/fr.po
+++ b/account_move_unique_reversal/i18n/fr.po
@@ -27,7 +27,7 @@ msgid "The accounting entry {} is already reversed (by entry {}). You can only r
msgstr "La pièce comptable {} est déjà renversée (pièce {}). Vous ne pouvez renverser une pièce qu’une seule fois."
#. module: account_move_unique_reversal
-#: code:addons/account_move_unique_reversal/models/account_move_reversal.py:26
+#: code:addons/account_move_unique_reversal/models/account_move_reversal.py:28
#, python-format
msgid "The accounting entry {} is the reversal of another entry ({}). You can not reverse a reversal accounting entry."
msgstr "La pièce comptable {} est le renversement d’une autre pièce comptable ({}). Vous ne pouvez pas renverser une pièce comptable qui est le renversement d’une autre pièce."
diff --git a/account_move_unique_reversal/models/account_move.py b/account_move_unique_reversal/models/account_move.py
index 5b79c968..7aa78a19 100644
--- a/account_move_unique_reversal/models/account_move.py
+++ b/account_move_unique_reversal/models/account_move.py
@@ -1,7 +1,7 @@
# © 2021 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-from odoo import _, api, fields, models
+from odoo import _, models
from odoo.exceptions import UserError
@@ -11,21 +11,23 @@ class AccountMove(models.Model):
def _reverse_moves(self, default_values_list=None, cancel=False):
for move in self:
if move.reversal_move_id and move.journal_id.type not in (
- 'sale', 'purchase'):
+ "sale",
+ "purchase",
+ ):
raise UserError(
_(
"The accounting entry {} is already reversed (by entry {}). "
"You can only reverse an accounting entry once."
- ).format(move.display_name,
- move.reversal_move_id.display_name)
+ ).format(move.display_name, move.reversal_move_id.display_name)
)
if move.reversed_entry_id and move.journal_id.type not in (
- 'sale', 'purchase'):
+ "sale",
+ "purchase",
+ ):
raise UserError(
_(
"The accounting entry {} is the reversal of another entry "
"({}). You can not reverse a reversal accounting entry."
- ).format(move.display_name,
- move.reversed_entry_id.display_name)
+ ).format(move.display_name, move.reversed_entry_id.display_name)
)
return super()._reverse_moves(default_values_list, cancel)
diff --git a/account_negative_debit_credit/tests/test_account_move_line.py b/account_negative_debit_credit/tests/test_account_move_line.py
index 95ba8e97..32c16c11 100644
--- a/account_negative_debit_credit/tests/test_account_move_line.py
+++ b/account_negative_debit_credit/tests/test_account_move_line.py
@@ -44,30 +44,78 @@ def _get_asset_line(self, move):
return move.line_ids.filtered(lambda l: l.account_id == self.asset)
def test_negative_debit(self):
- move = self._create_move([
- (0, 0, {"account_id": self.expense.id, "debit": -10,}),
- (0, 0, {"account_id": self.asset.id, "debit": 10,}),
- ])
+ move = self._create_move(
+ [
+ (
+ 0,
+ 0,
+ {
+ "account_id": self.expense.id,
+ "debit": -10,
+ },
+ ),
+ (
+ 0,
+ 0,
+ {
+ "account_id": self.asset.id,
+ "debit": 10,
+ },
+ ),
+ ]
+ )
line = move.line_ids[0]
assert line.debit == 0
assert line.credit == 10
def test_negative_credit(self):
- move = self._create_move([
- (0, 0, {"account_id": self.expense.id, "credit": 10,}),
- (0, 0, {"account_id": self.asset.id, "credit": -10,}),
- ])
+ move = self._create_move(
+ [
+ (
+ 0,
+ 0,
+ {
+ "account_id": self.expense.id,
+ "credit": 10,
+ },
+ ),
+ (
+ 0,
+ 0,
+ {
+ "account_id": self.asset.id,
+ "credit": -10,
+ },
+ ),
+ ]
+ )
line = move.line_ids[1]
assert line.debit == 10
assert line.credit == 0
def test_negative_debit_and_credit(self):
- move = self._create_move([
- (0, 0, {"account_id": self.expense.id, "credit": 10,}),
- (0, 0, {"account_id": self.asset.id, "credit": -10,}),
- ])
+ move = self._create_move(
+ [
+ (
+ 0,
+ 0,
+ {
+ "account_id": self.expense.id,
+ "credit": 10,
+ },
+ ),
+ (
+ 0,
+ 0,
+ {
+ "account_id": self.asset.id,
+ "credit": -10,
+ },
+ ),
+ ]
+ )
expense_line = move.line_ids[0]
assert expense_line.debit == 0
@@ -78,10 +126,26 @@ def test_negative_debit_and_credit(self):
assert asset_line.credit == 0
def test_write(self):
- move = self._create_move([
- (0, 0, {"account_id": self.expense.id, "debit": 10,}),
- (0, 0, {"account_id": self.asset.id, "credit": 10,}),
- ])
+ move = self._create_move(
+ [
+ (
+ 0,
+ 0,
+ {
+ "account_id": self.expense.id,
+ "debit": 10,
+ },
+ ),
+ (
+ 0,
+ 0,
+ {
+ "account_id": self.asset.id,
+ "credit": 10,
+ },
+ ),
+ ]
+ )
move.write(
{
"line_ids": [
diff --git a/account_payment_cancel_group/__manifest__.py b/account_payment_cancel_group/__manifest__.py
index 4fd97246..a3a94bfa 100644
--- a/account_payment_cancel_group/__manifest__.py
+++ b/account_payment_cancel_group/__manifest__.py
@@ -10,7 +10,12 @@
"license": "LGPL-3",
"category": "Accounting",
"summary": "Add a user group allowed to cancel payments",
- "depends": ["account",],
- "data": ["security/res_groups.xml", "views/account_payment.xml",],
+ "depends": [
+ "account",
+ ],
+ "data": [
+ "security/res_groups.xml",
+ "views/account_payment.xml",
+ ],
"installable": True,
}
diff --git a/account_payment_cancel_group/models/account_move.py b/account_payment_cancel_group/models/account_move.py
index 069d9d8a..12bda1a0 100644
--- a/account_payment_cancel_group/models/account_move.py
+++ b/account_payment_cancel_group/models/account_move.py
@@ -1,7 +1,7 @@
# © 2019 Numigi
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-from odoo import api, models, _
+from odoo import models, _
from odoo.exceptions import AccessError
@@ -19,7 +19,9 @@ def button_cancel(self):
def _check_payment_cancel_authorization(self):
if self._contains_payments() and not self._user_can_cancel_payments():
- raise AccessError(_("You are not authorized to reset to draft or cancel payments."))
+ raise AccessError(
+ _("You are not authorized to reset to draft or cancel payments.")
+ )
def _user_can_cancel_payments(self):
return self.env.user.has_group(
diff --git a/account_payment_cancel_group/tests/test_payment_cancel.py b/account_payment_cancel_group/tests/test_payment_cancel.py
index 0830c278..6cd02a89 100644
--- a/account_payment_cancel_group/tests/test_payment_cancel.py
+++ b/account_payment_cancel_group/tests/test_payment_cancel.py
@@ -11,30 +11,38 @@ class TestPaymentCancel(common.SavepointCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
- cls.user = cls.env['res.users'].create({
- 'name': 'Test User',
- 'email': 'test@test.com',
- 'login': 'test@test.com',
- 'groups_id': [
- (4, cls.env.ref('account.group_account_manager').id),
- ]
- })
-
- cls.journal = cls.env['account.journal'].create({
- 'name': 'Test Bank Journal',
- 'type': 'bank',
- 'code': 'TEST',
- })
-
- cls.supplier = cls.env['res.partner'].create({'name': 'Supplier'})
- cls.payment = cls.env['account.payment'].create({
- 'journal_id': cls.journal.id,
- 'partner_id': cls.supplier.id,
- 'amount': 100,
- 'payment_type': 'outbound',
- 'payment_method_id': cls.env.ref('account.account_payment_method_manual_out').id,
- 'partner_type': 'supplier',
- })
+ cls.user = cls.env["res.users"].create(
+ {
+ "name": "Test User",
+ "email": "test@test.com",
+ "login": "test@test.com",
+ "groups_id": [
+ (4, cls.env.ref("account.group_account_manager").id),
+ ],
+ }
+ )
+
+ cls.journal = cls.env["account.journal"].create(
+ {
+ "name": "Test Bank Journal",
+ "type": "bank",
+ "code": "TEST",
+ }
+ )
+
+ cls.supplier = cls.env["res.partner"].create({"name": "Supplier"})
+ cls.payment = cls.env["account.payment"].create(
+ {
+ "journal_id": cls.journal.id,
+ "partner_id": cls.supplier.id,
+ "amount": 100,
+ "payment_type": "outbound",
+ "payment_method_id": cls.env.ref(
+ "account.account_payment_method_manual_out"
+ ).id,
+ "partner_type": "supplier",
+ }
+ )
def test_if_not_member_of_group__action_draft_not_allowed(self):
with pytest.raises(AccessError):
@@ -45,11 +53,13 @@ def test_if_not_member_of_group__action_cancel_not_allowed(self):
self.payment.sudo(self.user).action_cancel()
def test_if_member_of_group__user_allowed(self):
- self.user.groups_id |= self.env.ref('account_payment_cancel_group.group_cancel_payments')
+ self.user.groups_id |= self.env.ref(
+ "account_payment_cancel_group.group_cancel_payments"
+ )
self.payment.sudo(self.user).action_draft()
- assert self.payment.state == 'draft'
+ assert self.payment.state == "draft"
self.payment.sudo(self.user).action_cancel()
- assert self.payment.state == 'cancel'
+ assert self.payment.state == "cancel"
def test_call_method_with_empty_recordset(self):
self.env["account.payment"].sudo(self.user).action_draft()
diff --git a/account_payment_term_usage/models/__init__.py b/account_payment_term_usage/models/__init__.py
index 4f4995b4..856e377e 100644
--- a/account_payment_term_usage/models/__init__.py
+++ b/account_payment_term_usage/models/__init__.py
@@ -2,6 +2,6 @@
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
from . import (
- account_move,
+ account_move,
account_payment_term,
)
diff --git a/account_payment_term_usage/models/account_move.py b/account_payment_term_usage/models/account_move.py
index e9a5f330..5aaa2631 100644
--- a/account_payment_term_usage/models/account_move.py
+++ b/account_payment_term_usage/models/account_move.py
@@ -9,7 +9,10 @@ class AccountMove(models.Model):
_inherit = "account.move"
payment_term_usage = fields.Selection(
- [("sale", "Sales"), ("purchase", "Purchases"),],
+ [
+ ("sale", "Sales"),
+ ("purchase", "Purchases"),
+ ],
compute="_compute_payment_term_usage",
)
diff --git a/account_payment_term_usage/tests/test_account_move.py b/account_payment_term_usage/tests/test_account_move.py
index bdfa4703..c754f477 100644
--- a/account_payment_term_usage/tests/test_account_move.py
+++ b/account_payment_term_usage/tests/test_account_move.py
@@ -1,11 +1,8 @@
# © 2021 - today Numigi
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-import pytest
-from ddt import ddt, data, unpack
-from datetime import datetime, timedelta
+from ddt import ddt
from odoo.tests.common import SavepointCase
-from odoo.exceptions import ValidationError
@ddt
@@ -14,7 +11,11 @@ class TestAccountMove(SavepointCase):
def setUpClass(cls):
super().setUpClass()
cls.journal = cls.env["account.journal"].create(
- {"name": "Journal", "type": "purchase", "code": "SAJ",}
+ {
+ "name": "Journal",
+ "type": "purchase",
+ "code": "SAJ",
+ }
)
cls.partner = cls.env["res.partner"].create({"name": "Partner"})
cls.invoice = cls.env["account.move"].create(
diff --git a/account_payment_widget_link/tests/__init__.py b/account_payment_widget_link/tests/__init__.py
index b67e645c..d36fa2b3 100644
--- a/account_payment_widget_link/tests/__init__.py
+++ b/account_payment_widget_link/tests/__init__.py
@@ -2,4 +2,3 @@
# License LGPL-3.0 or later (http://www.gnu.org/licenses/LGPL.html).
from . import test_account_move_line
-
diff --git a/account_report_trial_balance/controller/print_report.py b/account_report_trial_balance/controller/print_report.py
index 1ee66f23..0caf702c 100644
--- a/account_report_trial_balance/controller/print_report.py
+++ b/account_report_trial_balance/controller/print_report.py
@@ -1,22 +1,25 @@
# © 2021 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-import json
from odoo import http
from odoo.http import request
class PrintGeneralLedger(http.Controller):
- @http.route('/web/account_report_trial_balance/', type='http', auth='user')
+ @http.route(
+ "/web/account_report_trial_balance/", type="http", auth="user"
+ )
def account_report_trial_balance_pdf(self, report_id, token):
- output_pdf = request.env['account.report.trial.balance'].browse(report_id).get_pdf()
+ output_pdf = (
+ request.env["account.report.trial.balance"].browse(report_id).get_pdf()
+ )
response = request.make_response(
output_pdf,
headers=[
- ('Content-Type', 'application/pdf'),
- ('Content-Disposition', 'attachment; filename=trial_balance.pdf;')
- ]
+ ("Content-Type", "application/pdf"),
+ ("Content-Disposition", "attachment; filename=trial_balance.pdf;"),
+ ],
)
- response.set_cookie('fileToken', token)
+ response.set_cookie("fileToken", token)
return response
diff --git a/account_type_sane/__manifest__.py b/account_type_sane/__manifest__.py
index ef4b1af6..3d809429 100644
--- a/account_type_sane/__manifest__.py
+++ b/account_type_sane/__manifest__.py
@@ -10,7 +10,9 @@
"license": "LGPL-3",
"category": "Accounting",
"summary": "Make the account types more user friendly",
- "depends": ["account",],
+ "depends": [
+ "account",
+ ],
"data": [
"views/menu.xml",
"views/account_account.xml",
diff --git a/bank_statement_import_csv/error.py b/bank_statement_import_csv/error.py
index 831da773..f229a88b 100644
--- a/bank_statement_import_csv/error.py
+++ b/bank_statement_import_csv/error.py
@@ -11,6 +11,5 @@ class BankStatementError:
kwargs: dict = field(default_factory=lambda: {})
-
def is_bank_statement_error(value):
return isinstance(value, BankStatementError)
diff --git a/bank_statement_import_csv/loader.py b/bank_statement_import_csv/loader.py
index ee930984..b9e04a0e 100644
--- a/bank_statement_import_csv/loader.py
+++ b/bank_statement_import_csv/loader.py
@@ -158,9 +158,9 @@ def _get_currency_amount(self, row):
currency_amount = self._get_cell_decimal(row, self._currency_amount_index)
if (
- isinstance(amount, Decimal) and
- isinstance(currency_amount, Decimal) and
- _not_same_sign(amount, currency_amount)
+ isinstance(amount, Decimal)
+ and isinstance(currency_amount, Decimal)
+ and _not_same_sign(amount, currency_amount)
):
currency_amount *= -1
@@ -184,7 +184,7 @@ def _get_cell(self, row, index):
def _iter_rows(self, file):
reader = csv.reader(file, delimiter=self._delimiter, quotechar=self._quotechar)
- for i in range(self._first_row_index):
+ for __ in range(self._first_row_index):
next(reader, None)
for row in reader:
diff --git a/bank_statement_import_csv/models/account_journal.py b/bank_statement_import_csv/models/account_journal.py
index 8d30a767..1ebc4a04 100644
--- a/bank_statement_import_csv/models/account_journal.py
+++ b/bank_statement_import_csv/models/account_journal.py
@@ -1,7 +1,7 @@
# © 2022 - Numigi (tm) and all its contributors (https://bit.ly/numigiens)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-from odoo import api, fields, models
+from odoo import fields, models
class AccountJournal(models.Model):
diff --git a/bank_statement_import_csv/models/bank_statement_import_config.py b/bank_statement_import_csv/models/bank_statement_import_config.py
index da92e9aa..94b3c2fe 100644
--- a/bank_statement_import_csv/models/bank_statement_import_config.py
+++ b/bank_statement_import_csv/models/bank_statement_import_config.py
@@ -1,7 +1,7 @@
# © 2022 - Numigi (tm) and all its contributors (https://bit.ly/numigiens)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-from odoo import api, fields, models
+from odoo import fields, models
class BankStatementImportConfig(models.Model):
@@ -13,8 +13,7 @@ class BankStatementImportConfig(models.Model):
active = fields.Boolean(default=True)
first_row = fields.Integer(
- default=2,
- help="The position of the first transaction line in the file."
+ default=2, help="The position of the first transaction line in the file."
)
reversed_order = fields.Boolean(
help="Check this box is the lines in the csv files are ordered "
@@ -75,46 +74,62 @@ def get_csv_loader_config(self):
"description": {
"index": self.description_column - 1,
},
- "reference": {
- "index": self.reference_column - 1,
- }
- if self.reference_enabled
- else None,
- "partner_name": {
- "index": self.partner_name_column - 1,
- }
- if self.partner_name_enabled
- else None,
- "withdraw": {
- "index": self.withdraw_column - 1,
- "reverse": self.reverse_withdraw,
- }
- if self.withdraw_deposit_enabled
- else None,
- "deposit": {
- "index": self.deposit_column - 1,
- "reverse": self.reverse_deposit,
- }
- if self.withdraw_deposit_enabled
- else None,
- "amount": {
- "index": self.amount_column - 1,
- }
- if not self.withdraw_deposit_enabled
- else None,
- "balance": {
- "index": self.balance_column - 1,
- }
- if self.balance_enabled
- else None,
- "currency": {
- "index": self.currency_column - 1,
- }
- if self.currency_amount_enabled
- else None,
- "currency_amount": {
- "index": self.currency_amount_column - 1,
- }
- if self.currency_amount_enabled
- else None,
+ "reference": (
+ {
+ "index": self.reference_column - 1,
+ }
+ if self.reference_enabled
+ else None
+ ),
+ "partner_name": (
+ {
+ "index": self.partner_name_column - 1,
+ }
+ if self.partner_name_enabled
+ else None
+ ),
+ "withdraw": (
+ {
+ "index": self.withdraw_column - 1,
+ "reverse": self.reverse_withdraw,
+ }
+ if self.withdraw_deposit_enabled
+ else None
+ ),
+ "deposit": (
+ {
+ "index": self.deposit_column - 1,
+ "reverse": self.reverse_deposit,
+ }
+ if self.withdraw_deposit_enabled
+ else None
+ ),
+ "amount": (
+ {
+ "index": self.amount_column - 1,
+ }
+ if not self.withdraw_deposit_enabled
+ else None
+ ),
+ "balance": (
+ {
+ "index": self.balance_column - 1,
+ }
+ if self.balance_enabled
+ else None
+ ),
+ "currency": (
+ {
+ "index": self.currency_column - 1,
+ }
+ if self.currency_amount_enabled
+ else None
+ ),
+ "currency_amount": (
+ {
+ "index": self.currency_amount_column - 1,
+ }
+ if self.currency_amount_enabled
+ else None
+ ),
}
diff --git a/bank_statement_import_csv/wizard/bank_statement_import_wizard.py b/bank_statement_import_csv/wizard/bank_statement_import_wizard.py
index 0b5a5c13..8c9e0a2d 100644
--- a/bank_statement_import_csv/wizard/bank_statement_import_wizard.py
+++ b/bank_statement_import_csv/wizard/bank_statement_import_wizard.py
@@ -1,7 +1,6 @@
# © 2022 - Numigi (tm) and all its contributors (https://bit.ly/numigiens)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-import json
from base64 import b64decode
from io import StringIO
from odoo import api, fields, models, _
@@ -16,8 +15,7 @@ class BankStatementImportWizard(models.TransientModel):
_description = "Bank Statement Import Wizard"
journal_id = fields.Many2one(
- "account.journal",
- default=lambda self: self._context.get("journal_id")
+ "account.journal", default=lambda self: self._context.get("journal_id")
)
config_id = fields.Many2one("bank.statement.import.config", required=True)
@@ -52,7 +50,7 @@ def _compute_show_fields(self):
@api.depends("line_ids")
def _compute_has_error(self):
for wizard in self:
- wizard.has_error = any(l.has_error for l in self.line_ids)
+ wizard.has_error = any(line.has_error for line in self.line_ids)
@api.depends("line_ids", "has_error")
def _compute_is_ready(self):
@@ -144,4 +142,4 @@ def _get_first_and_last_line(self):
def _get_statement_line_vals(self):
lines = self.line_ids
- return [(0, 0, l._get_statement_line_vals()) for l in lines]
+ return [(0, 0, line._get_statement_line_vals()) for line in lines]
diff --git a/bank_statement_no_reverse/models/account_move.py b/bank_statement_no_reverse/models/account_move.py
index 6cd8054f..7f213400 100644
--- a/bank_statement_no_reverse/models/account_move.py
+++ b/bank_statement_no_reverse/models/account_move.py
@@ -1,7 +1,7 @@
# © 2021 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-from odoo import api, models, _
+from odoo import models, _
from odoo.exceptions import ValidationError
diff --git a/bank_statement_online_stripe/tests/test_online_bank_statement_provider.py b/bank_statement_online_stripe/tests/test_online_bank_statement_provider.py
index 78c4129f..48d28eb1 100644
--- a/bank_statement_online_stripe/tests/test_online_bank_statement_provider.py
+++ b/bank_statement_online_stripe/tests/test_online_bank_statement_provider.py
@@ -9,7 +9,6 @@
from odoo.tests import common
from odoo.exceptions import ValidationError
from unittest.mock import patch
-from ..interface import BalanceTransactionInterface
class TestStripe(common.SavepointCase):
@@ -98,13 +97,13 @@ def test_map_fee(self):
def test_no_partner_email(self):
self.transaction["source"]["billing_details"]["email"] = None
vals = self.provider._map_stripe_transaction(self.transaction)
- assert vals["partner_id"] == None
+ self.assertIsNone(vals["partner_id"])
assert vals["partner_name"] == self.partner_name
def test_partner_not_found(self):
self.partner.email = "different.email@example.com"
vals = self.provider._map_stripe_transaction(self.transaction)
- assert vals["partner_id"] == None
+ self.assertIsNone(vals["partner_id"])
def test_obtain_statement_data(self):
with self._mock_balance_transaction_list(), self._mock_balance(3000):
diff --git a/bank_statement_partner_name/__manifest__.py b/bank_statement_partner_name/__manifest__.py
index 463acd68..c953ef6a 100644
--- a/bank_statement_partner_name/__manifest__.py
+++ b/bank_statement_partner_name/__manifest__.py
@@ -11,6 +11,8 @@
"category": "Accounting",
"summary": "Add the partner name to bank statement lines",
"depends": ["account"],
- "data": ["views/bank_statement.xml",],
+ "data": [
+ "views/bank_statement.xml",
+ ],
"installable": True,
}
diff --git a/canada_bank_transfer/change_payment_date.py b/canada_bank_transfer/change_payment_date.py
index fb28e38c..3c8d3fff 100644
--- a/canada_bank_transfer/change_payment_date.py
+++ b/canada_bank_transfer/change_payment_date.py
@@ -1,8 +1,6 @@
# © 2019 Numigi
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-from datetime import date
-
def change_payment_date(payment, new_date):
"""Change the date of the payment to the given date.
@@ -14,11 +12,13 @@ def change_payment_date(payment, new_date):
Super user priviledges are used to prevent access right errors.
"""
payment_sudo = payment.sudo()
- account_move = payment_sudo.mapped('move_id')
- account_move.write({
- 'state': 'draft',
- 'date': new_date,
- })
- account_move.line_ids.write({'date_maturity': new_date})
- account_move.state = 'posted'
+ account_move = payment_sudo.mapped("move_id")
+ account_move.write(
+ {
+ "state": "draft",
+ "date": new_date,
+ }
+ )
+ account_move.line_ids.write({"date_maturity": new_date})
+ account_move.state = "posted"
payment_sudo.date = new_date
diff --git a/canada_bank_transfer/models/account_journal.py b/canada_bank_transfer/models/account_journal.py
index d3efbe27..fed946b1 100644
--- a/canada_bank_transfer/models/account_journal.py
+++ b/canada_bank_transfer/models/account_journal.py
@@ -1,8 +1,7 @@
# © 2019 Numigi
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-from odoo import api, fields, models, _
-from odoo.exceptions import ValidationError
+from odoo import api, fields, models
class AccountJournal(models.Model):
@@ -50,8 +49,7 @@ class AccountJournal(models.Model):
eft_sequence_id = fields.Many2one(
"ir.sequence", string="EFT Sequence", ondelete="restrict"
)
- transit_account = fields.Many2one(
- "account.account", string="Transit Account")
+ transit_account = fields.Many2one("account.account", string="Transit Account")
use_transit_account = fields.Boolean(
string="Use a transit Account", compute="_get_use_transit_account"
)
@@ -101,4 +99,5 @@ def _setup_eft_sequence(self):
"number_increment": 1,
"company_id": self.company_id.id,
"implementation": "no_gap",
- })
+ }
+ )
diff --git a/canada_bank_transfer/tests/test_generate_eft.py b/canada_bank_transfer/tests/test_generate_eft.py
index b4393c1f..83c09ad5 100644
--- a/canada_bank_transfer/tests/test_generate_eft.py
+++ b/canada_bank_transfer/tests/test_generate_eft.py
@@ -21,24 +21,30 @@
)
-@pytest.mark.parametrize('number,expected_value', [
- (10, '000001000'),
- (10.23, '000001023'),
- (10.234, '000001023'),
- (10.235, '000001024'),
- (1.49999999, '000000150')
-])
+@pytest.mark.parametrize(
+ "number,expected_value",
+ [
+ (10, "000001000"),
+ (10.23, "000001023"),
+ (10.234, "000001023"),
+ (10.235, "000001024"),
+ (1.49999999, "000000150"),
+ ],
+)
def test_format_payment_amount(number, expected_value):
assert _format_payment_amount(number) == expected_value
-@pytest.mark.parametrize('number,expected_value', [
- (10, '0000000001000'),
- (10.23, '0000000001023'),
- (10.234, '0000000001023'),
- (10.235, '0000000001024'),
- (1.49999999, '0000000000150')
-])
+@pytest.mark.parametrize(
+ "number,expected_value",
+ [
+ (10, "0000000001000"),
+ (10.23, "0000000001023"),
+ (10.234, "0000000001023"),
+ (10.235, "0000000001024"),
+ (1.49999999, "0000000000150"),
+ ],
+)
def test_format_total_amount(number, expected_value):
assert _format_total_amount(number) == expected_value
@@ -48,26 +54,26 @@ class TestFormatEFTHeader(EFTCase):
def test_record_type_is_a(self):
header = format_header(self.journal, 1)
- assert header[0] == 'A'
+ assert header[0] == "A"
def test_sequence_is_always_one(self):
header = format_header(self.journal, 999)
- assert header[1:10] == '000000001'
+ assert header[1:10] == "000000001"
def test_user_number(self):
header = format_header(self.journal, 1)
assert header[10:20] == USER_NUMBER
- @data(False, '123456789')
+ @data(False, "123456789")
def test_invalid_user_number_raises_error(self, wrong_number):
self.journal.eft_user_number = wrong_number
with pytest.raises(ValidationError):
format_header(self.journal, 1)
@data(
- (1, '0001'),
- (999, '0999'),
- (9999, '9999'),
+ (1, "0001"),
+ (999, "0999"),
+ (9999, "9999"),
)
def test_file_number(self, data_):
number, formatted_number = data_
@@ -79,8 +85,8 @@ def test_file_number_above_9999_raises_error(self):
format_header(self.journal, 10000)
@data(
- ('2019-06-30', '019181'),
- ('2020-01-01', '020001'),
+ ("2019-06-30", "019181"),
+ ("2020-01-01", "020001"),
)
def test_format_header_create_date(self, data_):
date, formatted_date = data_
@@ -92,7 +98,7 @@ def test_destination_data_center_code(self):
header = format_header(self.journal, 1)
assert header[30:35] == DESTINATION
- @data(False, '1234', 'abcde')
+ @data(False, "1234", "abcde")
def test_invalid_destination_data_center_code_raises_error(self, wrong_code):
self.journal.eft_destination = wrong_code
with pytest.raises(ValidationError):
@@ -107,12 +113,12 @@ def test_currency_code(self):
assert header[55:58] == "CAD"
def test_if_no_journal_currency_then_company_currency_is_used(self):
- journal = self.journal.copy({'currency_id': False})
+ journal = self.journal.copy({"currency_id": False})
header = format_header(journal, 1)
assert header[55:58] == journal.company_id.currency_id.name
def test_currency_code_with_usd(self):
- self.journal.currency_id = self.env.ref('base.USD')
+ self.journal.currency_id = self.env.ref("base.USD")
header = format_header(self.journal, 1)
assert header[55:58] == "USD"
@@ -137,11 +143,11 @@ def test_record_length(self):
def test_record_type_is_c(self):
record = format_credit_details_group(self.journal, self.payments, 1, 2)
- assert record[0] == 'C'
+ assert record[0] == "C"
@data(
- (2, '000000002'),
- (999, '000000999'),
+ (2, "000000002"),
+ (999, "000000999"),
)
def test_sequence_number(self, data_):
number, formatted_number = data_
@@ -154,51 +160,47 @@ def test_user_number(self):
def test_file_number(self):
record = format_credit_details_group(self.journal, self.payments, 999, 2)
- assert record[20:24] == '0999'
+ assert record[20:24] == "0999"
def test_operation_code(self):
record = format_credit_details_group(self.journal, self.payments, 1, 2)
- assert record[24:27] == '450'
+ assert record[24:27] == "450"
def test_operation_code_is_450_by_default(self):
- self.payments[0].write({'eft_transaction_type': None})
+ self.payments[0].write({"eft_transaction_type": None})
record = format_credit_details_group(self.journal, self.payments, 1, 2)
- assert record[24:27] == '450'
+ assert record[24:27] == "450"
def test_payment_amount(self):
record = format_credit_details_group(self.journal, self.payments, 1, 2)
- assert record[27:37] == '0000011111' # payment 1: 111.11
- assert record[27 + 240:37 + 240] == '0000022222' # payment 2: 222.22
+ assert record[27:37] == "0000011111" # payment 1: 111.11
+ assert record[27 + 240 : 37 + 240] == "0000022222" # payment 2: 222.22
def test_format_header_create_date(self):
- with freeze_time('2019-06-30'):
+ with freeze_time("2019-06-30"):
self.payments[0].move_id.date = datetime.now().date()
record = format_credit_details_group(self.journal, self.payments, 1, 2)
- assert record[37:43] == '019181'
+ assert record[37:43] == "019181"
def test_destination_institution(self):
record = format_credit_details_group(self.journal, self.payments, 1, 2)
- assert record[43:47] == '0004' # '0{institution}'
+ assert record[43:47] == "0004" # '0{institution}'
def test_destination_transit(self):
record = format_credit_details_group(self.journal, self.payments, 1, 2)
- assert record[47:52] == '20002'
+ assert record[47:52] == "20002"
@data(
- ('1234567', '1234567 '),
- ('12345678', '12345678 '),
- ('123456789012', '123456789012'),
+ ("1234567", "1234567 "),
+ ("12345678", "12345678 "),
+ ("123456789012", "123456789012"),
)
def test_destination_account(self, data_):
self.td_account.acc_number = data_[0]
record = format_credit_details_group(self.journal, self.payments, 1, 2)
assert record[52:64] == data_[1]
- @data(
- '1234567 ', # non-digit
- '123456', # too short
- '1234567890123' # too long
- )
+ @data("1234567 ", "123456", "1234567890123") # non-digit # too short # too long
def test_if_account_number_too_short_raise_error(self, wrong_number):
self.td_account.acc_number = wrong_number
with pytest.raises(ValidationError):
@@ -206,51 +208,51 @@ def test_if_account_number_too_short_raise_error(self, wrong_number):
def test_zeros_from_64_to_89(self):
record = format_credit_details_group(self.journal, self.payments, 1, 2)
- assert record[64:89] == '0' * 25
+ assert record[64:89] == "0" * 25
def test_user_short_name(self):
record = format_credit_details_group(self.journal, self.payments, 1, 2)
- assert record[89:104] == 'YOUR COMPANY ' # 15 caracters
+ assert record[89:104] == "YOUR COMPANY " # 15 caracters
def test_accents_are_removed_from_user_short_name(self):
- self.journal.eft_user_short_name = 'Québec Inc. *'
+ self.journal.eft_user_short_name = "Québec Inc. *"
record = format_credit_details_group(self.journal, self.payments, 1, 2)
- assert record[89:104] == 'QUEBEC INC. _ ' # 15 caracters
+ assert record[89:104] == "QUEBEC INC. _ " # 15 caracters
def test_destinator_short_name(self):
record = format_credit_details_group(self.journal, self.payments, 1, 2)
- assert record[104:134] == 'SUPPLIER 1 ' # 30 caracters
+ assert record[104:134] == "SUPPLIER 1 " # 30 caracters
def test_destinator_short_name__uses_commercial_partner_name(self):
self.payments[0].partner_id = self.supplier_contact
self.payments[0].partner_bank_id = self.td_account
record = format_credit_details_group(self.journal, self.payments, 1, 2)
- assert record[104:134] == 'SUPPLIER 1 ' # 30 caracters
+ assert record[104:134] == "SUPPLIER 1 " # 30 caracters
def test_destinator_short_name__uses_acc_holder_name_if_available(self):
self.payments[0].partner_bank_id.acc_holder_name = "Custom Account Holder Name"
record = format_credit_details_group(self.journal, self.payments, 1, 2)
- assert record[104:134] == 'CUSTOM ACCOUNT HOLDER NAME ' # 30 caracters
+ assert record[104:134] == "CUSTOM ACCOUNT HOLDER NAME " # 30 caracters
def test_accents_are_removed_from_destinator_name(self):
- self.td_account.partner_id.name = '12345 Québec Inc. *test*'
+ self.td_account.partner_id.name = "12345 Québec Inc. *test*"
record = format_credit_details_group(self.journal, self.payments, 1, 2)
- assert record[104:134] == '12345 QUEBEC INC. _TEST_ ' # 30 caracters
+ assert record[104:134] == "12345 QUEBEC INC. _TEST_ " # 30 caracters
def test_user_long_name(self):
- self.journal.company_id.name = 'Your Company Inc.'
+ self.journal.company_id.name = "Your Company Inc."
record = format_credit_details_group(self.journal, self.payments, 1, 2)
- assert record[134:164] == 'YOUR COMPANY INC. ' # 30 caracters
+ assert record[134:164] == "YOUR COMPANY INC. " # 30 caracters
def test_specific_user_long_name(self):
- self.journal.eft_user_long_name = 'Specific User Long Name'
+ self.journal.eft_user_long_name = "Specific User Long Name"
record = format_credit_details_group(self.journal, self.payments, 1, 2)
- assert record[134:164] == 'SPECIFIC USER LONG NAME '
+ assert record[134:164] == "SPECIFIC USER LONG NAME "
def test_accents_are_removed_from_user_long_name(self):
- self.journal.company_id.name = 'Your Company Inc. *test*'
+ self.journal.company_id.name = "Your Company Inc. *test*"
record = format_credit_details_group(self.journal, self.payments, 1, 2)
- assert record[134:164] == 'YOUR COMPANY INC. _TEST_ ' # 30 caracters
+ assert record[134:164] == "YOUR COMPANY INC. _TEST_ " # 30 caracters
def test_user_number_at_164(self):
record = format_credit_details_group(self.journal, self.payments, 1, 2)
@@ -259,16 +261,16 @@ def test_user_number_at_164(self):
def test_transaction_reference_number(self):
record = format_credit_details_group(self.journal, self.payments, 1, 2)
reference = record[174:192]
- assert reference.strip() == self.pmt_1.name.replace('/', '_')
+ assert reference.strip() == self.pmt_1.name.replace("/", "_")
- reference_2 = record[174 + 240:192 + 240]
- assert reference_2.strip() == self.pmt_2.name.replace('/', '_')
+ reference_2 = record[174 + 240 : 192 + 240]
+ assert reference_2.strip() == self.pmt_2.name.replace("/", "_")
def test_transaction_reference_number_with_long_payment_name(self):
- self.pmt_1.name = 'SUPP.OUT/2019/1234567'
+ self.pmt_1.name = "SUPP.OUT/2019/1234567"
record = format_credit_details_group(self.journal, self.payments, 1, 2)
reference = record[174:193]
- assert reference == 'PP.OUT_2019_1234567'
+ assert reference == "PP.OUT_2019_1234567"
def test_origin_institution(self):
record = format_credit_details_group(self.journal, self.payments, 1, 2)
@@ -315,24 +317,26 @@ def setUpClass(cls):
cls.pmt_4 = cls.generate_payment(cls.rbc_account, 444.44)
cls.pmt_5 = cls.generate_payment(cls.rbc_account, 555.55)
cls.pmt_6 = cls.generate_payment(cls.rbc_account, 666.66)
- cls.payments = cls.pmt_1 | cls.pmt_2 | cls.pmt_3 | cls.pmt_4 | cls.pmt_5 | cls.pmt_6
+ cls.payments = (
+ cls.pmt_1 | cls.pmt_2 | cls.pmt_3 | cls.pmt_4 | cls.pmt_5 | cls.pmt_6
+ )
def test_record_length(self):
record = format_credit_details_group(self.journal, self.payments, 1, 2)
assert len(record) == 1464
@data(
- (0, '0000011111'),
- (1, '0000022222'),
- (2, '0000033333'),
- (3, '0000044444'),
- (4, '0000055555'),
- (5, '0000066666'),
+ (0, "0000011111"),
+ (1, "0000022222"),
+ (2, "0000033333"),
+ (3, "0000044444"),
+ (4, "0000055555"),
+ (5, "0000066666"),
)
def test_payment_amount(self, data_):
record = format_credit_details_group(self.journal, self.payments, 1, 2)
offset = 240 * data_[0]
- assert record[27 + offset:37 + offset] == data_[1]
+ assert record[27 + offset : 37 + offset] == data_[1]
@ddt
@@ -344,11 +348,11 @@ def test_trailer_length(self):
def test_record_type_is_z(self):
trailer = format_trailer(self.journal, 1, 1, 1, 1)
- assert trailer[0] == 'Z'
+ assert trailer[0] == "Z"
def test_sequence_number(self):
trailer = format_trailer(self.journal, 1, 123, 1, 1)
- assert trailer[1:10] == '000000123'
+ assert trailer[1:10] == "000000123"
def test_user_number(self):
trailer = format_trailer(self.journal, 1, 1, 1, 1)
@@ -379,7 +383,7 @@ class CompleteEFTCase(EFTCase):
@classmethod
def _generate_payments(cls, number_of_payments):
- payments = cls.env['account.payment']
+ payments = cls.env["account.payment"]
for i in range(number_of_payments):
payments |= cls.generate_payment(cls.rbc_account, i + 1)
return payments
@@ -392,19 +396,25 @@ class TestCompleteEFTLength(CompleteEFTCase):
def test_eft_length_with_6_payments_or_less(self, number_of_payments):
payments = self._generate_payments(number_of_payments)
eft = generate_eft(self.journal, payments, 1)
- assert len(eft) == 4394 # 1464 + 1464 + 1464 (header + details + trailer) + 2 \n
+ assert (
+ len(eft) == 4394
+ ) # 1464 + 1464 + 1464 (header + details + trailer) + 2 \n
@data(7, 12)
def test_eft_length_with_7_to_12_payments(self, number_of_payments):
payments = self._generate_payments(number_of_payments)
eft = generate_eft(self.journal, payments, 1)
- assert len(eft) == 5859 # 1464 + 1464 * 2 + 1464 (header + details + trailer) + 3 \n
+ assert (
+ len(eft) == 5859
+ ) # 1464 + 1464 * 2 + 1464 (header + details + trailer) + 3 \n
@data(13, 18)
def test_eft_length_with_13_to_18_payments(self, number_of_payments):
payments = self._generate_payments(number_of_payments)
eft = generate_eft(self.journal, payments, 1)
- assert len(eft) == 7324 # 1464 + 1464 * 3 + 1464 (header + details + trailer) + 4 \n
+ assert (
+ len(eft) == 7324
+ ) # 1464 + 1464 * 3 + 1464 (header + details + trailer) + 4 \n
@ddt
@@ -417,18 +427,24 @@ def setUpClass(cls):
@data(
# (formatted_payment_amount, amount_index_in_file)
- ('0000000100', 1492), # 1492 = 1464 + 1 + 27 (header + \n + 27)
- ('0000000200', 1732), # 1732 = 1492 + 240
- ('0000000500', 2452), # 2452 = 1492 + 240 * 4
- ('0000000600', 2692), # 2692 = 1492 + 240 * 5
- ('0000000700', 2957), # 2957 = 1464 + 1 + 1464 + 1 + 27 (header + \n + group1 + \n + 27)
- ('0000001200', 4157), # 4157 = 2957 + 240 * 5
- ('0000001300', 4422), # 4421 = 1464 * 3 + 3 + 27
- ('0000001800', 5622), # 5622 = 4421 + 240 * 5
- ('0000001900', 5887), # 5887 = 1464 * 4 + 4 + 27
- ('0000002000', 6127), # 6127 = 5887 + 240
+ ("0000000100", 1492), # 1492 = 1464 + 1 + 27 (header + \n + 27)
+ ("0000000200", 1732), # 1732 = 1492 + 240
+ ("0000000500", 2452), # 2452 = 1492 + 240 * 4
+ ("0000000600", 2692), # 2692 = 1492 + 240 * 5
+ (
+ "0000000700",
+ 2957,
+ ), # 2957 = 1464 + 1 + 1464 + 1 + 27 (header + \n + group1 + \n + 27)
+ ("0000001200", 4157), # 4157 = 2957 + 240 * 5
+ ("0000001300", 4422), # 4421 = 1464 * 3 + 3 + 27
+ ("0000001800", 5622), # 5622 = 4421 + 240 * 5
+ ("0000001900", 5887), # 5887 = 1464 * 4 + 4 + 27
+ ("0000002000", 6127), # 6127 = 5887 + 240
)
def test_payments_order(self, data_):
formatted_payment_amount, amount_index_in_file = data_
eft = generate_eft(self.journal, self.payments, 1)
- assert eft[amount_index_in_file:amount_index_in_file + 10] == formatted_payment_amount
+ assert (
+ eft[amount_index_in_file : amount_index_in_file + 10]
+ == formatted_payment_amount
+ )
diff --git a/canada_bank_transfer/wizard/eft_confirmation.py b/canada_bank_transfer/wizard/eft_confirmation.py
index 6ffa4ddf..da771f19 100644
--- a/canada_bank_transfer/wizard/eft_confirmation.py
+++ b/canada_bank_transfer/wizard/eft_confirmation.py
@@ -8,11 +8,11 @@
class EFTConfirmationWizard(models.TransientModel):
- _name = 'account.eft.confirmation.wizard'
- _description = 'EFT Confirmation Wizard'
+ _name = "account.eft.confirmation.wizard"
+ _description = "EFT Confirmation Wizard"
- eft_id = fields.Many2one('account.eft')
- line_ids = fields.One2many('account.eft.confirmation.line', 'wizard_id')
+ eft_id = fields.Many2one("account.eft")
+ line_ids = fields.One2many("account.eft.confirmation.line", "wizard_id")
def action_validate(self):
"""Validate the EFT.
@@ -24,17 +24,19 @@ def action_validate(self):
* section in the form view of the EFT.
* Creation journal Entries.
"""
- self.eft_id.state = 'done'
+ self.eft_id.state = "done"
- completed_payments = self.line_ids.filtered(
- lambda l: l.completed).mapped('payment_id')
+ completed_payments = self.line_ids.filtered(lambda l: l.completed).mapped(
+ "payment_id"
+ )
for payment in completed_payments:
change_payment_date(payment, self.eft_id.payment_date)
completed_payments.mark_as_sent()
- failed_payments = self.line_ids.filtered(
- lambda l: not l.completed).mapped('payment_id')
+ failed_payments = self.line_ids.filtered(lambda l: not l.completed).mapped(
+ "payment_id"
+ )
self.eft_id.payment_ids = completed_payments
self.eft_id.failed_payment_ids = failed_payments
@@ -42,8 +44,7 @@ def action_validate(self):
# Creation of journal Entries
if self.eft_id.use_transit_account:
invoice_vals = self._prepare_account_move_values()
- deposit_account_move = self.env["account.move"].create(
- invoice_vals)
+ deposit_account_move = self.env["account.move"].create(invoice_vals)
deposit_account_move.post()
self.eft_id.deposit_account_move_id = deposit_account_move.id
return True
@@ -63,13 +64,7 @@ def _prepare_account_move_line_vals(self):
"""Prepare line values of EFT Entries."""
vals_account_move_lines = []
for line in self.line_ids.filtered(lambda line: line.completed):
- vals_account_move_lines.append(
- (
- 0,
- 0,
- self._get_payment_line_vals(line)
- )
- )
+ vals_account_move_lines.append((0, 0, self._get_payment_line_vals(line)))
vals_account_move_lines.append(
(
@@ -77,7 +72,11 @@ def _prepare_account_move_line_vals(self):
0,
{
"partner_id": self.eft_id.journal_id.company_id.partner_id.id,
- "credit": sum(self.line_ids.filtered(lambda line: line.completed).mapped('amount')),
+ "credit": sum(
+ self.line_ids.filtered(lambda line: line.completed).mapped(
+ "amount"
+ )
+ ),
"account_id": self.eft_id.journal_id.payment_credit_account_id.id,
"name": self.eft_id.name + _(" - Deposit"),
},
@@ -87,43 +86,45 @@ def _prepare_account_move_line_vals(self):
def _get_payment_line_vals(self, line):
"""Prepare line values of EFT Entries from Payments."""
- return {"partner_id": line.partner_id.id,
- "debit": line.amount,
- "account_id": self.eft_id.journal_id.transit_account.id,
- "name": self.eft_id.name + _(" - Deposit")}
+ return {
+ "partner_id": line.partner_id.id,
+ "debit": line.amount,
+ "account_id": self.eft_id.journal_id.transit_account.id,
+ "name": self.eft_id.name + _(" - Deposit"),
+ }
class EFTConfirmationLine(models.TransientModel):
- _name = 'account.eft.confirmation.line'
- _description = 'EFT Confirmation Line'
+ _name = "account.eft.confirmation.line"
+ _description = "EFT Confirmation Line"
- wizard_id = fields.Many2one('account.eft.confirmation.wizard')
- payment_id = fields.Many2one('account.payment')
+ wizard_id = fields.Many2one("account.eft.confirmation.wizard")
+ payment_id = fields.Many2one("account.payment")
payment_date = fields.Date(
- related='payment_id.date',
+ related="payment_id.date",
string="Payment Date",
)
name = fields.Char(
- related='payment_id.name',
+ related="payment_id.name",
string="Name",
)
partner_id = fields.Many2one(
- related='payment_id.partner_id',
+ related="payment_id.partner_id",
string="Partner",
)
partner_bank_account_id = fields.Many2one(
- related='payment_id.partner_bank_id',
+ related="payment_id.partner_bank_id",
string="Recipient Bank Account",
)
amount = fields.Monetary(
- related='payment_id.amount',
+ related="payment_id.amount",
string="Payment Amount",
)
currency_id = fields.Many2one(
- related='payment_id.currency_id',
+ related="payment_id.currency_id",
)
completed = fields.Boolean(
- string='Completed',
+ string="Completed",
default=True,
)
diff --git a/canada_bank_transfer/wizard/payment_notice_email.py b/canada_bank_transfer/wizard/payment_notice_email.py
index 2079fce3..d5d95852 100644
--- a/canada_bank_transfer/wizard/payment_notice_email.py
+++ b/canada_bank_transfer/wizard/payment_notice_email.py
@@ -1,19 +1,19 @@
# © 2019 Numigi
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-from odoo import _, api, fields, models
+from odoo import _, fields, models
class MailComposeWizard(models.TransientModel):
- _inherit = 'mail.compose.message'
+ _inherit = "mail.compose.message"
is_eft_payment_notice = fields.Boolean()
- eft_id = fields.Many2one('account.eft', 'EFT')
+ eft_id = fields.Many2one("account.eft", "EFT")
def action_send_mail(self):
result = super().action_send_mail()
if self.is_eft_payment_notice:
- self.eft_id.message_post(body=_('Payment notices sent.'))
+ self.eft_id.message_post(body=_("Payment notices sent."))
self.eft_id.payment_notices_sent = True
return result
diff --git a/hr_expense_tax_adjustment/models/hr_expense.py b/hr_expense_tax_adjustment/models/hr_expense.py
index b5282627..d1ffa270 100644
--- a/hr_expense_tax_adjustment/models/hr_expense.py
+++ b/hr_expense_tax_adjustment/models/hr_expense.py
@@ -3,83 +3,95 @@
import logging
from odoo import api, fields, models
-from odoo.exceptions import UserError
_logger = logging.getLogger(__name__)
class HrExpense(models.Model):
- _inherit = 'hr.expense'
+ _inherit = "hr.expense"
tax_line_ids = fields.One2many(
- 'hr.expense.tax', 'expense_id', 'Detailed Taxes',
- readonly=True, copy=True,
+ "hr.expense.tax",
+ "expense_id",
+ "Detailed Taxes",
+ readonly=True,
+ copy=True,
states={
- 'draft': [('readonly', False)],
- 'reported': [('readonly', False)],
- 'refused': [('readonly', False)],
- 'approved': [('readonly', False)],
- })
+ "draft": [("readonly", False)],
+ "reported": [("readonly", False)],
+ "refused": [("readonly", False)],
+ "approved": [("readonly", False)],
+ },
+ )
@api.onchange(
- 'product_id', 'quantity', 'unit_amount', 'tax_ids',
- 'company_id', 'currency_id')
+ "product_id", "quantity", "unit_amount", "tax_ids", "company_id", "currency_id"
+ )
def _onchange_amount_setup_tax_lines(self):
if self.quantity and self.unit_amount and self.tax_ids:
self._setup_tax_lines()
else:
- self.tax_line_ids = self.env['hr.expense.tax']
+ self.tax_line_ids = self.env["hr.expense.tax"]
def _setup_tax_lines(self):
"""Setup the taxes on the expense."""
- self.tax_line_ids = self.env['hr.expense.tax']
+ self.tax_line_ids = self.env["hr.expense.tax"]
currency = self.currency_id or self.company_id.currency_id
taxes = self.tax_ids.with_context(round=True).compute_all(
- self.unit_amount, currency, self.quantity, self.product_id)
- print("TAXES",taxes)
-
- for tax in taxes['taxes']:
- self.tax_line_ids |= self.env['hr.expense.tax'].new({
- 'amount': tax['amount'],
- 'account_id': tax['account_id'],
- 'tax_id': tax['id'] or tax['id'].origin,
- 'price_include': tax['price_include'],
- })
+ self.unit_amount, currency, self.quantity, self.product_id
+ )
+ print("TAXES", taxes)
+
+ for tax in taxes["taxes"]:
+ self.tax_line_ids |= self.env["hr.expense.tax"].new(
+ {
+ "amount": tax["amount"],
+ "account_id": tax["account_id"],
+ "tax_id": tax["id"] or tax["id"].origin,
+ "price_include": tax["price_include"],
+ }
+ )
def _move_line_get_using_tax_lines(self):
# TODO this function must be fixed and _prepare_move_line value obsolete on v14
expense_move_line = self._prepare_move_line_value()
- expense_move_line['price'] = self.untaxed_amount
+ expense_move_line["price"] = self.untaxed_amount
move_lines = [expense_move_line]
for line in self.tax_line_ids:
- move_lines.append({
- 'type': 'tax',
- 'name': line.tax_id.name,
- 'price_unit': line.amount,
- 'quantity': 1,
- 'price': line.amount,
- 'account_id': line.account_id.id,
- 'tax_line_id': line.tax_id.id,
- 'expense_id': self.id,
- })
+ move_lines.append(
+ {
+ "type": "tax",
+ "name": line.tax_id.name,
+ "price_unit": line.amount,
+ "quantity": 1,
+ "price": line.amount,
+ "account_id": line.account_id.id,
+ "tax_line_id": line.tax_id.id,
+ "expense_id": self.id,
+ }
+ )
return move_lines
- @api.depends('quantity', 'unit_amount', 'tax_ids', 'currency_id', 'tax_line_ids.amount')
+ @api.depends(
+ "quantity", "unit_amount", "tax_ids", "currency_id", "tax_line_ids.amount"
+ )
def _compute_amount(self):
expenses_with_tax_lines = self.filtered(lambda e: e.tax_ids)
expenses_without_tax_lines = self.filtered(lambda e: not e.tax_ids)
for expense in expenses_with_tax_lines:
included_tax_amount = sum(
- l.amount for l in expense.tax_line_ids if l.price_include)
- tax_amount = sum(l.amount for l in expense.tax_line_ids)
+ line.amount for line in expense.tax_line_ids if line.price_include
+ )
+ tax_amount = sum(line.amount for line in expense.tax_line_ids)
- expense.untaxed_amount = expense.unit_amount * \
- expense.quantity - included_tax_amount
+ expense.untaxed_amount = (
+ expense.unit_amount * expense.quantity - included_tax_amount
+ )
expense.total_amount = expense.untaxed_amount + tax_amount
super(HrExpense, expenses_without_tax_lines)._compute_amount()
diff --git a/hr_expense_tax_adjustment/tests/test_hr_expense.py b/hr_expense_tax_adjustment/tests/test_hr_expense.py
index f4315cb3..ca46f2de 100644
--- a/hr_expense_tax_adjustment/tests/test_hr_expense.py
+++ b/hr_expense_tax_adjustment/tests/test_hr_expense.py
@@ -2,7 +2,6 @@
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
from odoo.tests import common
-from odoo.exceptions import UserError
class TestAccountMoveLine(common.SavepointCase):
@@ -10,87 +9,122 @@ class TestAccountMoveLine(common.SavepointCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
- cls.tax_account = cls.env['account.account'].create({
- 'code': 'TAX1',
- 'name': 'Tax 1',
- 'user_type_id': cls.env.ref('account.data_account_type_receivable').id,
- 'reconcile': True,
- })
-
- cls.tax_account_2 = cls.env['account.account'].create({
- 'code': 'TAX2',
- 'name': 'Tax 2',
- 'user_type_id': cls.env.ref('account.data_account_type_receivable').id,
- 'reconcile': True,
- })
+ cls.tax_account = cls.env["account.account"].create(
+ {
+ "code": "TAX1",
+ "name": "Tax 1",
+ "user_type_id": cls.env.ref("account.data_account_type_receivable").id,
+ "reconcile": True,
+ }
+ )
+
+ cls.tax_account_2 = cls.env["account.account"].create(
+ {
+ "code": "TAX2",
+ "name": "Tax 2",
+ "user_type_id": cls.env.ref("account.data_account_type_receivable").id,
+ "reconcile": True,
+ }
+ )
# This case of taxes is based on the GST/QST taxes in Canada
- cls.tax_1 = cls.env['account.tax'].create({
- 'name': 'Tax 1 (5%)',
- 'description': 'Tax 1 (5%)',
- 'amount': 4.5465,
- 'amount_type': 'percent',
- 'type_tax_use': 'purchase',
- 'price_include': True,
- 'include_base_amount': False,
- 'invoice_repartition_line_ids': cls._make_tax_repartition(cls.tax_account),
- 'refund_repartition_line_ids': cls._make_tax_repartition(cls.tax_account),
- })
- cls.tax_2 = cls.env['account.tax'].create({
- 'name': 'Tax 2 (9.9975%)',
- 'description': 'Tax 2 (9.9975%)',
- 'amount': 9.975,
- 'amount_type': 'percent',
- 'type_tax_use': 'purchase',
- 'price_include': True,
- 'include_base_amount': False,
- 'invoice_repartition_line_ids': cls._make_tax_repartition(cls.tax_account_2),
- 'refund_repartition_line_ids': cls._make_tax_repartition(cls.tax_account_2),
- })
- cls.parent_tax = cls.env['account.tax'].create({
- 'name': 'Parent Tax',
- 'amount': 0,
- 'amount_type': 'group',
- 'type_tax_use': 'purchase',
- })
+ cls.tax_1 = cls.env["account.tax"].create(
+ {
+ "name": "Tax 1 (5%)",
+ "description": "Tax 1 (5%)",
+ "amount": 4.5465,
+ "amount_type": "percent",
+ "type_tax_use": "purchase",
+ "price_include": True,
+ "include_base_amount": False,
+ "invoice_repartition_line_ids": cls._make_tax_repartition(
+ cls.tax_account
+ ),
+ "refund_repartition_line_ids": cls._make_tax_repartition(
+ cls.tax_account
+ ),
+ }
+ )
+ cls.tax_2 = cls.env["account.tax"].create(
+ {
+ "name": "Tax 2 (9.9975%)",
+ "description": "Tax 2 (9.9975%)",
+ "amount": 9.975,
+ "amount_type": "percent",
+ "type_tax_use": "purchase",
+ "price_include": True,
+ "include_base_amount": False,
+ "invoice_repartition_line_ids": cls._make_tax_repartition(
+ cls.tax_account_2
+ ),
+ "refund_repartition_line_ids": cls._make_tax_repartition(
+ cls.tax_account_2
+ ),
+ }
+ )
+ cls.parent_tax = cls.env["account.tax"].create(
+ {
+ "name": "Parent Tax",
+ "amount": 0,
+ "amount_type": "group",
+ "type_tax_use": "purchase",
+ }
+ )
cls.parent_tax.children_tax_ids = cls.tax_1 | cls.tax_2
- cls.product = cls.env.ref('hr_expense.air_ticket')
+ cls.product = cls.env.ref("hr_expense.air_ticket")
cls.product.supplier_taxes_id = cls.parent_tax
- cls.user = cls.env.ref('base.user_demo')
+ cls.user = cls.env.ref("base.user_demo")
cls.employee = cls.user.employee_ids
- cls.payable = cls.env['account.account'].search(
- [('user_type_id.type', '=', 'payable')], limit=1)
+ cls.payable = cls.env["account.account"].search(
+ [("user_type_id.type", "=", "payable")], limit=1
+ )
cls.employee.address_home_id.property_account_payable_id = cls.payable.id
- cls.sheet = cls.env['hr.expense.sheet'].create({
- 'name': 'Air Tickets',
- 'employee_id': cls.employee.id,
- })
-
- cls.expense = cls.env['hr.expense'].with_user(cls.user).create({
- 'name': 'Car Travel Expenses',
- 'employee_id': cls.employee.id,
- 'product_id': cls.product.id,
- 'unit_amount': 700.00,
- 'tax_ids': [(6, 0, [cls.parent_tax.id])],
- 'sheet_id': cls.sheet.id,
- })
+ cls.sheet = cls.env["hr.expense.sheet"].create(
+ {
+ "name": "Air Tickets",
+ "employee_id": cls.employee.id,
+ }
+ )
+
+ cls.expense = (
+ cls.env["hr.expense"]
+ .with_user(cls.user)
+ .create(
+ {
+ "name": "Car Travel Expenses",
+ "employee_id": cls.employee.id,
+ "product_id": cls.product.id,
+ "unit_amount": 700.00,
+ "tax_ids": [(6, 0, [cls.parent_tax.id])],
+ "sheet_id": cls.sheet.id,
+ }
+ )
+ )
@staticmethod
def _make_tax_repartition(account):
return [
- (0, 0, {
- "repartition_type": "base",
- "factor_percent": 0,
- }),
- (0, 0, {
- "account_id": account.id,
- "factor_percent": 100,
- })
+ (
+ 0,
+ 0,
+ {
+ "repartition_type": "base",
+ "factor_percent": 0,
+ },
+ ),
+ (
+ 0,
+ 0,
+ {
+ "account_id": account.id,
+ "factor_percent": 100,
+ },
+ ),
]
def test_onchangeAmountSetupTaxLines_thenTaxLinesAreComputed(self):
@@ -104,7 +138,7 @@ def test_onchangeAmountSetupTaxLines_thenTaxLinesAreComputed(self):
self.assertEqual(len(lines), 2)
self.assertEqual(lines[0].tax_id, self.tax_1)
self.assertEqual(lines[1].tax_id, self.tax_2)
- base = round(700/(1 + 0.045465 + 0.09975), 2)
+ base = round(700 / (1 + 0.045465 + 0.09975), 2)
self.assertAlmostEqual(lines[0].amount, base * 0.045465, 2)
self.assertAlmostEqual(lines[1].amount, base * 0.09975, 2)
@@ -136,15 +170,17 @@ def test_whenValidatingExpense_thenTaxesAreCorrectlyAccounted(self):
self.assertEqual(len(move_lines), 4)
tax_1 = move_lines.filtered(lambda l: l.account_id == self.tax_account)
- tax_2 = move_lines.filtered(
- lambda l: l.account_id == self.tax_account_2)
+ tax_2 = move_lines.filtered(lambda l: l.account_id == self.tax_account_2)
payable = move_lines.filtered(lambda l: l.account_id == self.payable)
- base = round(700/(1 + 0.045465 + 0.09975), 2)
+ base = round(700 / (1 + 0.045465 + 0.09975), 2)
self.assertAlmostEqual(tax_1.debit, base * 0.045465, 2)
self.assertAlmostEqual(tax_2.debit, base * 0.09975, 2)
self.assertAlmostEqual(payable.credit, 700, 2)
+
#
- def test_whenValidatingExpenseWithExcludedTaxes_thenTaxesAreCorrectlyAccounted(self):
+ def test_whenValidatingExpenseWithExcludedTaxes_thenTaxesAreCorrectlyAccounted(
+ self,
+ ):
self.tax_1.amount = 5
self.tax_1.price_include = False
self.tax_2.price_include = False
@@ -158,14 +194,15 @@ def test_whenValidatingExpenseWithExcludedTaxes_thenTaxesAreCorrectlyAccounted(s
self.assertEqual(len(move_lines), 4)
tax_1 = move_lines.filtered(lambda l: l.account_id == self.tax_account)
- tax_2 = move_lines.filtered(
- lambda l: l.account_id == self.tax_account_2)
+ tax_2 = move_lines.filtered(lambda l: l.account_id == self.tax_account_2)
payable = move_lines.filtered(lambda l: l.account_id == self.payable)
self.assertAlmostEqual(tax_1.debit, 700 * 0.05, 2)
self.assertAlmostEqual(tax_2.debit, 700 * 0.09975, 2)
self.assertAlmostEqual(payable.credit, 700 * 1.14975, 2)
- def test_ifTaxesAreIncludedAndExpenseHasNoTaxeLines_thenTaxesAreCorrectlyAccounted(self):
+ def test_ifTaxesAreIncludedAndExpenseHasNoTaxeLines_thenTaxesAreCorrectlyAccounted(
+ self,
+ ):
self.sheet.approve_expense_sheets()
self.sheet.action_sheet_move_create()
@@ -173,14 +210,15 @@ def test_ifTaxesAreIncludedAndExpenseHasNoTaxeLines_thenTaxesAreCorrectlyAccount
self.assertEqual(len(move_lines), 4)
tax_1 = move_lines.filtered(lambda l: l.account_id == self.tax_account)
- tax_2 = move_lines.filtered(
- lambda l: l.account_id == self.tax_account_2)
+ tax_2 = move_lines.filtered(lambda l: l.account_id == self.tax_account_2)
payable = move_lines.filtered(lambda l: l.account_id == self.payable)
self.assertAlmostEqual(tax_1.debit, 700 * (0.045465 / 1.145215), 2)
self.assertAlmostEqual(tax_2.debit, 700 * (0.09975 / 1.145215), 2)
self.assertAlmostEqual(payable.credit, 700)
- def test_ifTaxesAreExcludedAndExpenseHasNoTaxeLines_thenTaxesAreCorrectlyAccounted(self):
+ def test_ifTaxesAreExcludedAndExpenseHasNoTaxeLines_thenTaxesAreCorrectlyAccounted(
+ self,
+ ):
self.tax_1.amount = 5
self.tax_1.price_include = False
self.tax_2.price_include = False
@@ -192,8 +230,7 @@ def test_ifTaxesAreExcludedAndExpenseHasNoTaxeLines_thenTaxesAreCorrectlyAccount
self.assertEqual(len(move_lines), 4)
tax_1 = move_lines.filtered(lambda l: l.account_id == self.tax_account)
- tax_2 = move_lines.filtered(
- lambda l: l.account_id == self.tax_account_2)
+ tax_2 = move_lines.filtered(lambda l: l.account_id == self.tax_account_2)
payable = move_lines.filtered(lambda l: l.account_id == self.payable)
self.assertAlmostEqual(tax_1.debit, 700 * 0.05, 2)
self.assertAlmostEqual(tax_2.debit, 700 * 0.09975, 2)
@@ -202,7 +239,7 @@ def test_ifTaxesAreExcludedAndExpenseHasNoTaxeLines_thenTaxesAreCorrectlyAccount
def test_withMultipleExpenseLines_totalAmountsAreComputedProperly(self):
self.expense._onchange_amount_setup_tax_lines()
- expense_2 = self.expense.copy({'unit_amount': 500})
+ expense_2 = self.expense.copy({"unit_amount": 500})
expense_2._onchange_amount_setup_tax_lines()
expense_2._compute_amount()
@@ -216,7 +253,7 @@ def test_withMultipleExpenseLines_totalAmountsAreComputedProperly(self):
def test_withMultipleExpenseLines_taxesAreCorrectlyAccounted(self):
self.expense._onchange_amount_setup_tax_lines()
- expense_2 = self.expense.copy({'unit_amount': 500})
+ expense_2 = self.expense.copy({"unit_amount": 500})
expense_2._onchange_amount_setup_tax_lines()
expense_2.sheet_id = self.sheet
@@ -226,13 +263,14 @@ def test_withMultipleExpenseLines_taxesAreCorrectlyAccounted(self):
move_lines = self.sheet.account_move_id.line_ids
tax_1 = move_lines.filtered(lambda l: l.account_id == self.tax_account)
- tax_2 = move_lines.filtered(
- lambda l: l.account_id == self.tax_account_2)
+ tax_2 = move_lines.filtered(lambda l: l.account_id == self.tax_account_2)
payable = move_lines.filtered(lambda l: l.account_id == self.payable)
total_amount = 700 + 500
- self.assertAlmostEqual(sum(tax_1.mapped('debit')),
- total_amount * (0.045465 / 1.145215), 0)
- self.assertAlmostEqual(sum(tax_2.mapped('debit')),
- total_amount * (0.09975 / 1.145215), 0)
- self.assertAlmostEqual(sum(payable.mapped('credit')), total_amount, 0)
+ self.assertAlmostEqual(
+ sum(tax_1.mapped("debit")), total_amount * (0.045465 / 1.145215), 0
+ )
+ self.assertAlmostEqual(
+ sum(tax_2.mapped("debit")), total_amount * (0.09975 / 1.145215), 0
+ )
+ self.assertAlmostEqual(sum(payable.mapped("credit")), total_amount, 0)
diff --git a/invoice_currency_validation/models/account_move.py b/invoice_currency_validation/models/account_move.py
index 3d7868a1..da23e63f 100644
--- a/invoice_currency_validation/models/account_move.py
+++ b/invoice_currency_validation/models/account_move.py
@@ -2,9 +2,8 @@
# © 2018 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-from odoo import _, api, models
+from odoo import _, models
from odoo.exceptions import UserError
-from typing import Optional
class AccountMove(models.Model):
@@ -44,7 +43,8 @@ def _check_invoice_currency_versus_account_currency(self):
invoice_currency = self.currency_id or company_currency
partner_lines = self.line_ids.filtered(
- lambda l: l.account_id.internal_type in (
+ lambda l: l.account_id.internal_type
+ in (
"receivable",
"payable",
)
diff --git a/invoice_intercompany_compatible/tests/test_account_invoice.py b/invoice_intercompany_compatible/tests/test_account_invoice.py
index 5d1797f3..9c05f534 100644
--- a/invoice_intercompany_compatible/tests/test_account_invoice.py
+++ b/invoice_intercompany_compatible/tests/test_account_invoice.py
@@ -1,7 +1,7 @@
# © 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-from odoo.tests.common import SavepointCase, Form
+from odoo.tests.common import SavepointCase
class TestAccountInvoice(SavepointCase):
diff --git a/invoice_list_email/__manifest__.py b/invoice_list_email/__manifest__.py
index c60f0fe6..4716cb7c 100644
--- a/invoice_list_email/__manifest__.py
+++ b/invoice_list_email/__manifest__.py
@@ -11,6 +11,8 @@
"category": "Accounting",
"summary": "Add the email to the list of customer invoices",
"depends": ["account"],
- "data": ["views/account_move.xml",],
+ "data": [
+ "views/account_move.xml",
+ ],
"installable": True,
}
diff --git a/invoice_mass_mailing_with_layout/tests/__init__.py b/invoice_mass_mailing_with_layout/tests/__init__.py
index 72c8ae9c..65c2064a 100644
--- a/invoice_mass_mailing_with_layout/tests/__init__.py
+++ b/invoice_mass_mailing_with_layout/tests/__init__.py
@@ -1,4 +1,4 @@
# © 2022 Numigi
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-from . import test_account_invoice_send
\ No newline at end of file
+from . import test_account_invoice_send
diff --git a/invoice_mass_mailing_with_layout/tests/test_account_invoice_send.py b/invoice_mass_mailing_with_layout/tests/test_account_invoice_send.py
index 93396f72..07748127 100644
--- a/invoice_mass_mailing_with_layout/tests/test_account_invoice_send.py
+++ b/invoice_mass_mailing_with_layout/tests/test_account_invoice_send.py
@@ -9,7 +9,8 @@ class TestAccountInvoice(SavepointCase):
def setUpClass(cls):
super().setUpClass()
cls.invoices = cls.env["account.move"].search(
- [("move_type", "=", "out_invoice")])
+ [("move_type", "=", "out_invoice")]
+ )
cls.template = cls.env.ref("account.email_template_edi_invoice")
cls.template.auto_delete = False
@@ -42,7 +43,10 @@ def _create_wizard(self, invoices):
def _find_last_email(self, invoice):
return self.env["mail.mail"].search(
- [("model", "=", "account.move"), ("res_id", "=", invoice.id),],
+ [
+ ("model", "=", "account.move"),
+ ("res_id", "=", invoice.id),
+ ],
order="id desc",
limit=1,
)
diff --git a/payment_list_not_sent/__manifest__.py b/payment_list_not_sent/__manifest__.py
index e05957e2..f0dfd7d9 100644
--- a/payment_list_not_sent/__manifest__.py
+++ b/payment_list_not_sent/__manifest__.py
@@ -11,6 +11,8 @@
"category": "Accounting",
"summary": "Easily view supplier payments not sent from list view",
"depends": ["account"],
- "data": ["views/account_payment.xml",],
+ "data": [
+ "views/account_payment.xml",
+ ],
"installable": True,
}