diff --git a/account_banking/__openerp__.py b/account_banking/__openerp__.py index e5b0ef21f..91cca8fb5 100644 --- a/account_banking/__openerp__.py +++ b/account_banking/__openerp__.py @@ -30,7 +30,7 @@ ############################################################################## { 'name': 'Account Banking', - 'version': '0.1.92', + 'version': '0.1.98', 'license': 'GPL-3', 'author': 'Banking addons community', 'website': 'https://launchpad.net/banking-addons', diff --git a/account_banking/account_banking.py b/account_banking/account_banking.py index 825b95905..e938cdd90 100644 --- a/account_banking/account_banking.py +++ b/account_banking/account_banking.py @@ -757,6 +757,10 @@ class payment_line(osv.osv): return res + """ + Hooks for processing direct debit orders, such as implemented in + account_direct_debit module. + """ def get_storno_account_id(self, cr, uid, payment_line_id, amount, currency_id, context=None): """ @@ -765,10 +769,11 @@ class payment_line(osv.osv): Used in account_banking interactive mode :param payment_line_id: the single payment line id :param amount: the (signed) amount debited from the bank account - :param currency_id: the bank account's currency id + :param currency: the bank account's currency *browse object* :return: an account if there is a full match, False otherwise :rtype: database id of an account.account resource. """ + return False def debit_storno(self, cr, uid, payment_line_id, amount, @@ -783,7 +788,7 @@ class payment_line(osv.osv): :param payment_line_id: the single payment line id :param amount: the (negative) amount debited from the bank account - :param currency_id: the bank account's currency id + :param currency: the bank account's currency *browse object* :param boolean storno_retry: whether the storno is considered fatal \ or not. :return: an incomplete reconcile for the caller to fill @@ -989,13 +994,29 @@ class payment_order(osv.osv): return 'account_banking', 'wizard_account_banking_payment_manual' return super(payment_order, self).get_wizard(type) - def debit_reconcile_transfer(self, cr, uid, payment_order_id, - amount, log, context=None): + """ + Hooks for processing direct debit orders, such as implemented in + account_direct_debit module. + """ + def debit_reconcile_transfer( + self, cr, uid, payment_order_id, amount, currency, context=None): """ - Hook for the account_direct_debit module. When not installed, - do nothing and make sure that the caller ignores the result. + Reconcile the payment order if the amount is correct. Return the + id of the reconciliation. """ - return False + raise osv.except_osv( + _("Cannot reconcile"), + _("Cannot reconcile debit order: "+ + "Not implemented.")) + + def debit_unreconcile_transfer( + self, cr, uid, payment_order_id, reconcile_id, amount, currency, + context=None): + """ Unreconcile the payment_order if at all possible """ + raise osv.except_osv( + _("Cannot unreconcile"), + _("Cannot unreconcile debit order: "+ + "Not implemented.")) payment_order() diff --git a/account_direct_debit/__openerp__.py b/account_direct_debit/__openerp__.py index ec1fa21cb..6ff570ee8 100644 --- a/account_direct_debit/__openerp__.py +++ b/account_direct_debit/__openerp__.py @@ -26,7 +26,7 @@ ############################################################################## { 'name': 'Direct Debit', - 'version': '6.0.1.92', + 'version': '6.0.1.98', 'license': 'GPL-3', 'author': 'Therp BV / Smile', 'website': 'https://launchpad.net/banking-addons', @@ -43,15 +43,19 @@ 'demo_xml': [], 'description': ''' This module adds support for direct debit orders, analogous to payment orders. -A new entry in the Accounting/Payment menu allow you to create a direct debit order that -helps you to select any customer invoices for you to collect. +A new entry in the Accounting/Payment menu allow you to create a direct debit +order that helps you to select any customer invoices for you to collect. -This module depends on and is part of the banking addons for OpenERP. This set of -modules helps you to provide support for communications with your local banking -institutions. See https://launchpad.net/banking-addons. +This module explicitely implements direct debit orders as applicable +in the Netherlands. Debit orders are advanced in total by the bank. +Amounts that cannot be debited or are canceled by account owners are +credited afterwards. Such a creditation is called a storno. This style of +direct debit order may not apply to your country. -The banking addons are a continuation of Account Banking Framework by Edusense BV. -See https://launchpad.net/account-banking. +This module depends on and is part of the banking addons for OpenERP. This set +of modules helps you to provide support for communications with your local +banking institutions. The banking addons are a continuation of Account Banking +Framework by Edusense BV. See https://launchpad.net/banking-addons. ''', 'active': False, 'installable': True, diff --git a/account_direct_debit/model/account_invoice.py b/account_direct_debit/model/account_invoice.py index 7325483f9..9f9c483b6 100644 --- a/account_direct_debit/model/account_invoice.py +++ b/account_direct_debit/model/account_invoice.py @@ -3,6 +3,11 @@ from osv import osv, fields from tools.translate import _ """ +This module adds support for Direct debit orders as applicable +in the Netherlands. Debit orders are advanced in total by the bank. +Amounts that cannot be debited or are canceled by account owners are +credited afterwards. Such a creditation is called a storno. + Invoice workflow: 1 the sale leads to @@ -24,12 +29,14 @@ Balance: Bank 100 | Sales | 2000 -This module considers the following diversion: +This module implements the following diversion: -2a the invoice is included in a direct debit order. When the order is confirmed: - 2000 Transfer account 100 - 1300 Debtors 100 - Reconciliation takes place between 1 and 2a +2a the invoice is included in a direct debit order. When the order is + confirmed, a move is created per invoice: + + 2000 Transfer account 100 | + 1300 Debtors | 100 + Reconciliation takes place between 1 and 2a. The invoice gets set to state 'paid', and 'reconciled' = True Balance: @@ -62,13 +69,13 @@ Balance: Sales | 2000 The reconciliation of 2a is undone. The booking of 2a is reconciled - with the booking of 4 instead (is this problematic?). - The payment line attribute 'storno' is set to True + with the booking of 4 instead. + The payment line attribute 'storno' is set to True and the invoice + state is no longer 'paid'. Two cases need to be distinguisted: 1) If the storno is a manual storno from the partner, the invoice is set to - state 'debit_denied', - with 'reconciled' = False + state 'debit_denied', with 'reconciled' = False This module implements this option by allowing the bank module to call netsvc.LocalService("workflow").trg_validate( @@ -87,22 +94,8 @@ Two cases need to be distinguisted: If not for that funny comment "#TODO: implement messages system" in account/invoice.py - Actual fatal errors need to be dealt with manually by checking open invoices - by invoice- or due date. - -Reconciliation -============== -The first reconciliation is between the invoice move line (this is payment_line.move_line_id) -and the transfer move line (stored as payment_line.debit_move_line_id). The invoice -may have already been partially recognized, so that the payment line.move_line_id does not cover -the whole account. In that case, add the transfer move line to an existing?! partial reconciliation. -Implementation of the reconciliation in payment_line.debit_reconcile() - - - - - - + Repeating non-fatal fatal errors need to be dealt with manually by checking + open invoices with a matured invoice- or due date. """ class account_invoice(osv.osv): diff --git a/account_direct_debit/model/account_move_line.py b/account_direct_debit/model/account_move_line.py index f93c8a077..ce4225d4d 100644 --- a/account_direct_debit/model/account_move_line.py +++ b/account_direct_debit/model/account_move_line.py @@ -4,6 +4,7 @@ # OpenERP, Open Source Management Solution # Copyright (C) 2004-2010 Tiny SPRL (). # This module additional (C) 2011 Therp BV (). +# (C) 2011 Smile Benelux (). # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -28,9 +29,11 @@ class account_move_line(osv.osv): _inherit = "account.move.line" def amount_to_receive(self, cr, uid, ids, name, arg={}, context=None): - """ Return the amount still to receive regarding all the payemnt orders - (excepting cancelled orders) - This is the reverse from account_payment/account_move_line.py + """ + Return the amount still to receive regarding all the debit orders + (excepting canceled orders). + This is the reverse from amount_to_pay() in + account_payment/account_move_line.py """ if not ids: return {} @@ -89,7 +92,12 @@ class account_move_line(osv.osv): res = dict([(x.id, False) for x in ids]) return res - def _invoice_payment_term_id_search(self, cr, uid, obj, name, args, context=None): + def _invoice_payment_term_id_search( + self, cr, uid, obj, name, args, context=None): + """ + Allow to search move lines associated with an invoice with + a particular payment term + """ if not args: return [] invoice_obj = self.pool.get('account.invoice') @@ -145,4 +153,3 @@ class account_move_line(osv.osv): } account_move_line() - diff --git a/account_direct_debit/model/account_payment.py b/account_direct_debit/model/account_payment.py index 7114081fa..370be0efd 100644 --- a/account_direct_debit/model/account_payment.py +++ b/account_direct_debit/model/account_payment.py @@ -36,12 +36,14 @@ class payment_order(osv.osv): def fields_view_get(self, cr, user, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): """ - Pretty awful workaround for no dynamic domain possible on - widget='selection' + We use the same form for payment and debit orders, but they + are accessible through different menu items. The user should only + be allowed to select a payment mode that applies to the type of order + i.e. payment or debit. - The domain is encoded in the context - - Uhmm, are these results are cached? + A pretty awful workaround is needed for the fact that no dynamic + domain is possible on the selection widget. This domain is encoded + in the context of the menu item. """ if not context: context = {} @@ -90,8 +92,7 @@ class payment_order(osv.osv): amount, currency, context=None): """ Due to a cancelled bank statements import, unreconcile the move on - the transfer account. Delegate the conditions to the workflow, but - rip out the reconcile first or the workflow may not allow the undo. + the transfer account. Delegate the conditions to the workflow. Raise on failure for rollback. """ self.pool.get('account.move.reconcile').unlink( @@ -156,7 +157,7 @@ class payment_order(osv.osv): 'reference': 'DEB%s' % line.move_line_id.move_id.name, }, context=context) - # TODO: multicurrency + # TODO: take multicurrency into account # create the debit move line on the transfer account vals = { @@ -324,7 +325,7 @@ class payment_line(osv.osv): def debit_reconcile(self, cr, uid, payment_line_id, context=None): """ Reconcile a debit order's payment line with the the move line - that it is based on. + that it is based on. Called from payment_order.action_sent(). As the amount is derived directly from the counterpart move line, we do not expect a write off. Take partially reconcilions into account though.