From 8f1a02e331f3b64d29f2cd9bd600c88d528690d0 Mon Sep 17 00:00:00 2001 From: Benoit Guillot Date: Wed, 29 Aug 2012 10:39:33 +0200 Subject: [PATCH 1/6] [IMP] add method to prepair refund and add context in the method def refund bzr revid: benoit.guillot@akretion.com.br-20120829083933-vfi198opk85dj91m --- addons/account/account_invoice.py | 102 +++++++++--------- .../account/wizard/account_invoice_refund.py | 2 +- 2 files changed, 54 insertions(+), 50 deletions(-) diff --git a/addons/account/account_invoice.py b/addons/account/account_invoice.py index 7bc9ceaaf61..41524e08bdf 100644 --- a/addons/account/account_invoice.py +++ b/addons/account/account_invoice.py @@ -1114,7 +1114,7 @@ class account_invoice(osv.osv): ids = self.search(cr, user, [('name',operator,name)] + args, limit=limit, context=context) return self.name_get(cr, user, ids, context) - def _refund_cleanup_lines(self, cr, uid, lines): + def _refund_cleanup_lines(self, cr, uid, lines, context=None): for line in lines: del line['id'] del line['invoice_id'] @@ -1126,60 +1126,64 @@ class account_invoice(osv.osv): line['invoice_line_tax_id'] = [(6,0, line.get('invoice_line_tax_id', [])) ] return map(lambda x: (0,0,x), lines) - def refund(self, cr, uid, ids, date=None, period_id=None, description=None, journal_id=None): - invoices = self.read(cr, uid, ids, ['name', 'type', 'number', 'reference', 'comment', 'date_due', 'partner_id', 'partner_contact', 'partner_insite', 'partner_ref', 'payment_term', 'account_id', 'currency_id', 'invoice_line', 'tax_line', 'journal_id', 'company_id']) + def prepair_refund(self, cr, uid, refund_id, invoice, date=None, period_id=None, description=None, journal_id=None, context=None): obj_invoice_line = self.pool.get('account.invoice.line') obj_invoice_tax = self.pool.get('account.invoice.tax') obj_journal = self.pool.get('account.journal') + del invoice['id'] + + type_dict = { + 'out_invoice': 'out_refund', # Customer Invoice + 'in_invoice': 'in_refund', # Supplier Invoice + 'out_refund': 'out_invoice', # Customer Refund + 'in_refund': 'in_invoice', # Supplier Refund + } + + invoice_lines = obj_invoice_line.read(cr, uid, invoice['invoice_line'], context=context) + invoice_lines = self._refund_cleanup_lines(cr, uid, invoice_lines, context=context) + + tax_lines = obj_invoice_tax.read(cr, uid, invoice['tax_line'], context=context) + tax_lines = filter(lambda l: l['manual'], tax_lines) + tax_lines = self._refund_cleanup_lines(cr, uid, tax_lines, context=context) + if journal_id: + refund_journal_ids = [journal_id] + elif invoice['type'] == 'in_invoice': + refund_journal_ids = obj_journal.search(cr, uid, [('type','=','purchase_refund')], context=context) + else: + refund_journal_ids = obj_journal.search(cr, uid, [('type','=','sale_refund')], context=context) + + if not date: + date = time.strftime('%Y-%m-%d') + invoice.update({ + 'type': type_dict[invoice['type']], + 'date_invoice': date, + 'state': 'draft', + 'number': False, + 'invoice_line': invoice_lines, + 'tax_line': tax_lines, + 'journal_id': refund_journal_ids + }) + if period_id: + invoice.update({ + 'period_id': period_id, + }) + if description: + invoice.update({ + 'name': description, + }) + # take the id part of the tuple returned for many2one fields + for field in ('partner_id', 'company_id', + 'account_id', 'currency_id', 'payment_term', 'journal_id'): + invoice[field] = invoice[field] and invoice[field][0] + return invoice + + def refund(self, cr, uid, ids, date=None, period_id=None, description=None, journal_id=None, context=None): + invoices = self.read(cr, uid, ids, ['name', 'type', 'number', 'reference', 'comment', 'date_due', 'partner_id', 'partner_contact', 'partner_insite', 'partner_ref', 'payment_term', 'account_id', 'currency_id', 'invoice_line', 'tax_line', 'journal_id', 'company_id'], context=context) new_ids = [] for invoice in invoices: - del invoice['id'] - - type_dict = { - 'out_invoice': 'out_refund', # Customer Invoice - 'in_invoice': 'in_refund', # Supplier Invoice - 'out_refund': 'out_invoice', # Customer Refund - 'in_refund': 'in_invoice', # Supplier Refund - } - - invoice_lines = obj_invoice_line.read(cr, uid, invoice['invoice_line']) - invoice_lines = self._refund_cleanup_lines(cr, uid, invoice_lines) - - tax_lines = obj_invoice_tax.read(cr, uid, invoice['tax_line']) - tax_lines = filter(lambda l: l['manual'], tax_lines) - tax_lines = self._refund_cleanup_lines(cr, uid, tax_lines) - if journal_id: - refund_journal_ids = [journal_id] - elif invoice['type'] == 'in_invoice': - refund_journal_ids = obj_journal.search(cr, uid, [('type','=','purchase_refund')]) - else: - refund_journal_ids = obj_journal.search(cr, uid, [('type','=','sale_refund')]) - - if not date: - date = time.strftime('%Y-%m-%d') - invoice.update({ - 'type': type_dict[invoice['type']], - 'date_invoice': date, - 'state': 'draft', - 'number': False, - 'invoice_line': invoice_lines, - 'tax_line': tax_lines, - 'journal_id': refund_journal_ids - }) - if period_id: - invoice.update({ - 'period_id': period_id, - }) - if description: - invoice.update({ - 'name': description, - }) - # take the id part of the tuple returned for many2one fields - for field in ('partner_id', 'company_id', - 'account_id', 'currency_id', 'payment_term', 'journal_id'): - invoice[field] = invoice[field] and invoice[field][0] + invoice = self.prepair_refund(cr, uid, invoice['id'], invoice, date=date, period_id=period_id, description=description, journal_id=journal_id, context=context) # create the new invoice - new_ids.append(self.create(cr, uid, invoice)) + new_ids.append(self.create(cr, uid, invoice, context=context)) return new_ids diff --git a/addons/account/wizard/account_invoice_refund.py b/addons/account/wizard/account_invoice_refund.py index b7d278b8849..a549f09e00b 100644 --- a/addons/account/wizard/account_invoice_refund.py +++ b/addons/account/wizard/account_invoice_refund.py @@ -146,7 +146,7 @@ class account_invoice_refund(osv.osv_memory): raise osv.except_osv(_('Insufficient Data!'), \ _('No period found on the invoice.')) - refund_id = inv_obj.refund(cr, uid, [inv.id], date, period, description, journal_id) + refund_id = inv_obj.refund(cr, uid, [inv.id], date, period, description, journal_id, context=context) refund = inv_obj.browse(cr, uid, refund_id[0], context=context) inv_obj.write(cr, uid, [refund.id], {'date_due': date, 'check_total': inv.check_total}) From 4b614305d4066e7b97045a1641aed925ae709b17 Mon Sep 17 00:00:00 2001 From: Benoit Guillot Date: Wed, 29 Aug 2012 10:40:32 +0200 Subject: [PATCH 2/6] [IMP] add context on the call of the method refund bzr revid: benoit.guillot@akretion.com.br-20120829084032-9ow83wx3kcmrvep7 --- addons/point_of_sale/wizard/pos_return.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/point_of_sale/wizard/pos_return.py b/addons/point_of_sale/wizard/pos_return.py index 0e5d4e1fbb5..c56fe5fd572 100644 --- a/addons/point_of_sale/wizard/pos_return.py +++ b/addons/point_of_sale/wizard/pos_return.py @@ -278,7 +278,7 @@ class add_product(osv.osv_memory): location_id=res and res[0] or None if order_id.invoice_id: - invoice_obj.refund(cr, uid, [order_id.invoice_id.id], time.strftime('%Y-%m-%d'), False, order_id.name) + invoice_obj.refund(cr, uid, [order_id.invoice_id.id], time.strftime('%Y-%m-%d'), False, order_id.name, context=context) new_picking=picking_obj.create(cr, uid, { 'name':'%s (return)' %order_id.name, 'move_lines':[], 'state':'draft', From e6f172b66d3db990aa1804716d7756339e9e82c1 Mon Sep 17 00:00:00 2001 From: Benoit Guillot Date: Wed, 29 Aug 2012 17:34:48 +0200 Subject: [PATCH 3/6] [FIX] fix typo bzr revid: benoit.guillot@akretion.com.br-20120829153448-i4ek7jny5hqgid1a --- addons/account/account_invoice.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/addons/account/account_invoice.py b/addons/account/account_invoice.py index 41524e08bdf..7ec504fa5e8 100644 --- a/addons/account/account_invoice.py +++ b/addons/account/account_invoice.py @@ -1126,7 +1126,7 @@ class account_invoice(osv.osv): line['invoice_line_tax_id'] = [(6,0, line.get('invoice_line_tax_id', [])) ] return map(lambda x: (0,0,x), lines) - def prepair_refund(self, cr, uid, refund_id, invoice, date=None, period_id=None, description=None, journal_id=None, context=None): + def _prepare_refund(self, cr, uid, refund_id, invoice, date=None, period_id=None, description=None, journal_id=None, context=None): obj_invoice_line = self.pool.get('account.invoice.line') obj_invoice_tax = self.pool.get('account.invoice.tax') obj_journal = self.pool.get('account.journal') @@ -1181,7 +1181,12 @@ class account_invoice(osv.osv): invoices = self.read(cr, uid, ids, ['name', 'type', 'number', 'reference', 'comment', 'date_due', 'partner_id', 'partner_contact', 'partner_insite', 'partner_ref', 'payment_term', 'account_id', 'currency_id', 'invoice_line', 'tax_line', 'journal_id', 'company_id'], context=context) new_ids = [] for invoice in invoices: - invoice = self.prepair_refund(cr, uid, invoice['id'], invoice, date=date, period_id=period_id, description=description, journal_id=journal_id, context=context) + invoice = self._prepare_refund(cr, uid, invoice['id'], invoice, + date=date, + period_id=period_id, + description=description, + journal_id=journal_id, + context=context) # create the new invoice new_ids.append(self.create(cr, uid, invoice, context=context)) From f4ea0af205d001110683dd8f1d11a97bf2d6724f Mon Sep 17 00:00:00 2001 From: Benoit Guillot Date: Wed, 10 Oct 2012 17:37:24 +0200 Subject: [PATCH 4/6] [IMP] add docstring and fix refund_id arg. Add also a new prepare method _prepapre_cleanup_fields() to override the fields of the refund lines bzr revid: benoit.guillot@akretion.com.br-20121010153724-rgjiluytvz3z7qju --- addons/account/account_invoice.py | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/addons/account/account_invoice.py b/addons/account/account_invoice.py index 7ec504fa5e8..ad29b199599 100644 --- a/addons/account/account_invoice.py +++ b/addons/account/account_invoice.py @@ -1114,19 +1114,43 @@ class account_invoice(osv.osv): ids = self.search(cr, user, [('name',operator,name)] + args, limit=limit, context=context) return self.name_get(cr, user, ids, context) + def _prepare_cleanup_fields(self, cr, uid, context=None): + """Prepare the list of the fields to use to create the refund lines + with the method _refund_cleanup_lines(). This method may be + overriden to add or remove fields to customize the refund lines + generetion (making sure to call super() to establish + a clean extension chain). + + retrun: tuple of fields to create() the refund lines + """ + return ('company_id', 'partner_id', 'account_id', 'product_id', + 'uos_id', 'account_analytic_id', 'tax_code_id', 'base_code_id') + def _refund_cleanup_lines(self, cr, uid, lines, context=None): for line in lines: del line['id'] del line['invoice_id'] - for field in ('company_id', 'partner_id', 'account_id', 'product_id', - 'uos_id', 'account_analytic_id', 'tax_code_id', 'base_code_id'): + for field in self._prepare_cleanup_fields(cr, uid, context=context): if line.get(field): line[field] = line[field][0] if 'invoice_line_tax_id' in line: line['invoice_line_tax_id'] = [(6,0, line.get('invoice_line_tax_id', [])) ] return map(lambda x: (0,0,x), lines) - def _prepare_refund(self, cr, uid, refund_id, invoice, date=None, period_id=None, description=None, journal_id=None, context=None): + def _prepare_refund(self, cr, uid, invoice_id, invoice, date=None, period_id=None, description=None, journal_id=None, context=None): + """Prepare the dict of values to create the new refund from the invoice. + This method may be overridden to implement custom + refund generation (making sure to call super() to establish + a clean extension chain). + + :param integer invoice_id: id of the invoice to refund + :param dict invoice: read of the invoice to refund + :param date date: refund creation date from the wizard + :param integer period_id: force account.period from the wizard + :param char description: description of the refund from the wizard + :param integer journal_id: account.journal from the wizard + :return: dict of value to create() the refund + """ obj_invoice_line = self.pool.get('account.invoice.line') obj_invoice_tax = self.pool.get('account.invoice.tax') obj_journal = self.pool.get('account.journal') From 8ee703031a5d295d7709d9f3301eb3fd3055f258 Mon Sep 17 00:00:00 2001 From: Benoit Guillot Date: Fri, 12 Oct 2012 14:24:06 +0200 Subject: [PATCH 5/6] [IMP] use browse_record instead of dict for refund creation bzr revid: benoit.guillot@akretion.com.br-20121012122406-7ghe5pazc430wtqm --- addons/account/account_invoice.py | 75 ++++++++++++++----------------- 1 file changed, 33 insertions(+), 42 deletions(-) diff --git a/addons/account/account_invoice.py b/addons/account/account_invoice.py index ad29b199599..2b8c2e3f099 100644 --- a/addons/account/account_invoice.py +++ b/addons/account/account_invoice.py @@ -1114,30 +1114,24 @@ class account_invoice(osv.osv): ids = self.search(cr, user, [('name',operator,name)] + args, limit=limit, context=context) return self.name_get(cr, user, ids, context) - def _prepare_cleanup_fields(self, cr, uid, context=None): - """Prepare the list of the fields to use to create the refund lines - with the method _refund_cleanup_lines(). This method may be - overriden to add or remove fields to customize the refund lines - generetion (making sure to call super() to establish - a clean extension chain). - - retrun: tuple of fields to create() the refund lines - """ - return ('company_id', 'partner_id', 'account_id', 'product_id', - 'uos_id', 'account_analytic_id', 'tax_code_id', 'base_code_id') - def _refund_cleanup_lines(self, cr, uid, lines, context=None): + clean_lines = [] for line in lines: - del line['id'] - del line['invoice_id'] - for field in self._prepare_cleanup_fields(cr, uid, context=context): - if line.get(field): - line[field] = line[field][0] - if 'invoice_line_tax_id' in line: - line['invoice_line_tax_id'] = [(6,0, line.get('invoice_line_tax_id', [])) ] - return map(lambda x: (0,0,x), lines) + clean_line = {} + for field in line._all_columns.keys(): + if line._all_columns[field].column._type == 'many2one': + clean_line[field] = line[field].id + elif line._all_columns[field].column._type == 'many2many': + m2m_list = [] + for link in line[field]: + m2m_list.append(link.id) + clean_line[field] = [(6,0, m2m_list)] + else: + clean_line[field] = line[field] + clean_lines.append(clean_line) + return map(lambda x: (0,0,x), clean_lines) - def _prepare_refund(self, cr, uid, invoice_id, invoice, date=None, period_id=None, description=None, journal_id=None, context=None): + def _prepare_refund(self, cr, uid, invoice, date=None, period_id=None, description=None, journal_id=None, context=None): """Prepare the dict of values to create the new refund from the invoice. This method may be overridden to implement custom refund generation (making sure to call super() to establish @@ -1145,16 +1139,13 @@ class account_invoice(osv.osv): :param integer invoice_id: id of the invoice to refund :param dict invoice: read of the invoice to refund - :param date date: refund creation date from the wizard + :param string date: refund creation date from the wizard :param integer period_id: force account.period from the wizard - :param char description: description of the refund from the wizard + :param string description: description of the refund from the wizard :param integer journal_id: account.journal from the wizard :return: dict of value to create() the refund """ - obj_invoice_line = self.pool.get('account.invoice.line') - obj_invoice_tax = self.pool.get('account.invoice.tax') obj_journal = self.pool.get('account.journal') - del invoice['id'] type_dict = { 'out_invoice': 'out_refund', # Customer Invoice @@ -1162,12 +1153,17 @@ class account_invoice(osv.osv): 'out_refund': 'out_invoice', # Customer Refund 'in_refund': 'in_invoice', # Supplier Refund } + invoice_data = {} + for field in ['name', 'reference', 'comment', 'date_due', 'partner_id', 'company_id', + 'account_id', 'currency_id', 'payment_term', 'journal_id']: + if invoice._all_columns[field].column._type == 'many2one': + invoice_data[field] = invoice[field].id + else: + invoice_data[field] = invoice[field] and invoice[field] or False - invoice_lines = obj_invoice_line.read(cr, uid, invoice['invoice_line'], context=context) - invoice_lines = self._refund_cleanup_lines(cr, uid, invoice_lines, context=context) + invoice_lines = self._refund_cleanup_lines(cr, uid, invoice.invoice_line, context=context) - tax_lines = obj_invoice_tax.read(cr, uid, invoice['tax_line'], context=context) - tax_lines = filter(lambda l: l['manual'], tax_lines) + tax_lines = filter(lambda l: l['manual'], invoice.tax_line) tax_lines = self._refund_cleanup_lines(cr, uid, tax_lines, context=context) if journal_id: refund_journal_ids = [journal_id] @@ -1178,34 +1174,29 @@ class account_invoice(osv.osv): if not date: date = time.strftime('%Y-%m-%d') - invoice.update({ + invoice_data.update({ 'type': type_dict[invoice['type']], 'date_invoice': date, 'state': 'draft', 'number': False, 'invoice_line': invoice_lines, 'tax_line': tax_lines, - 'journal_id': refund_journal_ids + 'journal_id': refund_journal_ids and refund_journal_ids[0] or False, }) if period_id: - invoice.update({ + invoice_data.update({ 'period_id': period_id, }) if description: - invoice.update({ + invoice_data.update({ 'name': description, }) - # take the id part of the tuple returned for many2one fields - for field in ('partner_id', 'company_id', - 'account_id', 'currency_id', 'payment_term', 'journal_id'): - invoice[field] = invoice[field] and invoice[field][0] - return invoice + return invoice_data def refund(self, cr, uid, ids, date=None, period_id=None, description=None, journal_id=None, context=None): - invoices = self.read(cr, uid, ids, ['name', 'type', 'number', 'reference', 'comment', 'date_due', 'partner_id', 'partner_contact', 'partner_insite', 'partner_ref', 'payment_term', 'account_id', 'currency_id', 'invoice_line', 'tax_line', 'journal_id', 'company_id'], context=context) new_ids = [] - for invoice in invoices: - invoice = self._prepare_refund(cr, uid, invoice['id'], invoice, + for invoice in self.browse(cr, uid, ids, context=context): + invoice = self._prepare_refund(cr, uid, invoice, date=date, period_id=period_id, description=description, From 1e9d0c49040136d862f15faf66e15b2e6b716c61 Mon Sep 17 00:00:00 2001 From: Benoit Guillot Date: Tue, 16 Oct 2012 18:22:51 +0200 Subject: [PATCH 6/6] [FIX] skip the one2many and the many2one fields in the invoice line and support invoice_line_tax_id bzr revid: benoit.guillot@akretion.com.br-20121016162251-iwgwq6h1po9uinr8 --- addons/account/account_invoice.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/addons/account/account_invoice.py b/addons/account/account_invoice.py index 2b8c2e3f099..7ae25f6ed33 100644 --- a/addons/account/account_invoice.py +++ b/addons/account/account_invoice.py @@ -1121,13 +1121,13 @@ class account_invoice(osv.osv): for field in line._all_columns.keys(): if line._all_columns[field].column._type == 'many2one': clean_line[field] = line[field].id - elif line._all_columns[field].column._type == 'many2many': - m2m_list = [] - for link in line[field]: - m2m_list.append(link.id) - clean_line[field] = [(6,0, m2m_list)] - else: + elif line._all_columns[field].column._type not in ['many2many','one2many']: clean_line[field] = line[field] + elif field == 'invoice_line_tax_id': + tax_list = [] + for tax in line[field]: + tax_list.append(tax.id) + clean_line[field] = [(6,0, tax_list)] clean_lines.append(clean_line) return map(lambda x: (0,0,x), clean_lines) @@ -1155,7 +1155,7 @@ class account_invoice(osv.osv): } invoice_data = {} for field in ['name', 'reference', 'comment', 'date_due', 'partner_id', 'company_id', - 'account_id', 'currency_id', 'payment_term', 'journal_id']: + 'account_id', 'currency_id', 'payment_term']: if invoice._all_columns[field].column._type == 'many2one': invoice_data[field] = invoice[field].id else: