diff --git a/account_check_deposit/__manifest__.py b/account_check_deposit/__manifest__.py index 706e43736..6f1ddbb05 100644 --- a/account_check_deposit/__manifest__.py +++ b/account_check_deposit/__manifest__.py @@ -1,13 +1,13 @@ -# Copyright 2012-2020 Akretion France (http://www.akretion.com/) +# Copyright 2012-2021 Akretion France (http://www.akretion.com/) # @author: Benoît GUILLOT # @author: Chafique DELLI # @author: Alexis de Lattre -# Copyright 2018-2020 Tecnativa - Pedro M. Baeza +# Copyright 2018-2021 Tecnativa - Pedro M. Baeza # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { "name": "Account Check Deposit", - "version": "14.0.1.1.0", + "version": "15.0.1.0.0", "category": "Accounting", "license": "AGPL-3", "summary": "Manage deposit of checks to the bank", diff --git a/account_check_deposit/models/account_check_deposit.py b/account_check_deposit/models/account_check_deposit.py index 53a5b2411..bdc7ef7fa 100644 --- a/account_check_deposit/models/account_check_deposit.py +++ b/account_check_deposit/models/account_check_deposit.py @@ -1,9 +1,9 @@ -# Copyright 2012-2020 Akretion (http://www.akretion.com/) +# Copyright 2012-2021 Akretion (http://www.akretion.com/) # @author: Benoît GUILLOT # @author: Chafique DELLI # @author: Alexis de Lattre # @author: Mourad EL HADJ MIMOUNE -# Copyright 2018 Tecnativa - Pedro M. Baeza +# Copyright 2018-2021 Tecnativa - Pedro M. Baeza # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import _, api, fields, models @@ -17,6 +17,100 @@ class AccountCheckDeposit(models.Model): _order = "deposit_date desc" _check_company_auto = True + name = fields.Char(size=64, readonly=True, default="/", copy=False) + check_payment_ids = fields.One2many( + comodel_name="account.move.line", + inverse_name="check_deposit_id", + string="Check Payments", + states={"done": [("readonly", "=", True)]}, + ) + deposit_date = fields.Date( + required=True, + states={"done": [("readonly", "=", True)]}, + default=fields.Date.context_today, + tracking=True, + copy=False, + ) + journal_id = fields.Many2one( + comodel_name="account.journal", + string="Check Journal", + domain="[('company_id', '=', company_id), ('type', '=', 'bank'), " + "('bank_account_id', '=', False)]", + required=True, + check_company=True, + states={"done": [("readonly", "=", True)]}, + tracking=True, + ) + in_hand_check_account_id = fields.Many2one( + comodel_name="account.account", + compute="_compute_in_hand_check_account_id", + store=True, + ) + currency_id = fields.Many2one( + comodel_name="res.currency", + required=True, + states={"done": [("readonly", "=", True)]}, + tracking=True, + ) + state = fields.Selection( + selection=[("draft", "Draft"), ("done", "Done")], + string="Status", + default="draft", + readonly=True, + tracking=True, + ) + move_id = fields.Many2one( + comodel_name="account.move", + string="Journal Entry", + readonly=True, + check_company=True, + ) + bank_journal_id = fields.Many2one( + comodel_name="account.journal", + string="Bank Account", + required=True, + domain="[('company_id', '=', company_id), ('type', '=', 'bank'), " + "('bank_account_id', '!=', False)]", + check_company=True, + states={"done": [("readonly", "=", True)]}, + tracking=True, + ) + line_ids = fields.One2many( + comodel_name="account.move.line", + related="move_id.line_ids", + string="Lines", + ) + company_id = fields.Many2one( + comodel_name="res.company", + required=True, + states={"done": [("readonly", "=", True)]}, + default=lambda self: self.env.company, + tracking=True, + ) + total_amount = fields.Monetary( + compute="_compute_check_deposit", + store=True, + currency_field="currency_id", + tracking=True, + ) + check_count = fields.Integer( + compute="_compute_check_deposit", + store=True, + string="Number of Checks", + tracking=True, + ) + is_reconcile = fields.Boolean( + compute="_compute_check_deposit", store=True, string="Reconcile" + ) + + _sql_constraints = [ + ( + "name_company_unique", + "unique(company_id, name)", + "A check deposit with this reference already exists in this company.", + ) + ] + @api.depends( "company_id", "currency_id", @@ -57,103 +151,19 @@ class AccountCheckDeposit(models.Model): deposit.is_reconcile = reconcile deposit.check_count = count - name = fields.Char(string="Name", size=64, readonly=True, default="/", copy=False) - check_payment_ids = fields.One2many( - comodel_name="account.move.line", - inverse_name="check_deposit_id", - string="Check Payments", - states={"done": [("readonly", "=", True)]}, - ) - deposit_date = fields.Date( - string="Deposit Date", - required=True, - states={"done": [("readonly", "=", True)]}, - default=fields.Date.context_today, - tracking=True, - copy=False, - ) - journal_id = fields.Many2one( - comodel_name="account.journal", - string="Journal", - domain="[('company_id', '=', company_id), ('type', '=', 'bank'), " - "('bank_account_id', '=', False)]", - required=True, - check_company=True, - states={"done": [("readonly", "=", True)]}, - tracking=True, - ) - journal_default_account_id = fields.Many2one( - comodel_name="account.account", - related="journal_id.payment_debit_account_id", - string="Outstanding Receipts Account", - ) - currency_id = fields.Many2one( - comodel_name="res.currency", - string="Currency", - required=True, - states={"done": [("readonly", "=", True)]}, - tracking=True, - ) - state = fields.Selection( - selection=[("draft", "Draft"), ("done", "Done")], - string="Status", - default="draft", - readonly=True, - tracking=True, - ) - move_id = fields.Many2one( - comodel_name="account.move", - string="Journal Entry", - readonly=True, - check_company=True, - ) - bank_journal_id = fields.Many2one( - comodel_name="account.journal", - string="Bank Account", - required=True, - domain="[('company_id', '=', company_id), ('type', '=', 'bank'), " - "('bank_account_id', '!=', False)]", - check_company=True, - states={"done": [("readonly", "=", True)]}, - tracking=True, - ) - line_ids = fields.One2many( - comodel_name="account.move.line", - related="move_id.line_ids", - string="Lines", - ) - company_id = fields.Many2one( - comodel_name="res.company", - string="Company", - required=True, - states={"done": [("readonly", "=", True)]}, - default=lambda self: self.env.company, - tracking=True, - ) - total_amount = fields.Monetary( - compute="_compute_check_deposit", - string="Total Amount", - store=True, - currency_field="currency_id", - tracking=True, - ) - check_count = fields.Integer( - compute="_compute_check_deposit", - store=True, - string="Number of Checks", - tracking=True, - ) - is_reconcile = fields.Boolean( - compute="_compute_check_deposit", store=True, string="Reconcile" - ) - - _sql_constraints = [ - ( - "name_company_unique", - "unique(company_id, name)", - "A check deposit with this reference already exists in this company.", - ) - ] + @api.depends("journal_id") + def _compute_in_hand_check_account_id(self): + for rec in self: + in_hand_check_account_id = False + if rec.journal_id: + for line in rec.journal_id.inbound_payment_method_line_ids: + if ( + line.payment_method_id.code == "manual" + and line.payment_account_id + ): + in_hand_check_account_id = line.payment_account_id.id + break + rec.in_hand_check_account_id = in_hand_check_account_id @api.model def default_get(self, fields_list): @@ -178,15 +188,14 @@ class AccountCheckDeposit(models.Model): if line.currency_id != deposit_currency: raise ValidationError( _( - "The check with amount %s and reference '%s' " - "is in currency %s but the deposit is in " - "currency %s." - ) - % ( - line.debit, - line.ref or "", - line.currency_id.name, - deposit_currency.name, + "The check with amount {amount} and reference '{ref}' " + "is in currency {check_currency} but the deposit is in " + "currency {deposit_currency}." + ).format( + amount=line.debit, + ref=line.ref or "", + check_currency=line.currency_id.name, + deposit_currency=deposit_currency.name, ) ) @@ -251,15 +260,22 @@ class AccountCheckDeposit(models.Model): def _prepare_counterpart_move_lines_vals(self, total_debit, total_amount_currency): self.ensure_one() - if not self.bank_journal_id.payment_debit_account_id: + account_id = False + for line in self.bank_journal_id.inbound_payment_method_line_ids: + if line.payment_method_id.code == "manual" and line.payment_account_id: + account_id = line.payment_account_id.id + break + if not account_id: + account_id = self.company_id.account_journal_payment_debit_account_id.id + if not account_id: raise UserError( - _("Missing 'Outstanding Receipts Account' on the bank journal '%s'.") - % self.bank_journal_id.display_name + _("Missing 'Outstanding Receipts Account' on the company '%s'.") + % self.company_id.display_name ) return { "debit": total_debit, "credit": 0.0, - "account_id": self.bank_journal_id.payment_debit_account_id.id, + "account_id": account_id, "partner_id": False, "currency_id": self.currency_id.id or False, "amount_currency": total_amount_currency, @@ -331,7 +347,7 @@ class AccountCheckDeposit(models.Model): [ ("company_id", "=", self.company_id.id), ("reconciled", "=", False), - ("account_id", "=", self.journal_id.payment_debit_account_id.id), + ("account_id", "=", self.in_hand_check_account_id.id), ("debit", ">", 0), ("check_deposit_id", "=", False), ("currency_id", "=", self.currency_id.id), @@ -344,11 +360,10 @@ class AccountCheckDeposit(models.Model): else: raise UserError( _( - "There are no received checks in account '%s' in currency '%s' " - "that are not already in this check deposit." - ) - % ( - self.journal_id.payment_debit_account_id.display_name, - self.currency_id.display_name, + "There are no received checks in account '{account}' in currency " + "'{currency}' that are not already in this check deposit." + ).format( + account=self.in_hand_check_account_id.display_name, + currency=self.currency_id.display_name, ) ) diff --git a/account_check_deposit/models/account_move_line.py b/account_check_deposit/models/account_move_line.py index f5155f713..a5baea11d 100644 --- a/account_check_deposit/models/account_move_line.py +++ b/account_check_deposit/models/account_move_line.py @@ -1,9 +1,9 @@ -# Copyright 2012-2020 Akretion France (http://www.akretion.com/) +# Copyright 2012-2021 Akretion France (http://www.akretion.com/) # @author: Benoît GUILLOT # @author: Chafique DELLI # @author: Alexis de Lattre # @author: Mourad EL HADJ MIMOUNE -# Copyright 2018-2020 Tecnativa - Pedro M. Baeza +# Copyright 2018-2021 Tecnativa - Pedro M. Baeza # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import fields, models diff --git a/account_check_deposit/readme/CONFIGURE.rst b/account_check_deposit/readme/CONFIGURE.rst index 8b2729f8b..db9ad00cc 100644 --- a/account_check_deposit/readme/CONFIGURE.rst +++ b/account_check_deposit/readme/CONFIGURE.rst @@ -4,9 +4,9 @@ journal: * Name: Checks Received * Type: Bank * Short Code: CHK (or any code you want) -* Outstanding Receipts Account: select an account for checks received +* in the tab *Incoming Payments*, add a line with *Payment Method* = *Manual* and *Outstanding receipts account* set to the account for the checks in hand. -Note that, on this *Checks Received* journal, the bank account and suspense account will not be used, so don't worry about these parameters. +Note that, on this *Checks Received* journal, the bank account and suspense account will not be used, so don't worry about these parameters. The field *Account number* must be empty. This bank journal will be available as a payment method in Odoo. The account you configured as *Outstanding Receipts Account* is the diff --git a/account_check_deposit/tests/test_check_deposit.py b/account_check_deposit/tests/test_check_deposit.py index 4f3c3715d..79ff93cde 100644 --- a/account_check_deposit/tests/test_check_deposit.py +++ b/account_check_deposit/tests/test_check_deposit.py @@ -100,45 +100,51 @@ class TestPayment(TransactionCase): } ) - self.check_journal = self.journal_model.search( - [("code", "=", "CHK"), ("company_id", "=", self.main_company.id)], limit=1 + self.manual_method_in = self.env.ref("account.account_payment_method_manual_in") + self.check_journal = self.journal_model.create( + { + "name": "received check", + "type": "bank", + "code": "CHK", + "company_id": self.main_company.id, + "inbound_payment_method_line_ids": [ + ( + 0, + 0, + { + "payment_method_id": self.manual_method_in.id, + "payment_account_id": self.received_check_account_id.id, + }, + ) + ], + } ) - if not self.check_journal: - self.check_journal = self.journal_model.create( - { - "name": "received check", - "type": "bank", - "code": "CHK", - "company_id": self.main_company.id, - } - ) - self.check_journal.payment_debit_account_id = self.received_check_account_id - self.check_journal.payment_credit_account_id = self.received_check_account_id - self.bank_journal = self.journal_model.search( - [("code", "=", "BNK1"), ("company_id", "=", self.main_company.id)], limit=1 + self.partner_bank_id = self.res_partner_bank_model.create( + { + "acc_number": "SI56 1910 0000 0123 438 584", + "partner_id": self.main_company.partner_id.id, + } ) - if not self.bank_journal: - self.bank_journal = self.journal_model.create( - { - "name": "Bank", - "type": "bank", - "code": "BNK1", - "company_id": self.main_company.id, - } - ) - self.bank_journal.payment_debit_account_id = self.transfer_account_id - self.bank_journal.payment_credit_account_id = self.transfer_account_id - self.partner_bank_id = self.res_partner_bank_model.search( - [("partner_id", "=", self.main_company.partner_id.id)], limit=1 + + self.bank_journal = self.journal_model.create( + { + "name": "Bank Test Chq", + "type": "bank", + "code": "TEST@@", + "company_id": self.main_company.id, + "bank_account_id": self.partner_bank_id.id, + "inbound_payment_method_line_ids": [ + ( + 0, + 0, + { + "payment_method_id": self.manual_method_in.id, + "payment_account_id": self.transfer_account_id.id, + }, + ) + ], + } ) - if not self.partner_bank_id: - self.partner_bank_id = self.res_partner_bank_model.create( - { - "acc_number": "SI56 1910 0000 0123 438 584", - "partner_id": self.main_company.partner_id.id, - } - ) - self.bank_journal.bank_account_id = self.partner_bank_id.id def create_invoice(self, amount=100, inv_type="out_invoice", currency_id=None): """Returns an open invoice""" @@ -164,7 +170,7 @@ class TestPayment(TransactionCase): invoice.action_post() return invoice - def create_check_deposit(self, move_lines): + def create_check_deposit(self): """Returns an validated check deposit""" check_deposit = self.check_deposit_model.create( { @@ -184,32 +190,24 @@ class TestPayment(TransactionCase): inv_1 = self.create_invoice(amount=100, currency_id=self.currency_id) inv_2 = self.create_invoice(amount=200, currency_id=self.currency_id) - ctx = {"active_model": "account.move", "active_ids": [inv_1.id, inv_2.id]} - register_payments = self.register_payments_model.with_context(ctx).create( - { - "journal_id": self.check_journal.id, - "payment_method_id": self.payment_method_manual_in.id, - "group_payment": True, - } - ) + register_payments = self.register_payments_model.with_context( + active_model="account.move", + active_ids=[inv_1.id, inv_2.id], + default_journal_id=self.check_journal.id, + ).create({"group_payment": True}) register_payments.action_create_payments() payment = self.payment_model.search([], order="id desc", limit=1) - self.assertAlmostEqual(payment.amount, 300) self.assertEqual(payment.state, "posted") self.assertEqual(inv_1.state, "posted") self.assertEqual(inv_2.state, "posted") - check_aml = payment.move_id.line_ids.filtered( - lambda r: r.account_id == self.received_check_account_id - ) - - check_deposit = self.create_check_deposit([check_aml]) + check_deposit = self.create_check_deposit() liquidity_aml = check_deposit.move_id.line_ids.filtered( lambda r: r.account_id == self.transfer_account_id ) - self.assertEqual(check_deposit.total_amount, 300) - self.assertEqual(liquidity_aml.debit, 300) + self.assertAlmostEqual(check_deposit.total_amount, 300) + self.assertAlmostEqual(liquidity_aml.debit, 300) self.assertEqual(check_deposit.move_id.state, "posted") self.assertEqual(check_deposit.state, "done") diff --git a/account_check_deposit/views/account_check_deposit_view.xml b/account_check_deposit/views/account_check_deposit_view.xml index 027e6691c..78f0e50ac 100644 --- a/account_check_deposit/views/account_check_deposit_view.xml +++ b/account_check_deposit/views/account_check_deposit_view.xml @@ -1,10 +1,10 @@ @@ -52,7 +52,7 @@ name="deposit_date" options="{'datepicker': {'warn_future': true}}" /> - + - + ', 0), ('check_deposit_id', '=', False), ('currency_id', '=', currency_id), - ('account_id', '=', journal_default_account_id), + ('account_id', '=', in_hand_check_account_id), ('company_id', '=', company_id), ('parent_state', '=', 'posted'), ]"