From 3bd9ee9cf95db0be33638a005afeac8e6b0be772 Mon Sep 17 00:00:00 2001 From: Guewen Baconnier Date: Thu, 16 Jan 2014 14:07:40 +0100 Subject: [PATCH 1/9] started module account_invoice_reference to modify the way the reference of moves are generated --- account_invoice_reference/__init__.py | 22 +++++++ account_invoice_reference/__openerp__.py | 60 +++++++++++++++++++ .../account_invoice_view.xml | 26 ++++++++ account_invoice_reference/account_move.py | 50 ++++++++++++++++ 4 files changed, 158 insertions(+) create mode 100644 account_invoice_reference/__init__.py create mode 100644 account_invoice_reference/__openerp__.py create mode 100644 account_invoice_reference/account_invoice_view.xml create mode 100644 account_invoice_reference/account_move.py diff --git a/account_invoice_reference/__init__.py b/account_invoice_reference/__init__.py new file mode 100644 index 00000000..ce74e081 --- /dev/null +++ b/account_invoice_reference/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Author: Guewen Baconnier +# Copyright 2014 Camptocamp SA +# +# 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_move diff --git a/account_invoice_reference/__openerp__.py b/account_invoice_reference/__openerp__.py new file mode 100644 index 00000000..a7fc1115 --- /dev/null +++ b/account_invoice_reference/__openerp__.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Author: Guewen Baconnier +# Copyright 2014 Camptocamp SA +# +# 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 . +# +############################################################################## + +{'name' : 'Invoices Reference', + 'version' : '1.0', + 'author' : 'Camptocamp', + 'maintainer': 'Camptocamp', + 'license': 'AGPL-3', + 'category': 'category', + 'complexity': "easy", + 'depends' : ['account', + ], + 'description': """ +Invoices Reference +================== + +Aims to simplify the "references" things on the invoices. +There is too many fields on the invoices. And it is very difficult +to remember which field goes in which field of the Journal Entries. + +It particularly fits with other modules of the bank-statement-reconcile series +as account_advanced_reconcile_transaction_ref. + +Use cases +--------- + +Customer invoices + Journal Entry Reference is the Origin of the invoice if there, + otherwise, it is the Number of the invoice. + +Supplier invoices + Journal Entry Reference is the Supplier Invoice Number of the invoice + which is now mandatory. + + """, + 'website': 'http://www.camptocamp.com', + 'data': ['account_invoice_view.xml', + ], + 'tests': [], + 'installable': True, + 'auto_install': False, +} diff --git a/account_invoice_reference/account_invoice_view.xml b/account_invoice_reference/account_invoice_view.xml new file mode 100644 index 00000000..1c9cfdde --- /dev/null +++ b/account_invoice_reference/account_invoice_view.xml @@ -0,0 +1,26 @@ + + + + + account.invoice.supplier.form + account.invoice + + + + 1 + + + + + + + + + {'invisible': [('reference_type', '=', 'none')]} + + + + + diff --git a/account_invoice_reference/account_move.py b/account_invoice_reference/account_move.py new file mode 100644 index 00000000..5d3ef4c6 --- /dev/null +++ b/account_invoice_reference/account_move.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Author: Guewen Baconnier +# Copyright 2014 Camptocamp SA +# +# 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 openerp.osv import orm, fields + + +class account_move(orm.Model): + _inherit = 'account.move' + + def _ref_from_invoice(self, cr, uid, invoice, context=None): + if invoice.type == 'out_invoice': + return invoice.origin or invoice.name + elif invoice.type == 'in_invoice': + # the supplier invoice number is now mandatory, but + # if historical invoices should not have one, we fallback + # to the name of the invoice + return invoice.supplier_invoice_number or invoice.name + + def create(self, cr, uid, vals, context=None): + if context is None: + context = {} + # invoice from which the move is generated + invoice = context.get('invoice') + if invoice: + assert isinstance(invoice, orm.browse_record) + ref = self._ref_from_invoice(cr, uid, invoice, context=context) + if ref: + vals = vals.copy() + vals['ref'] = ref + move_id = super(account_move, self).\ + create(cr, uid, vals, context=context) + return move_id From cf59d1bb97ec5e22a7e312f01652abc621cfd7e9 Mon Sep 17 00:00:00 2001 From: Guewen Baconnier Date: Fri, 17 Jan 2014 14:32:36 +0100 Subject: [PATCH 2/9] handle refunds the same way than invoices for the references --- account_invoice_reference/account_move.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/account_invoice_reference/account_move.py b/account_invoice_reference/account_move.py index 5d3ef4c6..8dd22c89 100644 --- a/account_invoice_reference/account_move.py +++ b/account_invoice_reference/account_move.py @@ -26,9 +26,9 @@ class account_move(orm.Model): _inherit = 'account.move' def _ref_from_invoice(self, cr, uid, invoice, context=None): - if invoice.type == 'out_invoice': + if invoice.type in ('out_invoice', 'out_refund'): return invoice.origin or invoice.name - elif invoice.type == 'in_invoice': + elif invoice.type == ('in_invoice', 'in_refund'): # the supplier invoice number is now mandatory, but # if historical invoices should not have one, we fallback # to the name of the invoice From 75e5c6e86e0bb1fdd36279241bd4b883303e2b75 Mon Sep 17 00:00:00 2001 From: Guewen Baconnier Date: Tue, 21 Jan 2014 10:31:36 +0100 Subject: [PATCH 3/9] set ref of move line from invoice origin/supplier invoice's number or invoice's number (work in progress) --- account_invoice_reference/__openerp__.py | 3 +- account_invoice_reference/account_move.py | 49 +++++++++++++++---- .../test/in_invoice_with_origin.yml | 23 +++++++++ 3 files changed, 64 insertions(+), 11 deletions(-) create mode 100644 account_invoice_reference/test/in_invoice_with_origin.yml diff --git a/account_invoice_reference/__openerp__.py b/account_invoice_reference/__openerp__.py index a7fc1115..04799a9d 100644 --- a/account_invoice_reference/__openerp__.py +++ b/account_invoice_reference/__openerp__.py @@ -54,7 +54,8 @@ Supplier invoices 'website': 'http://www.camptocamp.com', 'data': ['account_invoice_view.xml', ], - 'tests': [], + 'test': ['test/in_invoice_with_origin.yml', + ], 'installable': True, 'auto_install': False, } diff --git a/account_invoice_reference/account_move.py b/account_invoice_reference/account_move.py index 8dd22c89..4bab8987 100644 --- a/account_invoice_reference/account_move.py +++ b/account_invoice_reference/account_move.py @@ -25,15 +25,6 @@ from openerp.osv import orm, fields class account_move(orm.Model): _inherit = 'account.move' - def _ref_from_invoice(self, cr, uid, invoice, context=None): - if invoice.type in ('out_invoice', 'out_refund'): - return invoice.origin or invoice.name - elif invoice.type == ('in_invoice', 'in_refund'): - # the supplier invoice number is now mandatory, but - # if historical invoices should not have one, we fallback - # to the name of the invoice - return invoice.supplier_invoice_number or invoice.name - def create(self, cr, uid, vals, context=None): if context is None: context = {} @@ -41,10 +32,48 @@ class account_move(orm.Model): invoice = context.get('invoice') if invoice: assert isinstance(invoice, orm.browse_record) - ref = self._ref_from_invoice(cr, uid, invoice, context=context) + invoice_obj = self.pool['account.invoice'] + ref = invoice_obj._ref_from_invoice(cr, uid, invoice, context=context) if ref: vals = vals.copy() vals['ref'] = ref move_id = super(account_move, self).\ create(cr, uid, vals, context=context) return move_id + + +class account_invoice(orm.Model): + _inherit = 'account.invoice' + + def _ref_from_invoice(self, cr, uid, invoice, context=None): + if invoice.type in ('out_invoice', 'out_refund'): + return invoice.origin + elif invoice.type == ('in_invoice', 'in_refund'): + return invoice.supplier_invoice_number + + def action_number(self, cr, uid, ids, context=None): + if context is None: + context = {} + #TODO: not correct fix but required a frech values before reading it. + self.write(cr, uid, ids, {}) + + for invoice in self.browse(cr, uid, ids, context=context): + ref = self._ref_from_invoice(cr, uid, invoice, context=context) + if not ref: + ref = invoice.number + move_id = invoice.move_id.id if invoice.move_id else False + + self.write(cr, uid, ids, {'internal_number': invoice.number}, + context=context) + cr.execute('UPDATE account_move SET ref=%s ' + 'WHERE id=%s AND (ref is null OR ref = \'\')', + (ref, move_id)) + cr.execute('UPDATE account_move_line SET ref=%s ' + 'WHERE move_id=%s AND (ref is null OR ref = \'\')', + (ref, move_id)) + cr.execute('UPDATE account_analytic_line SET ref=%s ' + 'FROM account_move_line ' + 'WHERE account_move_line.move_id = %s ' + 'AND account_analytic_line.move_id = account_move_line.id', + (ref, move_id)) + return True diff --git a/account_invoice_reference/test/in_invoice_with_origin.yml b/account_invoice_reference/test/in_invoice_with_origin.yml new file mode 100644 index 00000000..993c0684 --- /dev/null +++ b/account_invoice_reference/test/in_invoice_with_origin.yml @@ -0,0 +1,23 @@ +- + In order to check if the reference of the invoice is the origin of + the invoice (customer invoices), I create an invoice +- + !record {model: account.invoice, id: invoice_reference_origin}: + payment_term: account.account_payment_term_advance + journal_id: account.sales_journal + partner_id: base.res_partner_3 + reference_type: none + name: 'Test Customer Invoice' + origin: ABC123 + invoice_line: + - product_id: product.product_product_5 + quantity: 10.0 +- + I create invoice by clicking on Create button +- + !workflow {model: account.invoice, action: invoice_open, ref: invoice_reference_origin} +- + I check that the reference of the move is the origin of the invoice +- + !assert {model: account.invoice, id: invoice_reference_origin}: + - move_id.ref == 'ABC123' From c34cbbf8f5881f4e6a18c8aa7020c7c18f9a44ae Mon Sep 17 00:00:00 2001 From: Guewen Baconnier Date: Tue, 21 Jan 2014 14:35:47 +0100 Subject: [PATCH 4/9] account_invoice_reference: ensure that the ref is always what we want, added tests --- account_invoice_reference/__openerp__.py | 5 ++- account_invoice_reference/account_move.py | 7 ++-- .../test/in_invoice_with_supplier_number.yml | 40 +++++++++++++++++++ .../in_invoice_without_supplier_number.yml | 39 ++++++++++++++++++ ...origin.yml => out_invoice_with_origin.yml} | 2 +- .../test/out_invoice_without_origin.yml | 22 ++++++++++ 6 files changed, 109 insertions(+), 6 deletions(-) create mode 100644 account_invoice_reference/test/in_invoice_with_supplier_number.yml create mode 100644 account_invoice_reference/test/in_invoice_without_supplier_number.yml rename account_invoice_reference/test/{in_invoice_with_origin.yml => out_invoice_with_origin.yml} (91%) create mode 100644 account_invoice_reference/test/out_invoice_without_origin.yml diff --git a/account_invoice_reference/__openerp__.py b/account_invoice_reference/__openerp__.py index 04799a9d..e6b0d90d 100644 --- a/account_invoice_reference/__openerp__.py +++ b/account_invoice_reference/__openerp__.py @@ -54,7 +54,10 @@ Supplier invoices 'website': 'http://www.camptocamp.com', 'data': ['account_invoice_view.xml', ], - 'test': ['test/in_invoice_with_origin.yml', + 'test': ['test/out_invoice_with_origin.yml', + 'test/out_invoice_without_origin.yml', + 'test/in_invoice_with_supplier_number.yml', + 'test/in_invoice_without_supplier_number.yml', ], 'installable': True, 'auto_install': False, diff --git a/account_invoice_reference/account_move.py b/account_invoice_reference/account_move.py index 4bab8987..5d9fc8c5 100644 --- a/account_invoice_reference/account_move.py +++ b/account_invoice_reference/account_move.py @@ -34,9 +34,8 @@ class account_move(orm.Model): assert isinstance(invoice, orm.browse_record) invoice_obj = self.pool['account.invoice'] ref = invoice_obj._ref_from_invoice(cr, uid, invoice, context=context) - if ref: - vals = vals.copy() - vals['ref'] = ref + vals = vals.copy() + vals['ref'] = ref move_id = super(account_move, self).\ create(cr, uid, vals, context=context) return move_id @@ -48,7 +47,7 @@ class account_invoice(orm.Model): def _ref_from_invoice(self, cr, uid, invoice, context=None): if invoice.type in ('out_invoice', 'out_refund'): return invoice.origin - elif invoice.type == ('in_invoice', 'in_refund'): + elif invoice.type in ('in_invoice', 'in_refund'): return invoice.supplier_invoice_number def action_number(self, cr, uid, ids, context=None): diff --git a/account_invoice_reference/test/in_invoice_with_supplier_number.yml b/account_invoice_reference/test/in_invoice_with_supplier_number.yml new file mode 100644 index 00000000..aaba9e44 --- /dev/null +++ b/account_invoice_reference/test/in_invoice_with_supplier_number.yml @@ -0,0 +1,40 @@ +- + In order to check if the reference of the move is the supplier invoice number of + the invoice (supplier invoices), I create an invoice +- + !record {model: account.invoice, id: invoice_reference_supplier_number, view: account.invoice_supplier_form}: + account_id: account.a_pay + check_total: 3000.0 + company_id: base.main_company + currency_id: base.EUR + invoice_line: + - account_id: account.a_expense + name: '[PCSC234] PC Assemble SC234' + price_unit: 300.0 + product_id: product.product_product_3 + quantity: 10.0 + uos_id: product.product_uom_unit + journal_id: account.expenses_journal + partner_id: base.res_partner_12 + reference_type: none + supplier_invoice_number: ZZZ246 + type: in_invoice +- + Set again the type of the invoice (not set on the first one...) +- + !record {model: account.invoice, id: invoice_reference_supplier_number, view: account.invoice_supplier_form}: + type: in_invoice +- + Ensure that the invoice is a supplier invoice +- + !assert {model: account.invoice, id: invoice_reference_supplier_number}: + - type == 'in_invoice' +- + I create invoice by clicking on Create button +- + !workflow {model: account.invoice, action: invoice_open, ref: invoice_reference_supplier_number} +- + I check that the reference of the move is the supplier invoice number of the invoice +- + !assert {model: account.invoice, id: invoice_reference_supplier_number}: + - move_id.ref == 'ZZZ246' diff --git a/account_invoice_reference/test/in_invoice_without_supplier_number.yml b/account_invoice_reference/test/in_invoice_without_supplier_number.yml new file mode 100644 index 00000000..d2833484 --- /dev/null +++ b/account_invoice_reference/test/in_invoice_without_supplier_number.yml @@ -0,0 +1,39 @@ +- + In order to check if the reference of the move is the supplier invoice number of + the invoice (supplier invoices), I create an invoice +- + !record {model: account.invoice, id: invoice_reference_no_supplier_number, view: account.invoice_supplier_form}: + account_id: account.a_pay + check_total: 3000.0 + company_id: base.main_company + currency_id: base.EUR + invoice_line: + - account_id: account.a_expense + name: '[PCSC234] PC Assemble SC234' + price_unit: 300.0 + product_id: product.product_product_3 + quantity: 10.0 + uos_id: product.product_uom_unit + journal_id: account.expenses_journal + partner_id: base.res_partner_12 + reference_type: none + type: in_invoice +- + Set again the type of the invoice (not set on the first one...) +- + !record {model: account.invoice, id: invoice_reference_supplier_number, view: account.invoice_supplier_form}: + type: in_invoice +- + Ensure that the invoice is a supplier invoice +- + !assert {model: account.invoice, id: invoice_reference_supplier_number}: + - type == 'in_invoice' +- + I create invoice by clicking on Create button +- + !workflow {model: account.invoice, action: invoice_open, ref: invoice_reference_no_supplier_number} +- + I check that the reference of the move is the number of the invoice +- + !assert {model: account.invoice, id: invoice_reference_no_supplier_number}: + - move_id.ref == number diff --git a/account_invoice_reference/test/in_invoice_with_origin.yml b/account_invoice_reference/test/out_invoice_with_origin.yml similarity index 91% rename from account_invoice_reference/test/in_invoice_with_origin.yml rename to account_invoice_reference/test/out_invoice_with_origin.yml index 993c0684..02bae0bc 100644 --- a/account_invoice_reference/test/in_invoice_with_origin.yml +++ b/account_invoice_reference/test/out_invoice_with_origin.yml @@ -1,5 +1,5 @@ - - In order to check if the reference of the invoice is the origin of + In order to check if the reference of the move is the origin of the invoice (customer invoices), I create an invoice - !record {model: account.invoice, id: invoice_reference_origin}: diff --git a/account_invoice_reference/test/out_invoice_without_origin.yml b/account_invoice_reference/test/out_invoice_without_origin.yml new file mode 100644 index 00000000..836d758c --- /dev/null +++ b/account_invoice_reference/test/out_invoice_without_origin.yml @@ -0,0 +1,22 @@ +- + In order to check if the reference of the move is the number of + the invoice (customer invoices) when it has no origin, I create an invoice +- + !record {model: account.invoice, id: invoice_reference_no_origin}: + payment_term: account.account_payment_term_advance + journal_id: account.sales_journal + partner_id: base.res_partner_3 + reference_type: none + name: 'Test Customer Invoice no origin' + invoice_line: + - product_id: product.product_product_5 + quantity: 10.0 +- + I create invoice by clicking on Create button +- + !workflow {model: account.invoice, action: invoice_open, ref: invoice_reference_no_origin} +- + I check that the reference of the move is the number of the invoice +- + !assert {model: account.invoice, id: invoice_reference_no_origin}: + - move_id.ref == number From 9eea7ee585246a2a6e763cee17af0898721d3597 Mon Sep 17 00:00:00 2001 From: Guewen Baconnier Date: Wed, 22 Jan 2014 14:55:30 +0100 Subject: [PATCH 5/9] add tests for refunds --- account_invoice_reference/__openerp__.py | 5 +++ .../test/in_refund_with_supplier_number.yml | 40 +++++++++++++++++++ .../in_refund_without_supplier_number.yml | 39 ++++++++++++++++++ .../test/out_refund_with_origin.yml | 34 ++++++++++++++++ .../test/out_refund_without_origin.yml | 33 +++++++++++++++ 5 files changed, 151 insertions(+) create mode 100644 account_invoice_reference/test/in_refund_with_supplier_number.yml create mode 100644 account_invoice_reference/test/in_refund_without_supplier_number.yml create mode 100644 account_invoice_reference/test/out_refund_with_origin.yml create mode 100644 account_invoice_reference/test/out_refund_without_origin.yml diff --git a/account_invoice_reference/__openerp__.py b/account_invoice_reference/__openerp__.py index e6b0d90d..11cd0f04 100644 --- a/account_invoice_reference/__openerp__.py +++ b/account_invoice_reference/__openerp__.py @@ -58,6 +58,11 @@ Supplier invoices 'test/out_invoice_without_origin.yml', 'test/in_invoice_with_supplier_number.yml', 'test/in_invoice_without_supplier_number.yml', + 'test/out_refund_with_origin.yml', + 'test/out_refund_without_origin.yml', + 'test/in_refund_with_supplier_number.yml', + 'test/in_refund_without_supplier_number.yml', + ], 'installable': True, 'auto_install': False, diff --git a/account_invoice_reference/test/in_refund_with_supplier_number.yml b/account_invoice_reference/test/in_refund_with_supplier_number.yml new file mode 100644 index 00000000..b67e71bf --- /dev/null +++ b/account_invoice_reference/test/in_refund_with_supplier_number.yml @@ -0,0 +1,40 @@ +- + In order to check if the reference of the move is the supplier invoice number of + the refund (supplier refunds), I create a refund +- + !record {model: account.invoice, id: refund_reference_supplier_number, view: account.invoice_supplier_form}: + account_id: account.a_pay + check_total: 3000.0 + company_id: base.main_company + currency_id: base.EUR + invoice_line: + - account_id: account.a_expense + name: '[PCSC234] PC Assemble SC234' + price_unit: 300.0 + product_id: product.product_product_3 + quantity: 10.0 + uos_id: product.product_uom_unit + journal_id: account.expenses_journal + partner_id: base.res_partner_12 + reference_type: none + supplier_invoice_number: RZZZ246 + type: in_refund +- + Set again the type of the refund (not set on the first one...) +- + !record {model: account.invoice, id: refund_reference_supplier_number, view: account.invoice_supplier_form}: + type: in_refund +- + Ensure that the refund is a supplier refund +- + !assert {model: account.invoice, id: refund_reference_supplier_number}: + - type == 'in_refund' +- + I create refund by clicking on Create button +- + !workflow {model: account.invoice, action: invoice_open, ref: refund_reference_supplier_number} +- + I check that the reference of the move is the supplier refund number of the refund +- + !assert {model: account.invoice, id: refund_reference_supplier_number}: + - move_id.ref == 'RZZZ246' diff --git a/account_invoice_reference/test/in_refund_without_supplier_number.yml b/account_invoice_reference/test/in_refund_without_supplier_number.yml new file mode 100644 index 00000000..c82f10a3 --- /dev/null +++ b/account_invoice_reference/test/in_refund_without_supplier_number.yml @@ -0,0 +1,39 @@ +- + In order to check if the reference of the move is the supplier refund number of + the refund (supplier refunds), I create an refund +- + !record {model: account.invoice, id: refund_reference_no_supplier_number, view: account.invoice_supplier_form}: + account_id: account.a_pay + check_total: 3000.0 + company_id: base.main_company + currency_id: base.EUR + invoice_line: + - account_id: account.a_expense + name: '[PCSC234] PC Assemble SC234' + price_unit: 300.0 + product_id: product.product_product_3 + quantity: 10.0 + uos_id: product.product_uom_unit + journal_id: account.expenses_journal + partner_id: base.res_partner_12 + reference_type: none + type: in_refund +- + Set again the type of the refund (not set on the first one...) +- + !record {model: account.invoice, id: refund_reference_supplier_number, view: account.invoice_supplier_form}: + type: in_refund +- + Ensure that the refund is a supplier refund +- + !assert {model: account.invoice, id: refund_reference_supplier_number}: + - type == 'in_refund' +- + I create refund by clicking on Create button +- + !workflow {model: account.invoice, action: invoice_open, ref: refund_reference_no_supplier_number} +- + I check that the reference of the move is the number of the refund +- + !assert {model: account.invoice, id: refund_reference_no_supplier_number}: + - move_id.ref == number diff --git a/account_invoice_reference/test/out_refund_with_origin.yml b/account_invoice_reference/test/out_refund_with_origin.yml new file mode 100644 index 00000000..d50e9aeb --- /dev/null +++ b/account_invoice_reference/test/out_refund_with_origin.yml @@ -0,0 +1,34 @@ +- + In order to check if the reference of the move is the origin of + the refund (customer refunds), I create a refund +- + !record {model: account.invoice, id: refund_reference_origin, view: account.invoice_form}: + payment_term: account.account_payment_term_advance + journal_id: account.sales_journal + partner_id: base.res_partner_3 + reference_type: none + name: 'Test Customer refund' + origin: RABC123 + invoice_line: + - product_id: product.product_product_5 + quantity: 10.0 + type: out_refund +- + Set again the type of the invoice (not set on the first one...) +- + !record {model: account.invoice, id: refund_reference_origin, view: account.invoice_form}: + type: out_refund +- + Ensure that the invoice is a customer refund +- + !assert {model: account.invoice, id: refund_reference_origin}: + - type == 'out_refund' +- + I create a refund by clicking on Create button +- + !workflow {model: account.invoice, action: invoice_open, ref: refund_reference_origin} +- + I check that the reference of the move is the origin of the refund +- + !assert {model: account.invoice, id: refund_reference_origin}: + - move_id.ref == 'RABC123' diff --git a/account_invoice_reference/test/out_refund_without_origin.yml b/account_invoice_reference/test/out_refund_without_origin.yml new file mode 100644 index 00000000..1ce3fb46 --- /dev/null +++ b/account_invoice_reference/test/out_refund_without_origin.yml @@ -0,0 +1,33 @@ +- + In order to check if the reference of the move is the number of + the refund (customer refunds) when it has no origin, I create a refund +- + !record {model: account.invoice, id: refund_reference_no_origin}: + payment_term: account.account_payment_term_advance + journal_id: account.sales_journal + partner_id: base.res_partner_3 + reference_type: none + name: 'Test Customer refund no origin' + invoice_line: + - product_id: product.product_product_5 + quantity: 10.0 + type: out_refund +- + Set again the type of the invoice (not set on the first one...) +- + !record {model: account.invoice, id: refund_reference_no_origin, view: account.invoice_form}: + type: out_refund +- + Ensure that the invoice is a customer refund +- + !assert {model: account.invoice, id: refund_reference_no_origin}: + - type == 'out_refund' +- + I create refund by clicking on Create button +- + !workflow {model: account.invoice, action: invoice_open, ref: refund_reference_no_origin} +- + I check that the reference of the move is the number of the refund +- + !assert {model: account.invoice, id: refund_reference_no_origin}: + - move_id.ref == number From c52a975357f828c5444fd43e7931488888e7d6b5 Mon Sep 17 00:00:00 2001 From: Guewen Baconnier Date: Wed, 22 Jan 2014 16:17:11 +0100 Subject: [PATCH 6/9] document the module --- account_invoice_reference/__openerp__.py | 15 +++++++++++---- account_invoice_reference/account_move.py | 5 ++--- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/account_invoice_reference/__openerp__.py b/account_invoice_reference/__openerp__.py index 11cd0f04..8fdb489b 100644 --- a/account_invoice_reference/__openerp__.py +++ b/account_invoice_reference/__openerp__.py @@ -32,12 +32,19 @@ Invoices Reference ================== -Aims to simplify the "references" things on the invoices. -There is too many fields on the invoices. And it is very difficult -to remember which field goes in which field of the Journal Entries. +Aims to simplify the "references" things on the invoices. There is too +many fields on the invoices. And it is very difficult to remember +which field goes in which field of the Journal Entries and under which +conditions. + +Is follows this rule: the reference of a journal entry is +always the reference of the document which generated it to +be able to trace them in the accounting reports. That means the origin +of an invoice or if the invoice has been created manually without origin, +its number. It particularly fits with other modules of the bank-statement-reconcile series -as account_advanced_reconcile_transaction_ref. +like account_advanced_reconcile_transaction_ref. Use cases --------- diff --git a/account_invoice_reference/account_move.py b/account_invoice_reference/account_move.py index 5d9fc8c5..96db538b 100644 --- a/account_invoice_reference/account_move.py +++ b/account_invoice_reference/account_move.py @@ -51,9 +51,8 @@ class account_invoice(orm.Model): return invoice.supplier_invoice_number def action_number(self, cr, uid, ids, context=None): - if context is None: - context = {} - #TODO: not correct fix but required a frech values before reading it. + # force the number of the invoice to be updated for the + # subsequent browse self.write(cr, uid, ids, {}) for invoice in self.browse(cr, uid, ids, context=context): From 84678c368fe6996434e5167c71c1fa5b04491d21 Mon Sep 17 00:00:00 2001 From: Guewen Baconnier Date: Fri, 24 Jan 2014 15:03:51 +0100 Subject: [PATCH 7/9] changes to the invoices views: always display the description, copy the supplier invoice number in ref. document the module --- account_invoice_reference/__openerp__.py | 106 +++++++++++++++--- .../account_invoice_view.xml | 27 ++++- account_invoice_reference/account_move.py | 22 ++++ 3 files changed, 135 insertions(+), 20 deletions(-) diff --git a/account_invoice_reference/__openerp__.py b/account_invoice_reference/__openerp__.py index 8fdb489b..ab0f0499 100644 --- a/account_invoice_reference/__openerp__.py +++ b/account_invoice_reference/__openerp__.py @@ -32,30 +32,100 @@ Invoices Reference ================== -Aims to simplify the "references" things on the invoices. There is too -many fields on the invoices. And it is very difficult to remember -which field goes in which field of the Journal Entries and under which -conditions. +Aims to simplify the "references" fields on the invoices. -Is follows this rule: the reference of a journal entry is -always the reference of the document which generated it to -be able to trace them in the accounting reports. That means the origin -of an invoice or if the invoice has been created manually without origin, -its number. +We observed difficulties for the users to file the references (name, +origin, free reference) and above all, to understand which field will be +copied in the reference field of the move and move lines. + +The approach here is to state simple rules with one concern: consistency. +The reference of the move lines must be the number of the document at their very +origin (number of a sales order, of an external document like a supplier +invoice, ...). The goal is for the accountant to be able to trace to the +source document from a ledger). +The description of a line should always be... well, a description. Not a number +or a cryptic reference. It particularly fits with other modules of the bank-statement-reconcile series -like account_advanced_reconcile_transaction_ref. +as account_advanced_reconcile_transaction_ref. -Use cases ---------- +Fields +------ -Customer invoices - Journal Entry Reference is the Origin of the invoice if there, - otherwise, it is the Number of the invoice. +Enumerating the information we need in an invoice, we find that the +mandatory fields are: -Supplier invoices - Journal Entry Reference is the Supplier Invoice Number of the invoice - which is now mandatory. +* Invoice Number +* Description +* Internal Reference ("our reference") +* External Reference ("customer or supplier reference") +* Optionally, a technical transaction reference (credit card payment gateways, SEPA, ...) + +Now, on the move lines: + +* Name +* Reference +* Optionally, a technical transaction reference (added by the module `base_transaction_id`) + +Let's see how the information will be organized with this module. + +Customers Invoices / Refunds +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +-----------------+-----------------+------------------------------+ + | Information | Invoice field | Instead of (in base modules) | + +=================+=================+==============================+ + | Invoice number | Invoice number | Invoice number | + +-----------------+-----------------+------------------------------+ + | Description | Name | -- | + +-----------------+-----------------+------------------------------+ + | Internal Ref | Origin | Origin | + +-----------------+-----------------+------------------------------+ + | External Ref | Reference | Name | + +-----------------+-----------------+------------------------------+ + +Information propagated to the move lines: + + +-----------------+------------------------------------+ + | Move line field | Invoice field | + +=================+====================================+ + | Description | Name | + +-----------------+------------------------------------+ + | Reference | Origin, or Invoice number if empty | + +-----------------+------------------------------------+ + + +Supplier Invoices / Refunds +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Supplier invoices have an additional field `supplier_invoice_number` +that we consider as redundant with the reference field. This field is kept +and even set as mandatory, while the reference field is hidden. + + +-----------------+-----------------+------------------------------+ + | Information | Invoice field | Instead of (in base modules) | + +=================+=================+==============================+ + | Invoice number | Invoice number | Invoice number | + +-----------------+-----------------+------------------------------+ + | Description | Name | -- | + +-----------------+-----------------+------------------------------+ + | Internal Ref | Origin | Origin | + +-----------------+-----------------+------------------------------+ + | External Ref | Supplier number | Supplier number | + +-----------------+-----------------+------------------------------+ + +The reference field is hidden when the reference type is "free reference", +because it is already filed in the Supplier invoice number. + +Information propagated to the move lines: + + +-----------------+---------------------------------------------+ + | Move line field | Invoice field | + +=================+=============================================+ + | Description | Name | + +-----------------+---------------------------------------------+ + | Reference | Supplier number, or Invoice number if empty | + +-----------------+---------------------------------------------+ """, 'website': 'http://www.camptocamp.com', diff --git a/account_invoice_reference/account_invoice_view.xml b/account_invoice_reference/account_invoice_view.xml index 1c9cfdde..62bff28a 100644 --- a/account_invoice_reference/account_invoice_view.xml +++ b/account_invoice_reference/account_invoice_view.xml @@ -13,14 +13,37 @@ - - + {'invisible': [('reference_type', '=', 'none')]} + + + + + + + + account.invoice.form + account.invoice + + + + + + + + + + + + + diff --git a/account_invoice_reference/account_move.py b/account_invoice_reference/account_move.py index 96db538b..66877aed 100644 --- a/account_invoice_reference/account_move.py +++ b/account_invoice_reference/account_move.py @@ -75,3 +75,25 @@ class account_invoice(orm.Model): 'AND account_analytic_line.move_id = account_move_line.id', (ref, move_id)) return True + + def create(self, cr, uid, vals, context=None): + if (vals.get('supplier_invoice_reference') and not + vals.get('reference')): + vals['reference'] = vals['supplier_invoice_reference'] + return super(account_invoice, self).create(cr, uid, vals, + context=context) + + def write(self, cr, uid, ids, vals, context=None): + if vals.get('supplier_invoice_reference'): + if isinstance(ids, (int, long)): + ids = [ids] + for invoice in self.browse(cr, uid, ids, context=context): + local_vals = vals + if not invoice.reference: + locvals = vals.copy() + locvals['reference'] = vals['supplier_invoice_reference'] + return super(account_invoice, self).write(cr, uid, [invoice.id], + locvals, context=context) + else: + return super(account_invoice, self).write(cr, uid, ids, vals, + context=context) From 52a96d5452413da5c7ac9a39116395f0f0119be5 Mon Sep 17 00:00:00 2001 From: Guewen Baconnier Date: Fri, 24 Jan 2014 15:49:52 +0100 Subject: [PATCH 8/9] translations --- .../i18n/account_invoice_reference.pot | 42 +++++++++++++++++++ account_invoice_reference/i18n/fr.po | 42 +++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 account_invoice_reference/i18n/account_invoice_reference.pot create mode 100644 account_invoice_reference/i18n/fr.po diff --git a/account_invoice_reference/i18n/account_invoice_reference.pot b/account_invoice_reference/i18n/account_invoice_reference.pot new file mode 100644 index 00000000..45f9cd06 --- /dev/null +++ b/account_invoice_reference/i18n/account_invoice_reference.pot @@ -0,0 +1,42 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# * account_invoice_reference +# +msgid "" +msgstr "" +"Project-Id-Version: OpenERP Server 7.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-01-24 14:43+0000\n" +"PO-Revision-Date: 2014-01-24 14:43+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: account_invoice_reference +#: view:account.invoice:0 +msgid "Enter the reference in the Supplier Invoice Number field" +msgstr "" + +#. module: account_invoice_reference +#: view:account.invoice:0 +msgid "{'invisible': [('reference_type', '=', 'none')]}" +msgstr "" + +#. module: account_invoice_reference +#: model:ir.model,name:account_invoice_reference.model_account_move +msgid "Account Entry" +msgstr "" + +#. module: account_invoice_reference +#: view:account.invoice:0 +msgid "Customer Reference" +msgstr "" + +#. module: account_invoice_reference +#: model:ir.model,name:account_invoice_reference.model_account_invoice +msgid "Invoice" +msgstr "" + diff --git a/account_invoice_reference/i18n/fr.po b/account_invoice_reference/i18n/fr.po new file mode 100644 index 00000000..6b7771c0 --- /dev/null +++ b/account_invoice_reference/i18n/fr.po @@ -0,0 +1,42 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# * account_invoice_reference +# +msgid "" +msgstr "" +"Project-Id-Version: OpenERP Server 7.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-01-24 14:43+0000\n" +"PO-Revision-Date: 2014-01-24 14:43+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: account_invoice_reference +#: view:account.invoice:0 +msgid "Enter the reference in the Supplier Invoice Number field" +msgstr "Veuillez saisir la référence dans le champ Numéro de facture fournisseur" + +#. module: account_invoice_reference +#: view:account.invoice:0 +msgid "{'invisible': [('reference_type', '=', 'none')]}" +msgstr "" + +#. module: account_invoice_reference +#: model:ir.model,name:account_invoice_reference.model_account_move +msgid "Account Entry" +msgstr "Pièce comptable" + +#. module: account_invoice_reference +#: view:account.invoice:0 +msgid "Customer Reference" +msgstr "Référence client" + +#. module: account_invoice_reference +#: model:ir.model,name:account_invoice_reference.model_account_invoice +msgid "Invoice" +msgstr "Facture" + From 78079b2fdc3bf7c174fbb81e71b4445b05c3f5a5 Mon Sep 17 00:00:00 2001 From: Guewen Baconnier Date: Wed, 29 Jan 2014 15:12:43 +0100 Subject: [PATCH 9/9] return too early --- account_invoice_reference/account_move.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/account_invoice_reference/account_move.py b/account_invoice_reference/account_move.py index 66877aed..b33a30e8 100644 --- a/account_invoice_reference/account_move.py +++ b/account_invoice_reference/account_move.py @@ -92,8 +92,9 @@ class account_invoice(orm.Model): if not invoice.reference: locvals = vals.copy() locvals['reference'] = vals['supplier_invoice_reference'] - return super(account_invoice, self).write(cr, uid, [invoice.id], - locvals, context=context) + super(account_invoice, self).write(cr, uid, [invoice.id], + locvals, context=context) + return True else: return super(account_invoice, self).write(cr, uid, ids, vals, context=context)