From a9e0b00515514c7ad8acfc6239a34c500b4dd816 Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Sun, 25 Oct 2015 11:24:01 +0100 Subject: [PATCH 01/28] OCA Transbot updated translations from Transifex --- account_check_deposit/i18n/ca.po | 12 ++++++------ account_check_deposit/i18n/es.po | 8 ++++---- account_check_deposit/i18n/hr.po | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/account_check_deposit/i18n/ca.po b/account_check_deposit/i18n/ca.po index cf28381d2..792d34b7e 100644 --- a/account_check_deposit/i18n/ca.po +++ b/account_check_deposit/i18n/ca.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: account-financial-tools (8.0)\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-07-01 13:26+0000\n" +"POT-Creation-Date: 2015-10-20 18:44+0000\n" "PO-Revision-Date: 2015-06-03 15:58+0000\n" "Last-Translator: <>\n" "Language-Team: Catalan (http://www.transifex.com/oca/OCA-account-financial-tools-8-0/language/ca/)\n" @@ -136,12 +136,12 @@ msgstr "" #. module: account_check_deposit #: field:account.check.deposit,create_uid:0 msgid "Created by" -msgstr "" +msgstr "Creat per" #. module: account_check_deposit #: field:account.check.deposit,create_date:0 msgid "Created on" -msgstr "" +msgstr "Creat el" #. module: account_check_deposit #: view:account.check.deposit:account_check_deposit.view_check_deposit_search @@ -208,7 +208,7 @@ msgstr "" #. module: account_check_deposit #: field:account.check.deposit,id:0 msgid "ID" -msgstr "" +msgstr "ID" #. module: account_check_deposit #: view:account.check.deposit:account_check_deposit.view_check_deposit_search @@ -229,12 +229,12 @@ msgstr "" #. module: account_check_deposit #: field:account.check.deposit,write_uid:0 msgid "Last Updated by" -msgstr "" +msgstr "Darrera Actualització per" #. module: account_check_deposit #: field:account.check.deposit,write_date:0 msgid "Last Updated on" -msgstr "" +msgstr "Darrera Actualització el" #. module: account_check_deposit #: field:account.check.deposit,line_ids:0 diff --git a/account_check_deposit/i18n/es.po b/account_check_deposit/i18n/es.po index 0470a9cbb..a680d38aa 100644 --- a/account_check_deposit/i18n/es.po +++ b/account_check_deposit/i18n/es.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: account-financial-tools (8.0)\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-07-01 13:26+0000\n" +"POT-Creation-Date: 2015-10-20 18:44+0000\n" "PO-Revision-Date: 2015-06-03 15:58+0000\n" "Last-Translator: <>\n" "Language-Team: Spanish (http://www.transifex.com/oca/OCA-account-financial-tools-8-0/language/es/)\n" @@ -35,7 +35,7 @@ msgstr "" #. module: account_check_deposit #: view:website:account_check_deposit.report_checkdeposit msgid "Amount" -msgstr "" +msgstr "Importe" #. module: account_check_deposit #: view:account.check.deposit:account_check_deposit.account_check_deposit_view_form @@ -179,7 +179,7 @@ msgstr "" #: view:account.check.deposit:account_check_deposit.view_check_deposit_search #: selection:account.check.deposit,state:0 msgid "Done" -msgstr "" +msgstr "Completado" #. module: account_check_deposit #: view:account.check.deposit:account_check_deposit.view_check_deposit_search @@ -219,7 +219,7 @@ msgstr "Diario" #. module: account_check_deposit #: field:account.check.deposit,move_id:0 msgid "Journal Entry" -msgstr "" +msgstr "Asiento contable" #. module: account_check_deposit #: model:ir.model,name:account_check_deposit.model_account_move_line diff --git a/account_check_deposit/i18n/hr.po b/account_check_deposit/i18n/hr.po index 23e8b889c..0daf86f12 100644 --- a/account_check_deposit/i18n/hr.po +++ b/account_check_deposit/i18n/hr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: account-financial-tools (8.0)\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-07-01 13:26+0000\n" +"POT-Creation-Date: 2015-10-20 18:44+0000\n" "PO-Revision-Date: 2015-06-03 15:58+0000\n" "Last-Translator: <>\n" "Language-Team: Croatian (http://www.transifex.com/oca/OCA-account-financial-tools-8-0/language/hr/)\n" @@ -208,7 +208,7 @@ msgstr "" #. module: account_check_deposit #: field:account.check.deposit,id:0 msgid "ID" -msgstr "" +msgstr "ID" #. module: account_check_deposit #: view:account.check.deposit:account_check_deposit.view_check_deposit_search From 24b77d32394d3de38c232cdefb850a08408bcf24 Mon Sep 17 00:00:00 2001 From: Alexis de Lattre Date: Fri, 30 Oct 2015 14:20:19 +0100 Subject: [PATCH 02/28] account_check_deposit : Port to new API Move description from __openerp__.py to README.rst --- account_check_deposit/README.rst | 69 ++++ account_check_deposit/__init__.py | 19 - account_check_deposit/__manifest__.py | 14 +- account_check_deposit/account_data.xml | 10 - account_check_deposit/account_deposit.py | 333 +++++++----------- .../account_deposit_sequence.xml | 2 +- .../account_deposit_view.xml | 7 +- 7 files changed, 210 insertions(+), 244 deletions(-) create mode 100644 account_check_deposit/README.rst diff --git a/account_check_deposit/README.rst b/account_check_deposit/README.rst new file mode 100644 index 000000000..12fb31dca --- /dev/null +++ b/account_check_deposit/README.rst @@ -0,0 +1,69 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + +============= +Check Deposit +============= + +This module allows you to easily manage check deposits : you can select all +the checks you received and create a global deposit for the +selected checks. This module supports multi-currency ; each deposit has a currency +and all the checks of the deposit must have the same currency +(so, if you have checks in EUR and checks in USD, you must create 2 deposits : +one in EUR and one in USD). + +Configuration +============= + +A journal named *Check Received* is automatically created. It will be available as a payment method in Odoo. On this journal, you must configure the *Default Debit Account* and *Defaut Credit Account* ; this is the account via which the amounts of checks will transit between the reception of a check from a customer and the validation of the check deposit in Odoo. + +On the company form view, you should configure the *Account for Check Deposits* ; this is the account via which the amounts of checks will transit between the validation of the check deposit in Odoo and the credit on the bank account. + +Usage +===== + +When you receive a check that pays a customer invoice, you can go to that invoice and click on the button *Register Payment* and select the *Check Received* journal as *Payment Method*. + +When you want to deposit checks to the bank, go to the menu *Accounting > Bank and Cash > Check Deposit*, create a new check deposit and set the journal *Checks Received* and select the bank account on which you want to credit the checks. Then click on *Add an item* to select the checks you want to deposit at the bank. Eventually, validate the deposit and print the report (you probably want to customize this report). + +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/92/8.0 + +For further information, please visit: + + * https://www.odoo.com/forum/help-1 + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed feedback +`here `_. + +Credits +======= + +Contributors +------------ + +* Benoît GUILLOT +* Chafique DELLI +* Alexis de Lattre + +Maintainer +---------- + +.. image:: http://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: http://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +To contribute to this module, please visit http://odoo-community.org. diff --git a/account_check_deposit/__init__.py b/account_check_deposit/__init__.py index f1c1297b1..a98c879ff 100644 --- a/account_check_deposit/__init__.py +++ b/account_check_deposit/__init__.py @@ -1,22 +1,3 @@ # -*- coding: utf-8 -*- -############################################################################### -# -# account_check_deposit for Odoo/OpenERP -# Copyright (C) 2012-2015 Akretion (http://www.akretion.com/) -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################### from . import account_deposit diff --git a/account_check_deposit/__manifest__.py b/account_check_deposit/__manifest__.py index 1536a39ed..f387103ec 100644 --- a/account_check_deposit/__manifest__.py +++ b/account_check_deposit/__manifest__.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- ############################################################################### # -# account_check_deposit for Odoo/OpenERP +# account_check_deposit for Odoo # Copyright (C) 2012-2015 Akretion (http://www.akretion.com/) # @author: Benoît GUILLOT # @author: Chafique DELLI @@ -28,18 +28,6 @@ 'category': 'Accounting & Finance', 'license': 'AGPL-3', 'summary': 'Manage deposit of checks to the bank', - 'description': """ -Account Check Deposit -===================== -This module allows you to easily manage check deposits : you can select all -the checks you received as payments and create a global deposit for the -selected checks. - -A journal for received checks is automatically created. -You must configure on this journal the default debit account and the default -credit account. You must also configure on the company the account for -check deposits. -""", 'author': "Akretion,Odoo Community Association (OCA)", 'website': 'http://www.akretion.com/', 'depends': [ diff --git a/account_check_deposit/account_data.xml b/account_check_deposit/account_data.xml index 141123f54..a2c525ec6 100644 --- a/account_check_deposit/account_data.xml +++ b/account_check_deposit/account_data.xml @@ -1,6 +1,5 @@ Check Received CHK bank - diff --git a/account_check_deposit/account_deposit.py b/account_check_deposit/account_deposit.py index cdc0fbd2c..8f40887b0 100644 --- a/account_check_deposit/account_deposit.py +++ b/account_check_deposit/account_deposit.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- ############################################################################### # -# account_check_deposit for Odoo/OpenERP +# account_check_deposit for Odoo # Copyright (C) 2012-2015 Akretion (http://www.akretion.com/) # @author: Benoît GUILLOT # @author: Chafique DELLI @@ -22,19 +22,24 @@ # ############################################################################### -from openerp.osv import fields, orm -from openerp.tools.translate import _ +from openerp import models, fields, api, _ import openerp.addons.decimal_precision as dp +from openerp.exceptions import ValidationError +from openerp.exceptions import Warning as UserError -class account_check_deposit(orm.Model): +class AccountCheckDeposit(models.Model): _name = "account.check.deposit" _description = "Account Check Deposit" _order = 'deposit_date desc' - def _compute_check_deposit(self, cr, uid, ids, name, args, context=None): - res = {} - for deposit in self.browse(cr, uid, ids, context=context): + @api.multi + @api.depends( + 'company_id', 'currency_id', 'check_payment_ids.debit', + 'check_payment_ids.amount_currency', + 'move_id.line_id.reconcile_id') + def _compute_check_deposit(self): + for deposit in self: total = 0.0 count = 0 reconcile = False @@ -51,82 +56,70 @@ class account_check_deposit(orm.Model): for line in deposit.move_id.line_id: if line.debit > 0 and line.reconcile_id: reconcile = True - res[deposit.id] = { - 'total_amount': total, - 'is_reconcile': reconcile, - 'currency_none_same_company_id': currency_none_same_company_id, - 'check_count': count, - } - return res + deposit.total_amount = total + deposit.is_reconcile = reconcile + deposit.currency_none_same_company_id =\ + currency_none_same_company_id + deposit.check_count = count - _columns = { - 'name': fields.char( - 'Name', size=64, readonly=True), - 'check_payment_ids': fields.one2many( - 'account.move.line', 'check_deposit_id', 'Check Payments', - states={'done': [('readonly', '=', True)]}), - 'deposit_date': fields.date( - 'Deposit Date', required=True, - states={'done': [('readonly', '=', True)]}), - 'journal_id': fields.many2one( - 'account.journal', 'Journal', domain=[('type', '=', 'bank')], - required=True, states={'done': [('readonly', '=', True)]}), - 'journal_default_account_id': fields.related( - 'journal_id', 'default_debit_account_id', type='many2one', - relation='account.account', - string='Default Debit Account of the Journal'), - 'currency_id': fields.many2one( - 'res.currency', 'Currency', required=True, - states={'done': [('readonly', '=', True)]}), - 'currency_none_same_company_id': fields.function( - _compute_check_deposit, type='many2one', - relation='res.currency', multi='deposit', - string='Currency (False if same as company)'), - 'state': fields.selection([ - ('draft', 'Draft'), - ('done', 'Done'), - ], 'Status', readonly=True), - 'move_id': fields.many2one( - 'account.move', 'Journal Entry', readonly=True), - 'partner_bank_id': fields.many2one( - 'res.partner.bank', 'Bank Account', required=True, - domain="[('company_id', '=', company_id)]", - states={'done': [('readonly', '=', True)]}), - 'line_ids': fields.related( - 'move_id', 'line_id', relation='account.move.line', - type='one2many', string='Lines', readonly=True), - 'company_id': fields.many2one( - 'res.company', 'Company', required=True, - change_default=True, - states={'done': [('readonly', '=', True)]}), - 'total_amount': fields.function( - _compute_check_deposit, multi='deposit', - string="Total Amount", readonly=True, - type="float", digits_compute=dp.get_precision('Account')), - 'check_count': fields.function( - _compute_check_deposit, multi='deposit', readonly=True, - string="Number of Checks", type="integer"), - 'is_reconcile': fields.function( - _compute_check_deposit, multi='deposit', readonly=True, - string="Reconcile", type="boolean"), - } + name = fields.Char(string='Name', size=64, readonly=True, default='/') + check_payment_ids = fields.One2many( + 'account.move.line', '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) + journal_id = fields.Many2one( + 'account.journal', string='Journal', domain=[('type', '=', 'bank')], + required=True, states={'done': [('readonly', '=', True)]}) + journal_default_account_id = fields.Many2one( + 'account.account', related='journal_id.default_debit_account_id', + string='Default Debit Account of the Journal') + currency_id = fields.Many2one( + 'res.currency', string='Currency', required=True, + states={'done': [('readonly', '=', True)]}) + currency_none_same_company_id = fields.Many2one( + 'res.currency', compute='_compute_check_deposit', + string='Currency (False if same as company)') + state = fields.Selection([ + ('draft', 'Draft'), + ('done', 'Done'), + ], string='Status', default='draft', readonly=True) + move_id = fields.Many2one( + 'account.move', string='Journal Entry', readonly=True) + partner_bank_id = fields.Many2one( + 'res.partner.bank', string='Bank Account', required=True, + domain="[('company_id', '=', company_id)]", + states={'done': [('readonly', '=', True)]}) + line_ids = fields.One2many( + 'account.move.line', related='move_id.line_id', + string='Lines', readonly=True) + company_id = fields.Many2one( + 'res.company', string='Company', required=True, + states={'done': [('readonly', '=', True)]}, + default=lambda self: self.env['res.company']._company_default_get( + 'account.check.deposit')) + total_amount = fields.Float( + compute='_compute_check_deposit', + string="Total Amount", readonly=True, + digits=dp.get_precision('Account')) + check_count = fields.Integer( + compute='_compute_check_deposit', readonly=True, + string="Number of Checks") + is_reconcile = fields.Boolean( + compute='_compute_check_deposit', readonly=True, + string="Reconcile") - _defaults = { - 'name': '/', - 'deposit_date': fields.date.context_today, - 'state': 'draft', - 'company_id': lambda self, cr, uid, c: self.pool['res.company']. - _company_default_get(cr, uid, 'account.check.deposit', context=c), - } - - def _check_deposit(self, cr, uid, ids): - for deposit in self.browse(cr, uid, ids): + @api.multi + @api.constrains('currency_id', 'check_payment_ids', 'company_id') + def _check_deposit(self): + for deposit in self: deposit_currency = deposit.currency_id if deposit_currency == deposit.company_id.currency_id: for line in deposit.check_payment_ids: if line.currency_id: - raise orm.except_orm( - _('Error:'), + raise ValidationError( _("The check with amount %s and reference '%s' " "is in currency %s but the deposit is in " "currency %s.") % ( @@ -136,35 +129,27 @@ class account_check_deposit(orm.Model): else: for line in deposit.check_payment_ids: if line.currency_id != deposit_currency: - raise orm.except_orm( - _('Error:'), + 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)) - return True - _constraints = [( - _check_deposit, - "All the checks of the deposit must be in the currency of the deposit", - ['currency_id', 'check_payment_ids', 'company_id'] - )] - - def unlink(self, cr, uid, ids, context=None): - for deposit in self.browse(cr, uid, ids, context=context): + @api.multi + def unlink(self): + for deposit in self: if deposit.state == 'done': - raise orm.except_orm( - _('Error!'), + raise UserError( _("The deposit '%s' is in valid state, so you must " "cancel it before deleting it.") % deposit.name) - return super(account_check_deposit, self).unlink( - cr, uid, ids, context=context) + return super(AccountCheckDeposit, self).unlink() - def backtodraft(self, cr, uid, ids, context=None): - for deposit in self.browse(cr, uid, ids, context=context): + @api.multi + def backtodraft(self): + for deposit in self: if deposit.move_id: # It will raise here if journal_id.update_posted = False deposit.move_id.button_cancel() @@ -175,29 +160,30 @@ class account_check_deposit(orm.Model): deposit.write({'state': 'draft'}) return True - def create(self, cr, uid, vals, context=None): + @api.model + def create(self, vals): if vals.get('name', '/') == '/': - vals['name'] = self.pool['ir.sequence'].\ - next_by_code(cr, uid, 'account.check.deposit') - return super(account_check_deposit, self).\ - create(cr, uid, vals, context=context) + vals['name'] = self.env['ir.sequence'].\ + next_by_code('account.check.deposit') + return super(AccountCheckDeposit, self).create(vals) - def _prepare_account_move_vals(self, cr, uid, deposit, context=None): + @api.model + def _prepare_account_move_vals(self, deposit): date = deposit.deposit_date - period_obj = self.pool['account.period'] - period_ids = period_obj.find(cr, uid, dt=date, context=context) + period_obj = self.env['account.period'] + period_ids = period_obj.find(dt=date) # period_ids will always have a value, cf the code of find() move_vals = { 'journal_id': deposit.journal_id.id, 'date': date, - 'period_id': period_ids[0], + 'period_id': period_ids[0].id, 'name': _('Check Deposit %s') % deposit.name, 'ref': deposit.name, } return move_vals - def _prepare_move_line_vals( - self, cr, uid, line, context=None): + @api.model + def _prepare_move_line_vals(self, line): assert (line.debit > 0), 'Debit must have a value' return { 'name': _('Check Deposit - Ref. Check %s') % line.ref, @@ -209,9 +195,9 @@ class account_check_deposit(orm.Model): 'amount_currency': line.amount_currency * -1, } + @api.model def _prepare_counterpart_move_lines_vals( - self, cr, uid, deposit, total_debit, total_amount_currency, - context=None): + self, deposit, total_debit, total_amount_currency): return { 'name': _('Check Deposit %s') % deposit.name, 'debit': total_debit, @@ -222,119 +208,74 @@ class account_check_deposit(orm.Model): 'amount_currency': total_amount_currency, } - def validate_deposit(self, cr, uid, ids, context=None): - am_obj = self.pool['account.move'] - aml_obj = self.pool['account.move.line'] - if context is None: - context = {} - for deposit in self.browse(cr, uid, ids, context=context): - move_vals = self._prepare_account_move_vals( - cr, uid, deposit, context=context) - context['journal_id'] = move_vals['journal_id'] - context['period_id'] = move_vals['period_id'] - move_id = am_obj.create(cr, uid, move_vals, context=context) + @api.multi + def validate_deposit(self): + am_obj = self.env['account.move'] + aml_obj = self.env['account.move.line'] + for deposit in self: + move_vals = self._prepare_account_move_vals(deposit) + move = am_obj.create(move_vals) total_debit = 0.0 total_amount_currency = 0.0 - to_reconcile_line_ids = [] + to_reconcile_lines = [] for line in deposit.check_payment_ids: total_debit += line.debit total_amount_currency += line.amount_currency - line_vals = self._prepare_move_line_vals( - cr, uid, line, context=context) - line_vals['move_id'] = move_id - move_line_id = aml_obj.create( - cr, uid, line_vals, context=context) - to_reconcile_line_ids.append([line.id, move_line_id]) + line_vals = self._prepare_move_line_vals(line) + line_vals['move_id'] = move.id + move_line = aml_obj.create(line_vals) + to_reconcile_lines.append(line + move_line) # Create counter-part if not deposit.company_id.check_deposit_account_id: - raise orm.except_orm( - _('Configuration Error:'), + raise UserError( _("Missing Account for Check Deposits on the " "company '%s'.") % deposit.company_id.name) counter_vals = self._prepare_counterpart_move_lines_vals( - cr, uid, deposit, total_debit, total_amount_currency, - context=context) - counter_vals['move_id'] = move_id - aml_obj.create(cr, uid, counter_vals, context=context) + deposit, total_debit, total_amount_currency) + counter_vals['move_id'] = move.id + aml_obj.create(counter_vals) - am_obj.post(cr, uid, [move_id], context=context) - deposit.write({'state': 'done', 'move_id': move_id}) + move.post() + deposit.write({'state': 'done', 'move_id': move.id}) # We have to reconcile after post() - for reconcile_line_ids in to_reconcile_line_ids: - aml_obj.reconcile( - cr, uid, reconcile_line_ids, context=context) + for reconcile_lines in to_reconcile_lines: + reconcile_lines.reconcile() return True - def onchange_company_id( - self, cr, uid, ids, company_id, currency_id, context=None): - vals = {} - if company_id: - company = self.pool['res.company'].browse( - cr, uid, company_id, context=context) - if currency_id: - if company.currency_id.id == currency_id: - vals['currency_none_same_company_id'] = False - else: - vals['currency_none_same_company_id'] = currency_id - partner_bank_ids = self.pool['res.partner.bank'].search( - cr, uid, [('company_id', '=', company_id)], context=context) - if len(partner_bank_ids) == 1: - vals['partner_bank_id'] = partner_bank_ids[0] + @api.onchange('company_id') + def onchange_company_id(self): + if self.company_id: + partner_banks = self.env['res.partner.bank'].search( + [('company_id', '=', self.company_id.id)]) + if len(partner_banks) == 1: + self.partner_bank_id = partner_banks[0] else: - vals['currency_none_same_company_id'] = False - vals['partner_bank_id'] = False - return {'value': vals} + self.partner_bank_id = False - def onchange_journal_id(self, cr, uid, ids, journal_id, context=None): - vals = {} - if journal_id: - journal = self.pool['account.journal'].browse( - cr, uid, journal_id, context=context) - vals['journal_default_account_id'] = \ - journal.default_debit_account_id.id - if journal.currency: - vals['currency_id'] = journal.currency.id + @api.onchange('journal_id') + def onchange_journal_id(self): + if self.journal_id: + if self.journal_id.currency: + self.currency_id = self.journal_id.currency else: - vals['currency_id'] = journal.company_id.currency_id.id - else: - vals['journal_default_account_id'] = False - return {'value': vals} - - def onchange_currency_id( - self, cr, uid, ids, currency_id, company_id, context=None): - vals = {} - if currency_id and company_id: - company = self.pool['res.company'].browse( - cr, uid, company_id, context=context) - if company.currency_id.id == currency_id: - vals['currency_none_same_company_id'] = False - else: - vals['currency_none_same_company_id'] = currency_id - else: - vals['currency_none_same_company_id'] = False - return {'value': vals} + self.currency_id = self.journal_id.company_id.currency_id -class account_move_line(orm.Model): +class AccountMoveLine(models.Model): _inherit = "account.move.line" - _columns = { - 'check_deposit_id': fields.many2one( - 'account.check.deposit', - 'Check Deposit'), - } + check_deposit_id = fields.Many2one( + 'account.check.deposit', string='Check Deposit', copy=False) -class res_company(orm.Model): +class ResCompany(models.Model): _inherit = 'res.company' - _columns = { - 'check_deposit_account_id': fields.many2one( - 'account.account', 'Account for Check Deposits', - domain=[ - ('type', '<>', 'view'), - ('type', '<>', 'closed'), - ('reconcile', '=', True)]), - } + check_deposit_account_id = fields.Many2one( + 'account.account', string='Account for Check Deposits', copy=False, + domain=[ + ('type', '<>', 'view'), + ('type', '<>', 'closed'), + ('reconcile', '=', True)]) diff --git a/account_check_deposit/account_deposit_sequence.xml b/account_check_deposit/account_deposit_sequence.xml index 47a53f88e..07c4c13bd 100644 --- a/account_check_deposit/account_deposit_sequence.xml +++ b/account_check_deposit/account_deposit_sequence.xml @@ -1,6 +1,6 @@ - - Account Check Deposit - account.check.deposit - - Account Check Deposit account.check.deposit diff --git a/account_check_deposit/models/account_deposit.py b/account_check_deposit/models/account_deposit.py index 980a61b0c..a1cf3a1d2 100644 --- a/account_check_deposit/models/account_deposit.py +++ b/account_check_deposit/models/account_deposit.py @@ -37,7 +37,7 @@ class AccountCheckDeposit(models.Model): @api.depends( 'company_id', 'currency_id', 'check_payment_ids.debit', 'check_payment_ids.amount_currency', - 'move_id.line_id.reconcile_id') + 'move_id.line_ids.reconciled') def _compute_check_deposit(self): for deposit in self: total = 0.0 @@ -53,8 +53,8 @@ class AccountCheckDeposit(models.Model): else: total += line.debit if deposit.move_id: - for line in deposit.move_id.line_id: - if line.debit > 0 and line.reconcile_id: + for line in deposit.move_id.line_ids: + if line.debit > 0 and line.reconciled: reconcile = True deposit.total_amount = total deposit.is_reconcile = reconcile @@ -64,8 +64,8 @@ class AccountCheckDeposit(models.Model): name = fields.Char(string='Name', size=64, readonly=True, default='/') check_payment_ids = fields.One2many( - 'account.move.line', 'check_deposit_id', string='Check Payments', - states={'done': [('readonly', '=', True)]}) + 'account.move.line', 'check_deposit_id', string='Check Payments',) + # states={'done': [('readonly', '=', True)]}) deposit_date = fields.Date( string='Deposit Date', required=True, states={'done': [('readonly', '=', True)]}, @@ -93,7 +93,7 @@ class AccountCheckDeposit(models.Model): domain="[('company_id', '=', company_id)]", states={'done': [('readonly', '=', True)]}) line_ids = fields.One2many( - 'account.move.line', related='move_id.line_id', + 'account.move.line', related='move_id.line_ids', string='Lines', readonly=True) company_id = fields.Many2one( 'res.company', string='Company', required=True, @@ -154,8 +154,8 @@ class AccountCheckDeposit(models.Model): # It will raise here if journal_id.update_posted = False deposit.move_id.button_cancel() for line in deposit.check_payment_ids: - if line.reconcile_id: - line.reconcile_id.unlink() + if line.reconciled: + line.remove_move_reconcile() deposit.move_id.unlink() deposit.write({'state': 'draft'}) return True @@ -170,16 +170,12 @@ class AccountCheckDeposit(models.Model): @api.model def _prepare_account_move_vals(self, deposit): date = deposit.deposit_date - period_obj = self.env['account.period'] - period_ids = period_obj.find(dt=date) - # period_ids will always have a value, cf the code of find() move_vals = { 'journal_id': deposit.journal_id.id, 'date': date, - 'period_id': period_ids[0].id, 'name': _('Check Deposit %s') % deposit.name, 'ref': deposit.name, - } + } return move_vals @api.model @@ -257,8 +253,8 @@ class AccountCheckDeposit(models.Model): @api.onchange('journal_id') def onchange_journal_id(self): if self.journal_id: - if self.journal_id.currency: - self.currency_id = self.journal_id.currency + if self.journal_id.currency_id: + self.currency_id = self.journal_id.currency_id else: self.currency_id = self.journal_id.company_id.currency_id @@ -275,7 +271,4 @@ class ResCompany(models.Model): check_deposit_account_id = fields.Many2one( 'account.account', string='Account for Check Deposits', copy=False, - domain=[ - ('type', '<>', 'view'), - ('type', '<>', 'closed'), - ('reconcile', '=', True)]) + domain=[('reconcile', '=', True)]) diff --git a/account_check_deposit/views/account_deposit_view.xml b/account_check_deposit/views/account_deposit_view.xml index fd58b77f9..f09700ef8 100644 --- a/account_check_deposit/views/account_deposit_view.xml +++ b/account_check_deposit/views/account_deposit_view.xml @@ -55,7 +55,7 @@ ', 0), ('check_deposit_id', '=', False), ('currency_id', '=', currency_none_same_company_id), @@ -119,7 +119,7 @@ From fc97241847b14945776394e619a328e872d92030 Mon Sep 17 00:00:00 2001 From: Mourad Elhadj Mimoune Date: Tue, 7 Jun 2016 14:46:08 +0200 Subject: [PATCH 19/28] create move and move line at the same time --- .../models/account_deposit.py | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/account_check_deposit/models/account_deposit.py b/account_check_deposit/models/account_deposit.py index a1cf3a1d2..97ff31e8c 100644 --- a/account_check_deposit/models/account_deposit.py +++ b/account_check_deposit/models/account_deposit.py @@ -64,8 +64,8 @@ class AccountCheckDeposit(models.Model): name = fields.Char(string='Name', size=64, readonly=True, default='/') check_payment_ids = fields.One2many( - 'account.move.line', 'check_deposit_id', string='Check Payments',) - # states={'done': [('readonly', '=', True)]}) + 'account.move.line', 'check_deposit_id', string='Check Payments', + states={'done': [('readonly', '=', True)]}) deposit_date = fields.Date( string='Deposit Date', required=True, states={'done': [('readonly', '=', True)]}, @@ -82,9 +82,10 @@ class AccountCheckDeposit(models.Model): currency_none_same_company_id = fields.Many2one( 'res.currency', compute='_compute_check_deposit', string='Currency (False if same as company)') - state = fields.Selection([ - ('draft', 'Draft'), - ('done', 'Done'), + state = fields.Selection( + [ + ('draft', 'Draft'), + ('done', 'Done'), ], string='Status', default='draft', readonly=True) move_id = fields.Many2one( 'account.move', string='Journal Entry', readonly=True) @@ -189,7 +190,7 @@ class AccountCheckDeposit(models.Model): 'partner_id': line.partner_id.id, 'currency_id': line.currency_id.id or False, 'amount_currency': line.amount_currency * -1, - } + } @api.model def _prepare_counterpart_move_lines_vals( @@ -202,25 +203,24 @@ class AccountCheckDeposit(models.Model): 'partner_id': False, 'currency_id': deposit.currency_none_same_company_id.id or False, 'amount_currency': total_amount_currency, - } + } @api.multi def validate_deposit(self): am_obj = self.env['account.move'] - aml_obj = self.env['account.move.line'] for deposit in self: move_vals = self._prepare_account_move_vals(deposit) - move = am_obj.create(move_vals) total_debit = 0.0 total_amount_currency = 0.0 to_reconcile_lines = [] + mv_lines_vals = [] for line in deposit.check_payment_ids: total_debit += line.debit total_amount_currency += line.amount_currency line_vals = self._prepare_move_line_vals(line) - line_vals['move_id'] = move.id - move_line = aml_obj.create(line_vals) - to_reconcile_lines.append(line + move_line) + mv_lines_vals.append((0, 0, line_vals)) + + to_reconcile_lines.append(line) # Create counter-part if not deposit.company_id.check_deposit_account_id: @@ -230,8 +230,10 @@ class AccountCheckDeposit(models.Model): counter_vals = self._prepare_counterpart_move_lines_vals( deposit, total_debit, total_amount_currency) - counter_vals['move_id'] = move.id - aml_obj.create(counter_vals) + mv_lines_vals.append((0, 0, counter_vals)) + move_vals['line_ids'] = mv_lines_vals + move = am_obj.create(move_vals) + to_reconcile_lines.extend(move.line_ids) move.post() deposit.write({'state': 'done', 'move_id': move.id}) From d582e70266b71e7aaf0cc269acec16b486410432 Mon Sep 17 00:00:00 2001 From: Mourad Elhadj Mimoune Date: Tue, 7 Jun 2016 16:31:50 +0200 Subject: [PATCH 20/28] add tests --- account_check_deposit/tests/__init__.py | 2 + .../tests/test_check_deposit.py | 223 ++++++++++++++++++ 2 files changed, 225 insertions(+) create mode 100644 account_check_deposit/tests/__init__.py create mode 100644 account_check_deposit/tests/test_check_deposit.py diff --git a/account_check_deposit/tests/__init__.py b/account_check_deposit/tests/__init__.py new file mode 100644 index 000000000..841522611 --- /dev/null +++ b/account_check_deposit/tests/__init__.py @@ -0,0 +1,2 @@ + +from . import test_check_deposit diff --git a/account_check_deposit/tests/test_check_deposit.py b/account_check_deposit/tests/test_check_deposit.py new file mode 100644 index 000000000..d3b2080dd --- /dev/null +++ b/account_check_deposit/tests/test_check_deposit.py @@ -0,0 +1,223 @@ +from openerp.addons.account.tests.account_test_classes\ + import AccountingTestCase +import time + + +class TestPayment(AccountingTestCase): + + def setUp(self): + super(TestPayment, self).setUp() + self.register_payments_model = self.env['account.register.payments'] + self.payment_model = self.env['account.payment'] + self.journal_model = self.env['account.journal'] + self.account_account_model = self.env['account.account'] + self.invoice_model = self.env['account.invoice'] + self.invoice_line_model = self.env['account.invoice.line'] + self.acc_bank_stmt_model = self.env['account.bank.statement'] + self.acc_bank_stmt_line_model = self.env['account.bank.statement.line'] + + self.partner_agrolait = self.env.ref("base.res_partner_2") + self.currency_eur_id = self.env.ref("base.EUR").id + self.env.ref('base.main_company').write( + {'currency_id': self.currency_eur_id}) + self.product = self.env.ref("product.product_product_4") + self.payment_method_manual_in = self.env.ref( + "account.account_payment_method_manual_in") + self.payment_method_manual_out = self.env.ref( + "account.account_payment_method_manual_out") + + self.account_receivable = self.env['account.account'].search( + [('user_type_id', '=', self.env.ref( + 'account.data_account_type_receivable').id)], limit=1) + self.account_payable = self.env['account.account'].search( + [('user_type_id', '=', self.env.ref( + 'account.data_account_type_payable').id)], limit=1) + self.account_revenue = self.env['account.account'].search( + [('user_type_id', '=', self.env.ref( + 'account.data_account_type_revenue').id)], limit=1) + + self.recived_check_account_id = self.account_account_model.search( + [('code', '=', '511200')], limit=1) + if not self.recived_check_account_id: + self.recived_check_account_id = self.account_account_model.create( + {"code": '511200', + "name": "Recived check - (test)", + "reconcile": True, + "user_type_id": + self.ref('account.data_account_type_liquidity') + }) + self.bank_account_id = self.account_account_model.search( + [('code', '=', '512001')], limit=1) + if not self.bank_account_id: + self.bank_account_id = self.account_account_model.create( + {"code": '512001', + "name": "Bank - (test)", + "reconcile": True, + "user_type_id": + self.ref('account.data_account_type_liquidity') + }) + + self.check_journal = self.journal_model.search( + [('code', '=', 'CHK')], limit=1) + if not self.check_journal: + self.check_journal = self.journal_model.create( + {'name': 'Recived check', 'type': 'bank', 'code': 'CHK'}) + self.check_journal.default_debit_account_id = \ + self.recived_check_account_id + self.bank_journal = self.journal_model.search( + [('code', '=', 'BNK1')], limit=1) + if not self.bank_journal: + self.bank_journal = self.journal_model.create( + {'name': 'Bank', 'type': 'bank', 'code': 'BNK1'}) + self.bank_journal.default_debit_account_id = self.bank_account_id + + def create_invoice(self, amount=100, type='out_invoice', currency_id=None): + """ Returns an open invoice """ + invoice = self.invoice_model.create({ + 'partner_id': self.partner_agrolait.id, + 'reference_type': 'none', + 'currency_id': currency_id, + 'name': type == 'out_invoice' + and 'invoice to client' or 'invoice to supplier', + 'account_id': self.account_receivable.id, + 'type': type, + 'date_invoice': time.strftime('%Y-%m-%d'), + }) + self.invoice_line_model.create({ + 'product_id': self.product.id, + 'quantity': 1, + 'price_unit': amount, + 'invoice_id': invoice.id, + 'name': 'something', + 'account_id': self.account_revenue.id, + }) + invoice.signal_workflow('invoice_open') + return invoice + + def reconcile( + self, + liquidity_aml, + amount=0.0, + amount_currency=0.0, + currency_id=None): + """ Reconcile a journal entry corresponding + to a payment with its bank statement line """ + bank_stmt = self.acc_bank_stmt_model.create({ + 'journal_id': liquidity_aml.journal_id.id, + 'date': time.strftime('%Y-%m-%d'), + }) + bank_stmt_line = self.acc_bank_stmt_line_model.create({ + 'name': 'payment', + 'statement_id': bank_stmt.id, + 'partner_id': self.partner_agrolait.id, + 'amount': amount, + 'amount_currency': amount_currency, + 'currency_id': currency_id, + 'date': time.strftime('%Y-%m-%d') + }) + + bank_stmt_line.process_reconciliation(payment_aml_rec=liquidity_aml) + return bank_stmt + + def check_journal_items(self, aml_recs, aml_dicts): + def compare_rec_dict(aml_rec, aml_dict): + return aml_rec.account_id.id == aml_dict['account_id'] \ + and round(aml_rec.debit, 2) == aml_dict['debit'] \ + and round(aml_rec.credit, 2) == aml_dict['credit'] \ + and round(aml_rec.amount_currency, 2) ==\ + aml_dict['amount_currency']\ + and aml_rec.currency_id.id == aml_dict['currency_id'] + + for aml_dict in aml_dicts: + # There is no unique key to identify journal items + # (an account_payment may create several lines + # in the same account), so to check the expected entries + # are created, we check there is a line + # matching for each dict of expected values + aml_rec = aml_recs.filtered( + lambda r: compare_rec_dict(r, aml_dict)) + self.assertEqual( + len(aml_rec), + 1, + "Expected a move line with values : %s" % + str(aml_dict)) + if aml_dict.get('currency_diff'): + if aml_rec.credit: + rec_ids = [r.id for r in aml_rec.matched_debit_ids] + else: + rec_ids = [r.id for r in aml_rec.matched_credit_ids] + currency_diff_move = self.env['account.move'].search( + [('rate_diff_partial_rec_id', 'in', rec_ids)]) + self.assertEqual(len(currency_diff_move), 1) + for currency_diff_line in currency_diff_move[0].line_ids: + if aml_dict.get('currency_diff') > 0: + if currency_diff_line.account_id.id == aml_rec.account_id.id: + self.assertAlmostEquals( + currency_diff_line.debit, aml_dict.get('currency_diff')) + else: + self.assertAlmostEquals( + currency_diff_line.credit, aml_dict.get('currency_diff')) + self.assertIn( + currency_diff_line.account_id.id, [ + self.diff_expense_account.id, self.diff_income_account.id]) + else: + if currency_diff_line.account_id.id == aml_rec.account_id.id: + self.assertAlmostEquals( + currency_diff_line.credit, abs( + aml_dict.get('currency_diff'))) + else: + self.assertAlmostEquals( + currency_diff_line.debit, abs( + aml_dict.get('currency_diff'))) + self.assertIn( + currency_diff_line.account_id.id, [ + self.diff_expense_account.id, self.diff_income_account.id]) + + def test_full_payment_process(self): + """ Create a payment for two invoices, post it and reconcile it with a bank statement """ + inv_1 = self.create_invoice( + amount=100, currency_id=self.currency_eur_id) + inv_2 = self.create_invoice( + amount=200, currency_id=self.currency_eur_id) + + ctx = { + 'active_model': 'account.invoice', + 'active_ids': [ + inv_1.id, + inv_2.id]} + register_payments = self.register_payments_model.with_context(ctx).create({ + 'payment_date': time.strftime('%Y-%m-%d'), + 'journal_id': self.check_journal.id, + 'payment_method_id': self.payment_method_manual_in.id, + }) + register_payments.create_payment() + payment = self.payment_model.search([], order="id desc", limit=1) + + self.assertAlmostEquals(payment.amount, 300) + self.assertEqual(payment.state, 'posted') + self.assertEqual(inv_1.state, 'paid') + self.assertEqual(inv_2.state, 'paid') + + self.check_journal_items(payment.move_line_ids, + [{'account_id': self.account_eur.id, + 'debit': 300.0, + 'credit': 0.0, + 'amount_currency': 0, + 'currency_id': False}, + {'account_id': inv_1.account_id.id, + 'debit': 0.0, + 'credit': 300.0, + 'amount_currency': 00, + 'currency_id': False}, + ]) + + liquidity_aml = payment.move_line_ids.filtered( + lambda r: r.account_id == self.account_eur) + bank_statement = self.reconcile(liquidity_aml, 200, 0, False) + + self.assertEqual(liquidity_aml.statement_id, bank_statement) + self.assertEqual( + liquidity_aml.move_id.statement_line_id, + bank_statement.line_ids[0]) + + self.assertEqual(payment.state, 'reconciled') From 9d12b8ea48e096f353778ec13654e5b2e8a7f4b9 Mon Sep 17 00:00:00 2001 From: Mourad Elhadj Mimoune Date: Thu, 9 Jun 2016 11:26:48 +0200 Subject: [PATCH 21/28] add tests --- account_check_deposit/README.rst | 1 + account_check_deposit/__manifest__.py | 13 +- .../models/account_deposit.py | 16 +- .../tests/test_check_deposit.py | 186 +++++++----------- 4 files changed, 75 insertions(+), 141 deletions(-) diff --git a/account_check_deposit/README.rst b/account_check_deposit/README.rst index 12fb31dca..fc0afa5b3 100644 --- a/account_check_deposit/README.rst +++ b/account_check_deposit/README.rst @@ -52,6 +52,7 @@ Contributors * Benoît GUILLOT * Chafique DELLI * Alexis de Lattre +* Mourad EL HADJ MIMOUNE Maintainer ---------- diff --git a/account_check_deposit/__manifest__.py b/account_check_deposit/__manifest__.py index ee20250f0..854713d08 100644 --- a/account_check_deposit/__manifest__.py +++ b/account_check_deposit/__manifest__.py @@ -7,18 +7,7 @@ # @author: Chafique DELLI # @author: Alexis de Lattre # -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # ############################################################################### diff --git a/account_check_deposit/models/account_deposit.py b/account_check_deposit/models/account_deposit.py index 97ff31e8c..076775c4d 100644 --- a/account_check_deposit/models/account_deposit.py +++ b/account_check_deposit/models/account_deposit.py @@ -2,23 +2,13 @@ ############################################################################### # # account_check_deposit for Odoo -# Copyright (C) 2012-2015 Akretion (http://www.akretion.com/) +# Copyright (C) 2012-2016 Akretion (http://www.akretion.com/) # @author: Benoît GUILLOT # @author: Chafique DELLI # @author: Alexis de Lattre +# @author: Mourad EL HADJ MIMOUNE # -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # ############################################################################### diff --git a/account_check_deposit/tests/test_check_deposit.py b/account_check_deposit/tests/test_check_deposit.py index d3b2080dd..cd6a5d0f2 100644 --- a/account_check_deposit/tests/test_check_deposit.py +++ b/account_check_deposit/tests/test_check_deposit.py @@ -1,3 +1,8 @@ +# -*- coding: utf-8 -*- +# © 2014-2016 Akretion (http://www.akretion.com) +# @author Mourad EL HADJ MIMOUNE +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + from openerp.addons.account.tests.account_test_classes\ import AccountingTestCase import time @@ -15,26 +20,40 @@ class TestPayment(AccountingTestCase): self.invoice_line_model = self.env['account.invoice.line'] self.acc_bank_stmt_model = self.env['account.bank.statement'] self.acc_bank_stmt_line_model = self.env['account.bank.statement.line'] + self.res_partner_bank_model = self.env['res.partner.bank'] + self.check_deposit_model = self.env['account.check.deposit'] self.partner_agrolait = self.env.ref("base.res_partner_2") self.currency_eur_id = self.env.ref("base.EUR").id - self.env.ref('base.main_company').write( - {'currency_id': self.currency_eur_id}) + self.main_company = self.env.ref('base.main_company') + self.main_company.write({'currency_id': self.currency_eur_id}) self.product = self.env.ref("product.product_product_4") self.payment_method_manual_in = self.env.ref( "account.account_payment_method_manual_in") self.payment_method_manual_out = self.env.ref( "account.account_payment_method_manual_out") + # check if those accounts exist otherwise create them + self.account_receivable = self.account_account_model.search( + [('code', '=', '411100')], limit=1) - self.account_receivable = self.env['account.account'].search( - [('user_type_id', '=', self.env.ref( - 'account.data_account_type_receivable').id)], limit=1) - self.account_payable = self.env['account.account'].search( - [('user_type_id', '=', self.env.ref( - 'account.data_account_type_payable').id)], limit=1) - self.account_revenue = self.env['account.account'].search( - [('user_type_id', '=', self.env.ref( - 'account.data_account_type_revenue').id)], limit=1) + if not self.account_receivable: + self.account_receivable = self.account_account_model.create( + {"code": '411100', + "name": "Debtors - (test)", + "reconcile": True, + "user_type_id": + self.ref('account.data_account_type_receivable') + }) + + self.account_revenue = self.account_account_model.search( + [('code', '=', '707100')], limit=1) + if not self.account_revenue: + self.account_revenue = self.account_account_model.create( + {"code": '707100', + "name": "Product Sales - (test)", + "user_type_id": + self.ref('account.data_account_type_revenue') + }) self.recived_check_account_id = self.account_account_model.search( [('code', '=', '511200')], limit=1) @@ -64,12 +83,22 @@ class TestPayment(AccountingTestCase): {'name': 'Recived check', 'type': 'bank', 'code': 'CHK'}) self.check_journal.default_debit_account_id = \ self.recived_check_account_id + self.check_journal.default_credit_account_id = \ + self.recived_check_account_id self.bank_journal = self.journal_model.search( [('code', '=', 'BNK1')], limit=1) if not self.bank_journal: self.bank_journal = self.journal_model.create( {'name': 'Bank', 'type': 'bank', 'code': 'BNK1'}) self.bank_journal.default_debit_account_id = self.bank_account_id + self.bank_journal.default_credit_account_id = self.bank_account_id + self.partner_bank_id = self.res_partner_bank_model.search( + [('partner_id', '=', self.main_company.partner_id.id)], limit=1) + 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, + }) def create_invoice(self, amount=100, type='out_invoice', currency_id=None): """ Returns an open invoice """ @@ -78,7 +107,7 @@ class TestPayment(AccountingTestCase): 'reference_type': 'none', 'currency_id': currency_id, 'name': type == 'out_invoice' - and 'invoice to client' or 'invoice to supplier', + and 'invoice to client' or 'invoice to supplier', 'account_id': self.account_receivable.id, 'type': type, 'date_invoice': time.strftime('%Y-%m-%d'), @@ -94,87 +123,23 @@ class TestPayment(AccountingTestCase): invoice.signal_workflow('invoice_open') return invoice - def reconcile( - self, - liquidity_aml, - amount=0.0, - amount_currency=0.0, - currency_id=None): - """ Reconcile a journal entry corresponding - to a payment with its bank statement line """ - bank_stmt = self.acc_bank_stmt_model.create({ - 'journal_id': liquidity_aml.journal_id.id, - 'date': time.strftime('%Y-%m-%d'), + def create_check_deposit( + self, move_lines): + """ Returns an validated check deposit """ + check_deposit = self.check_deposit_model.create({ + 'journal_id': self.bank_journal.id, + 'partner_bank_id': self.partner_bank_id.id, + 'deposit_date': time.strftime('%Y-%m-%d'), + 'currency_id': self.currency_eur_id, }) - bank_stmt_line = self.acc_bank_stmt_line_model.create({ - 'name': 'payment', - 'statement_id': bank_stmt.id, - 'partner_id': self.partner_agrolait.id, - 'amount': amount, - 'amount_currency': amount_currency, - 'currency_id': currency_id, - 'date': time.strftime('%Y-%m-%d') - }) - - bank_stmt_line.process_reconciliation(payment_aml_rec=liquidity_aml) - return bank_stmt - - def check_journal_items(self, aml_recs, aml_dicts): - def compare_rec_dict(aml_rec, aml_dict): - return aml_rec.account_id.id == aml_dict['account_id'] \ - and round(aml_rec.debit, 2) == aml_dict['debit'] \ - and round(aml_rec.credit, 2) == aml_dict['credit'] \ - and round(aml_rec.amount_currency, 2) ==\ - aml_dict['amount_currency']\ - and aml_rec.currency_id.id == aml_dict['currency_id'] - - for aml_dict in aml_dicts: - # There is no unique key to identify journal items - # (an account_payment may create several lines - # in the same account), so to check the expected entries - # are created, we check there is a line - # matching for each dict of expected values - aml_rec = aml_recs.filtered( - lambda r: compare_rec_dict(r, aml_dict)) - self.assertEqual( - len(aml_rec), - 1, - "Expected a move line with values : %s" % - str(aml_dict)) - if aml_dict.get('currency_diff'): - if aml_rec.credit: - rec_ids = [r.id for r in aml_rec.matched_debit_ids] - else: - rec_ids = [r.id for r in aml_rec.matched_credit_ids] - currency_diff_move = self.env['account.move'].search( - [('rate_diff_partial_rec_id', 'in', rec_ids)]) - self.assertEqual(len(currency_diff_move), 1) - for currency_diff_line in currency_diff_move[0].line_ids: - if aml_dict.get('currency_diff') > 0: - if currency_diff_line.account_id.id == aml_rec.account_id.id: - self.assertAlmostEquals( - currency_diff_line.debit, aml_dict.get('currency_diff')) - else: - self.assertAlmostEquals( - currency_diff_line.credit, aml_dict.get('currency_diff')) - self.assertIn( - currency_diff_line.account_id.id, [ - self.diff_expense_account.id, self.diff_income_account.id]) - else: - if currency_diff_line.account_id.id == aml_rec.account_id.id: - self.assertAlmostEquals( - currency_diff_line.credit, abs( - aml_dict.get('currency_diff'))) - else: - self.assertAlmostEquals( - currency_diff_line.debit, abs( - aml_dict.get('currency_diff'))) - self.assertIn( - currency_diff_line.account_id.id, [ - self.diff_expense_account.id, self.diff_income_account.id]) + for move_line in move_lines: + move_line.check_deposit_id = check_deposit + check_deposit.validate_deposit() + return check_deposit def test_full_payment_process(self): - """ Create a payment for two invoices, post it and reconcile it with a bank statement """ + """ Create a payment for on invoice by check, + post it and create check deposit""" inv_1 = self.create_invoice( amount=100, currency_id=self.currency_eur_id) inv_2 = self.create_invoice( @@ -185,11 +150,12 @@ class TestPayment(AccountingTestCase): 'active_ids': [ inv_1.id, inv_2.id]} - register_payments = self.register_payments_model.with_context(ctx).create({ - 'payment_date': time.strftime('%Y-%m-%d'), - 'journal_id': self.check_journal.id, - 'payment_method_id': self.payment_method_manual_in.id, - }) + register_payments = self.register_payments_model.with_context( + ctx).create({ + 'payment_date': time.strftime('%Y-%m-%d'), + 'journal_id': self.check_journal.id, + 'payment_method_id': self.payment_method_manual_in.id, + }) register_payments.create_payment() payment = self.payment_model.search([], order="id desc", limit=1) @@ -198,26 +164,14 @@ class TestPayment(AccountingTestCase): self.assertEqual(inv_1.state, 'paid') self.assertEqual(inv_2.state, 'paid') - self.check_journal_items(payment.move_line_ids, - [{'account_id': self.account_eur.id, - 'debit': 300.0, - 'credit': 0.0, - 'amount_currency': 0, - 'currency_id': False}, - {'account_id': inv_1.account_id.id, - 'debit': 0.0, - 'credit': 300.0, - 'amount_currency': 00, - 'currency_id': False}, - ]) + check_aml = payment.move_line_ids.filtered( + lambda r: r.account_id == self.recived_check_account_id) - liquidity_aml = payment.move_line_ids.filtered( - lambda r: r.account_id == self.account_eur) - bank_statement = self.reconcile(liquidity_aml, 200, 0, False) + check_deposit = self.create_check_deposit([check_aml]) + liquidity_aml = check_deposit.move_id.line_ids.filtered( + lambda r: r.account_id != self.recived_check_account_id) - self.assertEqual(liquidity_aml.statement_id, bank_statement) - self.assertEqual( - liquidity_aml.move_id.statement_line_id, - bank_statement.line_ids[0]) - - self.assertEqual(payment.state, 'reconciled') + self.assertEqual(check_deposit.total_amount, 300) + self.assertEqual(liquidity_aml.debit, 300) + self.assertEqual(check_deposit.move_id.state, 'posted') + self.assertEqual(check_deposit.state, 'done') From ef67df1098f6083b80eba31db9d565535a566a7c Mon Sep 17 00:00:00 2001 From: Mourad Elhadj Mimoune Date: Fri, 10 Jun 2016 11:09:58 +0200 Subject: [PATCH 22/28] tests: add check_deposit_account_id on company --- account_check_deposit/tests/test_check_deposit.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/account_check_deposit/tests/test_check_deposit.py b/account_check_deposit/tests/test_check_deposit.py index cd6a5d0f2..34beb3e91 100644 --- a/account_check_deposit/tests/test_check_deposit.py +++ b/account_check_deposit/tests/test_check_deposit.py @@ -65,6 +65,18 @@ class TestPayment(AccountingTestCase): "user_type_id": self.ref('account.data_account_type_liquidity') }) + self.main_company.check_deposit_account_id = \ + self.account_account_model.search( + [('code', '=', '511201')], limit=1) + if not self.main_company.check_deposit_account_id: + self.main_company.check_deposit_account_id = \ + self.account_account_model.create( + {"code": '511201', + "name": "Check deposited in bank - (test)", + "reconcile": True, + "user_type_id": + self.ref('account.data_account_type_liquidity') + }) self.bank_account_id = self.account_account_model.search( [('code', '=', '512001')], limit=1) if not self.bank_account_id: From f85fc449da1c1b701890ef219703a12a29ac3a50 Mon Sep 17 00:00:00 2001 From: Mourad Elhadj Mimoune Date: Fri, 10 Jun 2016 11:38:01 +0200 Subject: [PATCH 23/28] flake8 --- account_check_deposit/tests/test_check_deposit.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/account_check_deposit/tests/test_check_deposit.py b/account_check_deposit/tests/test_check_deposit.py index 34beb3e91..477dd8e3e 100644 --- a/account_check_deposit/tests/test_check_deposit.py +++ b/account_check_deposit/tests/test_check_deposit.py @@ -118,8 +118,8 @@ class TestPayment(AccountingTestCase): 'partner_id': self.partner_agrolait.id, 'reference_type': 'none', 'currency_id': currency_id, - 'name': type == 'out_invoice' - and 'invoice to client' or 'invoice to supplier', + 'name': type == 'out_invoice' and + 'invoice to client' or 'invoice to supplier', 'account_id': self.account_receivable.id, 'type': type, 'date_invoice': time.strftime('%Y-%m-%d'), From f3e2b159ae88f2bc97ad84a89c0f653638023987 Mon Sep 17 00:00:00 2001 From: Florian da Costa Date: Sun, 6 Nov 2016 15:33:05 +0100 Subject: [PATCH 24/28] Fix payment field + automatic reconciliation on validation --- .../models/account_deposit.py | 16 ++++++++-------- .../views/account_deposit_view.xml | 18 +++++++++++++++++- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/account_check_deposit/models/account_deposit.py b/account_check_deposit/models/account_deposit.py index 076775c4d..38f37feda 100644 --- a/account_check_deposit/models/account_deposit.py +++ b/account_check_deposit/models/account_deposit.py @@ -198,19 +198,21 @@ class AccountCheckDeposit(models.Model): @api.multi def validate_deposit(self): am_obj = self.env['account.move'] + move_line_obj = self.env['account.move.line'] for deposit in self: move_vals = self._prepare_account_move_vals(deposit) + move = am_obj.create(move_vals) total_debit = 0.0 total_amount_currency = 0.0 to_reconcile_lines = [] - mv_lines_vals = [] for line in deposit.check_payment_ids: total_debit += line.debit total_amount_currency += line.amount_currency line_vals = self._prepare_move_line_vals(line) - mv_lines_vals.append((0, 0, line_vals)) - - to_reconcile_lines.append(line) + line_vals['move_id'] = move.id + move_line = move_line_obj.with_context( + check_move_validity=False).create(line_vals) + to_reconcile_lines.append(line + move_line) # Create counter-part if not deposit.company_id.check_deposit_account_id: @@ -220,10 +222,8 @@ class AccountCheckDeposit(models.Model): counter_vals = self._prepare_counterpart_move_lines_vals( deposit, total_debit, total_amount_currency) - mv_lines_vals.append((0, 0, counter_vals)) - move_vals['line_ids'] = mv_lines_vals - move = am_obj.create(move_vals) - to_reconcile_lines.extend(move.line_ids) + counter_vals['move_id'] = move.id + move_line_obj.create(counter_vals) move.post() deposit.write({'state': 'done', 'move_id': move.id}) diff --git a/account_check_deposit/views/account_deposit_view.xml b/account_check_deposit/views/account_deposit_view.xml index f09700ef8..7d178d400 100644 --- a/account_check_deposit/views/account_deposit_view.xml +++ b/account_check_deposit/views/account_deposit_view.xml @@ -61,7 +61,23 @@ ('currency_id', '=', currency_none_same_company_id), ('account_id', '=', journal_default_account_id)]" context="{'currency': currency_id, - 'journal_id': journal_id}" /> + 'journal_id': journal_id}"> + + + + + + + + + + + + + + + + From 9f33f9770352206c63a6f98859448d278f810f80 Mon Sep 17 00:00:00 2001 From: Alexis de Lattre Date: Tue, 6 Dec 2016 08:52:08 +0100 Subject: [PATCH 25/28] Port account_check_deposit to v10 Add option to have the counter-part of the deposit move directly to the bank account Use account.config.settings page --- account_check_deposit/README.rst | 27 ++++--- account_check_deposit/__manifest__.py | 18 ++--- account_check_deposit/models/__init__.py | 2 + .../models/account_config_settings.py | 14 ++++ .../models/account_deposit.py | 77 ++++++++++--------- account_check_deposit/models/company.py | 22 ++++++ .../report/report_checkdeposit.xml | 8 +- .../views/account_config_settings.xml | 28 +++++++ .../views/account_deposit_view.xml | 4 +- account_check_deposit/views/company_view.xml | 25 ------ 10 files changed, 130 insertions(+), 95 deletions(-) create mode 100644 account_check_deposit/models/account_config_settings.py create mode 100644 account_check_deposit/models/company.py create mode 100644 account_check_deposit/views/account_config_settings.xml delete mode 100644 account_check_deposit/views/company_view.xml diff --git a/account_check_deposit/README.rst b/account_check_deposit/README.rst index fc0afa5b3..4b05315ef 100644 --- a/account_check_deposit/README.rst +++ b/account_check_deposit/README.rst @@ -18,30 +18,29 @@ Configuration A journal named *Check Received* is automatically created. It will be available as a payment method in Odoo. On this journal, you must configure the *Default Debit Account* and *Defaut Credit Account* ; this is the account via which the amounts of checks will transit between the reception of a check from a customer and the validation of the check deposit in Odoo. -On the company form view, you should configure the *Account for Check Deposits* ; this is the account via which the amounts of checks will transit between the validation of the check deposit in Odoo and the credit on the bank account. +On the Settings page of the Accounting, you should configure the *Check Deposit Offsetting Account*: + +* if you select *Bank Account*, the counter-part of the account move related to the check deposit will be the default debit account of the bank account selected on the check deposit. +* if you select *Transfer Account*, you will have to select a specific account that will be used as transfer account for check deposits. Usage ===== When you receive a check that pays a customer invoice, you can go to that invoice and click on the button *Register Payment* and select the *Check Received* journal as *Payment Method*. -When you want to deposit checks to the bank, go to the menu *Accounting > Bank and Cash > Check Deposit*, create a new check deposit and set the journal *Checks Received* and select the bank account on which you want to credit the checks. Then click on *Add an item* to select the checks you want to deposit at the bank. Eventually, validate the deposit and print the report (you probably want to customize this report). +When you want to deposit checks to the bank, go to the menu *Accounting > Adviser > Check Deposit*, create a new check deposit and set the journal *Checks Received* and select the bank account on which you want to credit the checks. Then click on *Add an item* to select the checks you want to deposit at the bank. Eventually, validate the deposit and print the report (you probably want to customize this report). .. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas :alt: Try me on Runbot - :target: https://runbot.odoo-community.org/runbot/92/8.0 - -For further information, please visit: - - * https://www.odoo.com/forum/help-1 + :target: https://runbot.odoo-community.org/runbot/92/10.0 Bug Tracker =========== -Bugs are tracked on `GitHub Issues `_. -In case of trouble, please check there if your issue has already been reported. -If you spotted it first, help us smashing it by providing a detailed and welcomed feedback -`here `_. +Bugs are tracked on `GitHub Issues +`_. In case of trouble, please +check there if your issue has already been reported. If you spotted it first, +help us smashing it by providing a detailed and welcomed feedback. Credits ======= @@ -57,9 +56,9 @@ Contributors Maintainer ---------- -.. image:: http://odoo-community.org/logo.png +.. image:: https://odoo-community.org/logo.png :alt: Odoo Community Association - :target: http://odoo-community.org + :target: https://odoo-community.org This module is maintained by the OCA. @@ -67,4 +66,4 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -To contribute to this module, please visit http://odoo-community.org. +To contribute to this module, please visit https://odoo-community.org. diff --git a/account_check_deposit/__manifest__.py b/account_check_deposit/__manifest__.py index 854713d08..19df0157e 100644 --- a/account_check_deposit/__manifest__.py +++ b/account_check_deposit/__manifest__.py @@ -1,19 +1,13 @@ # -*- coding: utf-8 -*- -############################################################################### -# -# account_check_deposit for Odoo -# Copyright (C) 2012-2015 Akretion (http://www.akretion.com/) -# @author: Benoît GUILLOT -# @author: Chafique DELLI -# @author: Alexis de Lattre -# +# © 2012-2015 Akretion (http://www.akretion.com/) +# @author: Benoît GUILLOT +# @author: Chafique DELLI +# @author: Alexis de Lattre # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -# -############################################################################### { 'name': 'Account Check Deposit', - 'version': '8.0.0.1.0', + 'version': '10.0.1.0.0', 'category': 'Accounting & Finance', 'license': 'AGPL-3', 'summary': 'Manage deposit of checks to the bank', @@ -26,7 +20,7 @@ 'views/account_deposit_view.xml', 'views/account_move_line_view.xml', 'data/account_deposit_sequence.xml', - 'views/company_view.xml', + 'views/account_config_settings.xml', 'security/ir.model.access.csv', 'security/check_deposit_security.xml', 'data/account_data.xml', diff --git a/account_check_deposit/models/__init__.py b/account_check_deposit/models/__init__.py index a98c879ff..2bec86b0c 100644 --- a/account_check_deposit/models/__init__.py +++ b/account_check_deposit/models/__init__.py @@ -1,3 +1,5 @@ # -*- coding: utf-8 -*- +from . import company +from . import account_config_settings from . import account_deposit diff --git a/account_check_deposit/models/account_config_settings.py b/account_check_deposit/models/account_config_settings.py new file mode 100644 index 000000000..51f3423fa --- /dev/null +++ b/account_check_deposit/models/account_config_settings.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +# © 2016 Akretion (Alexis de Lattre ) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import models, fields + + +class AccountConfigSettings(models.TransientModel): + _inherit = 'account.config.settings' + + check_deposit_offsetting_account = fields.Selection( + related='company_id.check_deposit_offsetting_account') + check_deposit_transfer_account_id = fields.Many2one( + related='company_id.check_deposit_transfer_account_id') diff --git a/account_check_deposit/models/account_deposit.py b/account_check_deposit/models/account_deposit.py index 38f37feda..c3ad7628d 100644 --- a/account_check_deposit/models/account_deposit.py +++ b/account_check_deposit/models/account_deposit.py @@ -1,21 +1,14 @@ # -*- coding: utf-8 -*- -############################################################################### -# -# account_check_deposit for Odoo -# Copyright (C) 2012-2016 Akretion (http://www.akretion.com/) -# @author: Benoît GUILLOT -# @author: Chafique DELLI -# @author: Alexis de Lattre -# @author: Mourad EL HADJ MIMOUNE -# +# © 2012-2016 Akretion (http://www.akretion.com/) +# @author: Benoît GUILLOT +# @author: Chafique DELLI +# @author: Alexis de Lattre +# @author: Mourad EL HADJ MIMOUNE # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -# -############################################################################### -from openerp import models, fields, api, _ -import openerp.addons.decimal_precision as dp -from openerp.exceptions import ValidationError -from openerp.exceptions import Warning as UserError +from odoo import models, fields, api, _ +import odoo.addons.decimal_precision as dp +from odoo.exceptions import ValidationError, UserError class AccountCheckDeposit(models.Model): @@ -61,7 +54,8 @@ class AccountCheckDeposit(models.Model): states={'done': [('readonly', '=', True)]}, default=fields.Date.context_today) journal_id = fields.Many2one( - 'account.journal', string='Journal', domain=[('type', '=', 'bank')], + 'account.journal', string='Journal', + domain=[('type', '=', 'bank'), ('bank_account_id', '=', False)], required=True, states={'done': [('readonly', '=', True)]}) journal_default_account_id = fields.Many2one( 'account.account', related='journal_id.default_debit_account_id', @@ -79,9 +73,10 @@ class AccountCheckDeposit(models.Model): ], string='Status', default='draft', readonly=True) move_id = fields.Many2one( 'account.move', string='Journal Entry', readonly=True) - partner_bank_id = fields.Many2one( - 'res.partner.bank', string='Bank Account', required=True, - domain="[('company_id', '=', company_id)]", + bank_journal_id = fields.Many2one( + 'account.journal', string='Bank Account', required=True, + domain="[('company_id', '=', company_id), ('type', '=', 'bank'), " + "('bank_account_id', '!=', False)]", states={'done': [('readonly', '=', True)]}) line_ids = fields.One2many( 'account.move.line', related='move_id.line_ids', @@ -185,11 +180,28 @@ class AccountCheckDeposit(models.Model): @api.model def _prepare_counterpart_move_lines_vals( self, deposit, total_debit, total_amount_currency): + company = deposit.company_id + if not company.check_deposit_offsetting_account: + raise UserError(_( + "You must configure the 'Check Deposit Offsetting Account' " + "on the Accounting Settings page")) + if company.check_deposit_offsetting_account == 'bank_account': + if not deposit.bank_journal_id.default_debit_account_id: + raise UserError(_( + "Missing 'Default Debit Account' on bank journal '%s'") + % deposit.bank_journal_id.name) + account_id = deposit.bank_journal_id.default_debit_account_id.id + elif company.check_deposit_offsetting_account == 'transfer_account': + if not company.check_deposit_transfer_account_id: + raise UserError(_( + "Missing 'Account for Check Deposits' on the " + "company '%s'.") % company.name) + account_id = company.check_deposit_transfer_account_id.id return { 'name': _('Check Deposit %s') % deposit.name, 'debit': total_debit, 'credit': 0.0, - 'account_id': deposit.company_id.check_deposit_account_id.id, + 'account_id': account_id, 'partner_id': False, 'currency_id': deposit.currency_none_same_company_id.id or False, 'amount_currency': total_amount_currency, @@ -215,11 +227,6 @@ class AccountCheckDeposit(models.Model): to_reconcile_lines.append(line + move_line) # Create counter-part - if not deposit.company_id.check_deposit_account_id: - raise UserError( - _("Missing Account for Check Deposits on the " - "company '%s'.") % deposit.company_id.name) - counter_vals = self._prepare_counterpart_move_lines_vals( deposit, total_debit, total_amount_currency) counter_vals['move_id'] = move.id @@ -235,12 +242,14 @@ class AccountCheckDeposit(models.Model): @api.onchange('company_id') def onchange_company_id(self): if self.company_id: - partner_banks = self.env['res.partner.bank'].search( - [('company_id', '=', self.company_id.id)]) - if len(partner_banks) == 1: - self.partner_bank_id = partner_banks[0] + bank_journals = self.env['account.journal'].search([ + ('company_id', '=', self.company_id.id), + ('type', '=', 'bank'), + ('bank_account_id', '!=', False)]) + if len(bank_journals) == 1: + self.bank_journal_id = bank_journals[0] else: - self.partner_bank_id = False + self.bank_journal_id = False @api.onchange('journal_id') def onchange_journal_id(self): @@ -256,11 +265,3 @@ class AccountMoveLine(models.Model): check_deposit_id = fields.Many2one( 'account.check.deposit', string='Check Deposit', copy=False) - - -class ResCompany(models.Model): - _inherit = 'res.company' - - check_deposit_account_id = fields.Many2one( - 'account.account', string='Account for Check Deposits', copy=False, - domain=[('reconcile', '=', True)]) diff --git a/account_check_deposit/models/company.py b/account_check_deposit/models/company.py new file mode 100644 index 000000000..f83c1ac7d --- /dev/null +++ b/account_check_deposit/models/company.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# © 2012-2016 Akretion (http://www.akretion.com/) +# @author: Benoît GUILLOT +# @author: Chafique DELLI +# @author: Alexis de Lattre +# @author: Mourad EL HADJ MIMOUNE +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import models, fields + + +class ResCompany(models.Model): + _inherit = 'res.company' + + check_deposit_offsetting_account = fields.Selection([ + ('bank_account', 'Bank Account'), + ('transfer_account', 'Transfer Account'), + ], string='Check Deposit Offsetting Account', default='bank_account') + check_deposit_transfer_account_id = fields.Many2one( + 'account.account', string='Transfer Account for Check Deposits', + ondelete='restrict', copy=False, + domain=[('reconcile', '=', True), ('deprecated', '=', False)]) diff --git a/account_check_deposit/report/report_checkdeposit.xml b/account_check_deposit/report/report_checkdeposit.xml index 0ec70ed2b..68809535d 100644 --- a/account_check_deposit/report/report_checkdeposit.xml +++ b/account_check_deposit/report/report_checkdeposit.xml @@ -20,15 +20,15 @@

Check Deposit n°

Bank:

-


-
-

+


+
+

Beneficiary:

-

Bank Account Number to Credit:

+

Bank Account Number to Credit:

Check Currency:

diff --git a/account_check_deposit/views/account_config_settings.xml b/account_check_deposit/views/account_config_settings.xml new file mode 100644 index 000000000..995e10a7f --- /dev/null +++ b/account_check_deposit/views/account_config_settings.xml @@ -0,0 +1,28 @@ + + + + + + currency_rate_update.account_config_settings.form + account.config.settings + + +
+
+
+
+
+
+
+
+ +
diff --git a/account_check_deposit/views/account_deposit_view.xml b/account_check_deposit/views/account_deposit_view.xml index 7d178d400..9e7ed8e9b 100644 --- a/account_check_deposit/views/account_deposit_view.xml +++ b/account_check_deposit/views/account_deposit_view.xml @@ -39,7 +39,7 @@ invisible="1"/> - + - + diff --git a/account_check_deposit/views/company_view.xml b/account_check_deposit/views/company_view.xml deleted file mode 100644 index 06329163a..000000000 --- a/account_check_deposit/views/company_view.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - check.deposit.company.form - res.company - - - - - - - - - - - From 1dc7b7c799265c667a5d48fe9df40603874f78cc Mon Sep 17 00:00:00 2001 From: Alexis de Lattre Date: Thu, 8 Dec 2016 20:43:17 +0100 Subject: [PATCH 26/28] Remove data that create a bank journal because it blocks the loading of the chart of accounts when the module is installed at the same time as the chart of account (via dependencies) --- account_check_deposit/README.rst | 10 ++++++++- account_check_deposit/__manifest__.py | 2 -- account_check_deposit/data/account_data.xml | 22 ------------------- .../data/account_deposit_sequence.xml | 21 ------------------ 4 files changed, 9 insertions(+), 46 deletions(-) delete mode 100644 account_check_deposit/data/account_data.xml delete mode 100644 account_check_deposit/data/account_deposit_sequence.xml diff --git a/account_check_deposit/README.rst b/account_check_deposit/README.rst index 4b05315ef..9a5e28e99 100644 --- a/account_check_deposit/README.rst +++ b/account_check_deposit/README.rst @@ -16,7 +16,15 @@ one in EUR and one in USD). Configuration ============= -A journal named *Check Received* is automatically created. It will be available as a payment method in Odoo. On this journal, you must configure the *Default Debit Account* and *Defaut Credit Account* ; this is the account via which the amounts of checks will transit between the reception of a check from a customer and the validation of the check deposit in Odoo. +In the menu *Accounting > Configuration > Accounting > Journals*, create a new journal: + +* Name: Checks Received +* Type: Bank +* Short Code: CHK (or any code you want) +* Default Debit Account: select an account for checks received +* Default Credit Account: idem + +This bank journal will be available as a payment method in Odoo. The account you configured as *Default Debit Account* and *Defaut Credit Account* is the account via which the amounts of checks will transit between the reception of a check from a customer and the validation of the check deposit in Odoo. On the Settings page of the Accounting, you should configure the *Check Deposit Offsetting Account*: diff --git a/account_check_deposit/__manifest__.py b/account_check_deposit/__manifest__.py index 19df0157e..02d70bf3b 100644 --- a/account_check_deposit/__manifest__.py +++ b/account_check_deposit/__manifest__.py @@ -19,11 +19,9 @@ 'data': [ 'views/account_deposit_view.xml', 'views/account_move_line_view.xml', - 'data/account_deposit_sequence.xml', 'views/account_config_settings.xml', 'security/ir.model.access.csv', 'security/check_deposit_security.xml', - 'data/account_data.xml', 'report/report.xml', 'report/report_checkdeposit.xml', ], diff --git a/account_check_deposit/data/account_data.xml b/account_check_deposit/data/account_data.xml deleted file mode 100644 index a2c525ec6..000000000 --- a/account_check_deposit/data/account_data.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - Check Received - CHK - bank - - - - - - diff --git a/account_check_deposit/data/account_deposit_sequence.xml b/account_check_deposit/data/account_deposit_sequence.xml deleted file mode 100644 index 4206b28cc..000000000 --- a/account_check_deposit/data/account_deposit_sequence.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - Account Check Deposit - account.check.deposit - DEP - 3 - - - - - From 1442cd8e29cf2943216370a3f5e678f299bb0bbc Mon Sep 17 00:00:00 2001 From: Alexis de Lattre Date: Fri, 9 Dec 2016 09:42:36 +0100 Subject: [PATCH 27/28] Fix tests of account_check_deposit --- .../tests/test_check_deposit.py | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/account_check_deposit/tests/test_check_deposit.py b/account_check_deposit/tests/test_check_deposit.py index 477dd8e3e..351152c07 100644 --- a/account_check_deposit/tests/test_check_deposit.py +++ b/account_check_deposit/tests/test_check_deposit.py @@ -3,7 +3,7 @@ # @author Mourad EL HADJ MIMOUNE # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from openerp.addons.account.tests.account_test_classes\ +from odoo.addons.account.tests.account_test_classes\ import AccountingTestCase import time @@ -55,12 +55,15 @@ class TestPayment(AccountingTestCase): self.ref('account.data_account_type_revenue') }) - self.recived_check_account_id = self.account_account_model.search( + self.received_check_account_id = self.account_account_model.search( [('code', '=', '511200')], limit=1) - if not self.recived_check_account_id: - self.recived_check_account_id = self.account_account_model.create( + if self.received_check_account_id: + if not self.received_check_account_id.reconcile: + self.received_check_account_id.reconcile = True + else: + self.received_check_account_id = self.account_account_model.create( {"code": '511200', - "name": "Recived check - (test)", + "name": "Received check - (test)", "reconcile": True, "user_type_id": self.ref('account.data_account_type_liquidity') @@ -92,11 +95,11 @@ class TestPayment(AccountingTestCase): [('code', '=', 'CHK')], limit=1) if not self.check_journal: self.check_journal = self.journal_model.create( - {'name': 'Recived check', 'type': 'bank', 'code': 'CHK'}) + {'name': 'received check', 'type': 'bank', 'code': 'CHK'}) self.check_journal.default_debit_account_id = \ - self.recived_check_account_id + self.received_check_account_id self.check_journal.default_credit_account_id = \ - self.recived_check_account_id + self.received_check_account_id self.bank_journal = self.journal_model.search( [('code', '=', 'BNK1')], limit=1) if not self.bank_journal: @@ -111,6 +114,7 @@ class TestPayment(AccountingTestCase): {"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, type='out_invoice', currency_id=None): """ Returns an open invoice """ @@ -132,7 +136,7 @@ class TestPayment(AccountingTestCase): 'name': 'something', 'account_id': self.account_revenue.id, }) - invoice.signal_workflow('invoice_open') + invoice.action_invoice_open() return invoice def create_check_deposit( @@ -140,7 +144,7 @@ class TestPayment(AccountingTestCase): """ Returns an validated check deposit """ check_deposit = self.check_deposit_model.create({ 'journal_id': self.bank_journal.id, - 'partner_bank_id': self.partner_bank_id.id, + 'bank_journal_id': self.bank_journal.id, 'deposit_date': time.strftime('%Y-%m-%d'), 'currency_id': self.currency_eur_id, }) @@ -177,11 +181,11 @@ class TestPayment(AccountingTestCase): self.assertEqual(inv_2.state, 'paid') check_aml = payment.move_line_ids.filtered( - lambda r: r.account_id == self.recived_check_account_id) + lambda r: r.account_id == self.received_check_account_id) check_deposit = self.create_check_deposit([check_aml]) liquidity_aml = check_deposit.move_id.line_ids.filtered( - lambda r: r.account_id != self.recived_check_account_id) + lambda r: r.account_id != self.received_check_account_id) self.assertEqual(check_deposit.total_amount, 300) self.assertEqual(liquidity_aml.debit, 300) From 6bdf51457df10e908ba524e43fb8043f9ef3cf5d Mon Sep 17 00:00:00 2001 From: Alexis de Lattre Date: Fri, 30 Dec 2016 10:56:38 +0100 Subject: [PATCH 28/28] Restore sequence that was removed by mistake --- account_check_deposit/__manifest__.py | 1 + account_check_deposit/data/sequence.xml | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 account_check_deposit/data/sequence.xml diff --git a/account_check_deposit/__manifest__.py b/account_check_deposit/__manifest__.py index 02d70bf3b..79d13f9f5 100644 --- a/account_check_deposit/__manifest__.py +++ b/account_check_deposit/__manifest__.py @@ -17,6 +17,7 @@ 'account_accountant', ], 'data': [ + 'data/sequence.xml', 'views/account_deposit_view.xml', 'views/account_move_line_view.xml', 'views/account_config_settings.xml', diff --git a/account_check_deposit/data/sequence.xml b/account_check_deposit/data/sequence.xml new file mode 100644 index 000000000..d299ca661 --- /dev/null +++ b/account_check_deposit/data/sequence.xml @@ -0,0 +1,18 @@ + + + + + + + Account Check Deposit + account.check.deposit + DEP + 3 + + + +