From 39ba10d8ac4bf21163f47a3e250e7d72a0eefc7c Mon Sep 17 00:00:00 2001 From: Holger Brunn Date: Thu, 29 Dec 2016 17:09:40 +0100 Subject: [PATCH 1/3] [ADD] migration of account_invoice_import_invoice2data and dependencies --- .travis.yml | 3 +- README.md | 1 + account_invoice_import/README.rst | 2 +- account_invoice_import/__init__.py | 7 +- account_invoice_import/__openerp__.py | 10 +- account_invoice_import/models/__init__.py | 4 + .../{ => models}/account_invoice.py | 0 .../account_invoice_import_config.py | 2 +- .../{ => models}/partner.py | 0 .../account_invoice_import_config_view.xml | 2 +- .../{ => views}/partner_view.xml | 0 .../{wizard => wizards}/__init__.py | 0 .../account_invoice_import.py | 135 +++++++++++------- .../account_invoice_import_view.xml | 0 .../README.rst | 2 +- .../__openerp__.py | 4 +- .../tests/test_invoice_import.py | 25 ++-- .../wizard/account_invoice_import.py | 2 +- base_business_document_import/README.rst | 4 +- base_business_document_import/__openerp__.py | 4 +- .../models/business_document_import.py | 23 +-- .../tests/test_business_document_import.py | 12 +- 22 files changed, 139 insertions(+), 103 deletions(-) create mode 100644 account_invoice_import/models/__init__.py rename account_invoice_import/{ => models}/account_invoice.py (100%) rename account_invoice_import/{ => models}/account_invoice_import_config.py (98%) rename account_invoice_import/{ => models}/partner.py (100%) rename account_invoice_import/{ => views}/account_invoice_import_config_view.xml (98%) rename account_invoice_import/{ => views}/partner_view.xml (100%) rename account_invoice_import/{wizard => wizards}/__init__.py (100%) rename account_invoice_import/{wizard => wizards}/account_invoice_import.py (87%) rename account_invoice_import/{wizard => wizards}/account_invoice_import_view.xml (100%) diff --git a/.travis.yml b/.travis.yml index e5274781f6..61665a7a6d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -49,7 +49,8 @@ install: - git clone --depth=1 https://github.com/OCA/maintainer-quality-tools.git ${HOME}/maintainer-quality-tools - export PATH=${HOME}/maintainer-quality-tools/travis:${PATH} - travis_install_nightly - - pip install invoice2data +# use patched lib for now; that's okay to merge because nobody could use this before anyways + - pip install https://github.com/hbrunn/invoice2data/tarball/master-extract_lines#egg=invoice2data - wget -P /tmp http://public.akretion.com/pdftotext-3.04 - sudo mv /tmp/pdftotext-3.04 /usr/local/bin/pdftotext - sudo chmod 755 /usr/local/bin/pdftotext diff --git a/README.md b/README.md index d0650bff4c..56512dfcfc 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ EDI Modules [//]: # (addons) + Unported addons --------------- addon | version | summary diff --git a/account_invoice_import/README.rst b/account_invoice_import/README.rst index 5f7f8d6c13..b7b3929453 100644 --- a/account_invoice_import/README.rst +++ b/account_invoice_import/README.rst @@ -41,7 +41,7 @@ Go to the form view of the suppliers and configure it with the following paramet Usage ===== -To use this module, go to the menu *Accounting > Suppliers > Import Invoices* and upload a PDF or XML invoice of your supplier. +To use this module, go to the menu *Accounting > Purchases > Import Invoices* and upload a PDF or XML invoice of your supplier. .. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas :alt: Try me on Runbot diff --git a/account_invoice_import/__init__.py b/account_invoice_import/__init__.py index a9731feaa7..862180dead 100644 --- a/account_invoice_import/__init__.py +++ b/account_invoice_import/__init__.py @@ -1,6 +1,3 @@ # -*- coding: utf-8 -*- - -from . import partner -from . import account_invoice_import_config -from . import account_invoice -from . import wizard +from . import models +from . import wizards diff --git a/account_invoice_import/__openerp__.py b/account_invoice_import/__openerp__.py index 49850c378b..122f9fae5d 100644 --- a/account_invoice_import/__openerp__.py +++ b/account_invoice_import/__openerp__.py @@ -4,7 +4,7 @@ { 'name': 'Account Invoice Import', - 'version': '8.0.1.0.0', + 'version': '9.0.1.0.0', 'category': 'Accounting & Finance', 'license': 'AGPL-3', 'summary': 'Import supplier invoices/refunds as PDF or XML files', @@ -14,11 +14,11 @@ 'data': [ 'security/ir.model.access.csv', 'security/rule.xml', - 'account_invoice_import_config_view.xml', - 'wizard/account_invoice_import_view.xml', + 'views/account_invoice_import_config_view.xml', + 'wizards/account_invoice_import_view.xml', 'views/account_invoice.xml', - 'partner_view.xml', + 'views/partner_view.xml', ], 'images': ['images/sshot-wizard1.png'], - 'installable': False, + 'installable': True, } diff --git a/account_invoice_import/models/__init__.py b/account_invoice_import/models/__init__.py new file mode 100644 index 0000000000..accb64a32f --- /dev/null +++ b/account_invoice_import/models/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +from . import partner +from . import account_invoice_import_config +from . import account_invoice diff --git a/account_invoice_import/account_invoice.py b/account_invoice_import/models/account_invoice.py similarity index 100% rename from account_invoice_import/account_invoice.py rename to account_invoice_import/models/account_invoice.py diff --git a/account_invoice_import/account_invoice_import_config.py b/account_invoice_import/models/account_invoice_import_config.py similarity index 98% rename from account_invoice_import/account_invoice_import_config.py rename to account_invoice_import/models/account_invoice_import_config.py index 4de1b70b78..a21bec45ba 100644 --- a/account_invoice_import/account_invoice_import_config.py +++ b/account_invoice_import/models/account_invoice_import_config.py @@ -34,7 +34,7 @@ class AccountInvoiceImportConfig(models.Model): 'account.invoice.import.config')) account_id = fields.Many2one( 'account.account', string='Expense Account', - domain=[('type', 'not in', ('view', 'closed'))]) + domain=[('deprecated', '=', False)]) account_analytic_id = fields.Many2one( 'account.analytic.account', string='Analytic Account', domain=[('type', '!=', 'view')]) diff --git a/account_invoice_import/partner.py b/account_invoice_import/models/partner.py similarity index 100% rename from account_invoice_import/partner.py rename to account_invoice_import/models/partner.py diff --git a/account_invoice_import/account_invoice_import_config_view.xml b/account_invoice_import/views/account_invoice_import_config_view.xml similarity index 98% rename from account_invoice_import/account_invoice_import_config_view.xml rename to account_invoice_import/views/account_invoice_import_config_view.xml index 5f45adf7e0..b03bdfedf0 100644 --- a/account_invoice_import/account_invoice_import_config_view.xml +++ b/account_invoice_import/views/account_invoice_import_config_view.xml @@ -60,7 +60,7 @@ diff --git a/account_invoice_import/partner_view.xml b/account_invoice_import/views/partner_view.xml similarity index 100% rename from account_invoice_import/partner_view.xml rename to account_invoice_import/views/partner_view.xml diff --git a/account_invoice_import/wizard/__init__.py b/account_invoice_import/wizards/__init__.py similarity index 100% rename from account_invoice_import/wizard/__init__.py rename to account_invoice_import/wizards/__init__.py diff --git a/account_invoice_import/wizard/account_invoice_import.py b/account_invoice_import/wizards/account_invoice_import.py similarity index 87% rename from account_invoice_import/wizard/account_invoice_import.py rename to account_invoice_import/wizards/account_invoice_import.py index 53b54cba0d..07fd8d9100 100644 --- a/account_invoice_import/wizard/account_invoice_import.py +++ b/account_invoice_import/wizards/account_invoice_import.py @@ -103,7 +103,7 @@ def fallback_parse_pdf_invoice(self, file_data): # 'note': 'Note embedded in the document', # 'lines': [{ # 'product': { - # 'ean13': '4123456000021', + # 'barcode': '4123456000021', # 'code': 'GZ250', # }, # 'name': 'Gelierzucker Extra 250g', @@ -117,7 +117,6 @@ def fallback_parse_pdf_invoice(self, file_data): @api.model def _prepare_create_invoice_vals(self, parsed_inv): aio = self.env['account.invoice'] - ailo = self.env['account.invoice.line'] bdio = self.env['business.document.import'] rpo = self.env['res.partner'] company = self.env.user.company_id @@ -132,16 +131,22 @@ def _prepare_create_invoice_vals(self, parsed_inv): 'currency_id': currency.id, 'type': parsed_inv['type'], 'company_id': company.id, - 'supplier_invoice_number': - parsed_inv.get('invoice_number'), + 'reference': parsed_inv.get('invoice_number'), 'date_invoice': parsed_inv.get('date'), 'journal_id': aio.with_context(type='in_invoice')._default_journal().id, - 'invoice_line': [], - 'check_total': parsed_inv.get('amount_total'), - } - vals.update(aio.onchange_partner_id( - 'in_invoice', partner.id, company_id=company.id)['value']) + 'invoice_line_ids': [], + } + new_invoice = aio.new(vals) + new_invoice._onchange_partner_id() + vals.update({ + f: aio._fields[f].convert_to_write(v) + if not isinstance(new_invoice._fields[f], + fields._RelationalMulti) + else v.ids + for f, v in new_invoice._cache.iteritems() + }) + # Force due date of the invoice if parsed_inv.get('date_due'): vals['date_due'] = parsed_inv.get('date_due') @@ -158,16 +163,15 @@ def _prepare_create_invoice_vals(self, parsed_inv): if config.invoice_line_method == '1line_no_product': il_vals = { 'account_id': config.account_id.id, - 'invoice_line_tax_id': config.tax_ids.ids or False, + 'invoice_line_tax_ids': config.tax_ids.ids or False, 'price_unit': parsed_inv.get('amount_untaxed'), } elif config.invoice_line_method == '1line_static_product': product = config.static_product_id - il_vals = ailo.product_id_change( - product.id, product.uom_id.id, type='in_invoice', - partner_id=partner.id, - fposition_id=partner.property_account_position.id, - company_id=company.id)['value'] + il_vals = self._amend_create_invoice_line_vals( + product, 'in_invoice', partner, + partner.property_account_position_id, company + ) il_vals.update({ 'product_id': product.id, 'price_unit': parsed_inv.get('amount_untaxed'), @@ -180,7 +184,7 @@ def _prepare_create_invoice_vals(self, parsed_inv): il_vals['name'] = _('MISSING DESCRIPTION') self.set_1line_price_unit_and_quantity(il_vals, parsed_inv) self.set_1line_start_end_dates(il_vals, parsed_inv) - vals['invoice_line'].append((0, 0, il_vals)) + vals['invoice_line_ids'].append((0, 0, il_vals)) elif config.invoice_line_method.startswith('nline'): if not parsed_inv.get('lines'): raise UserError(_( @@ -193,11 +197,10 @@ def _prepare_create_invoice_vals(self, parsed_inv): } elif config.invoice_line_method == 'nline_static_product': sproduct = config.static_product_id - static_vals = ailo.product_id_change( - sproduct.id, sproduct.uom_id.id, type='in_invoice', - partner_id=partner.id, - fposition_id=partner.property_account_position.id, - company_id=company.id)['value'] + static_vals = self._amend_create_invoice_line_vals( + sproduct, 'in_invoice', partner, + partner.property_account_position_id, company + ) static_vals['product_id'] = sproduct.id else: static_vals = {} @@ -207,18 +210,17 @@ def _prepare_create_invoice_vals(self, parsed_inv): product = bdio._match_product( line['product'], parsed_inv['chatter_msg'], seller=partner) - fposition_id = partner.property_account_position.id il_vals.update( - ailo.product_id_change( - product.id, product.uom_id.id, type='in_invoice', - partner_id=partner.id, - fposition_id=fposition_id, - company_id=company.id)['value']) + self._amend_create_invoice_line_vals( + product, 'in_invoice', partner, + partner.property_account_position_id, company + ) + ) il_vals['product_id'] = product.id elif config.invoice_line_method == 'nline_no_product': taxes = bdio._match_taxes( line.get('taxes'), parsed_inv['chatter_msg']) - il_vals['invoice_line_tax_id'] = taxes.ids + il_vals['invoice_line_tax_ids'] = taxes.ids if line.get('name'): il_vals['name'] = line['name'] elif not il_vals.get('name'): @@ -230,27 +232,53 @@ def _prepare_create_invoice_vals(self, parsed_inv): 'quantity': line['qty'], 'price_unit': line['price_unit'], # TODO fix for tax incl }) - vals['invoice_line'].append((0, 0, il_vals)) + vals['invoice_line_ids'].append((0, 0, il_vals)) # Write analytic account + fix syntax for taxes aacount_id = config.account_analytic_id.id or False - for line in vals['invoice_line']: + for line in vals['invoice_line_ids']: line_dict = line[2] - if line_dict.get('invoice_line_tax_id'): - line_dict['invoice_line_tax_id'] = [ - (6, 0, line_dict['invoice_line_tax_id'])] + if line_dict.get('invoice_line_tax_ids'): + line_dict['invoice_line_tax_ids'] = [ + (6, 0, line_dict['invoice_line_tax_ids'])] if aacount_id: line_dict['account_analytic_id'] = aacount_id return vals + @api.model + def _amend_create_invoice_line_vals( + self, product, invoice_type, partner, fposition, company + ): + new_invoice = self.env['account.invoice'].new({ + 'type': invoice_type, + 'partner_id': partner, + 'fiscal_position_id': fposition, + 'company_id': company, + }) + new_invoice._onchange_partner_id() + new_invoice_line = self.env['account.invoice.line'].new({ + 'invoice_id': new_invoice, + 'product_id': product, + 'uom_id': product.uom_id + }) + new_invoice_line._onchange_product_id() + return { + f: new_invoice_line._fields[f].convert_to_write(v) + if not isinstance(new_invoice_line._fields[f], + fields._RelationalMulti) + else v.ids + for f, v in new_invoice_line._cache.iteritems() + if f != 'invoice_id' + } + @api.model def set_1line_price_unit_and_quantity(self, il_vals, parsed_inv): """For the moment, we only take into account the 'price_include' option of the first tax""" il_vals['quantity'] = 1 il_vals['price_unit'] = parsed_inv.get('amount_total') - if il_vals.get('invoice_line_tax_id'): + if il_vals.get('invoice_line_tax_ids'): first_tax = self.env['account.tax'].browse( - il_vals['invoice_line_tax_id'][0]) + il_vals['invoice_line_tax_ids'][0]) if not first_tax.price_include: il_vals['price_unit'] = parsed_inv.get('amount_untaxed') @@ -367,9 +395,8 @@ def import_invoice(self): existing_invs = aio.search( domain + [( - 'supplier_invoice_number', - '=ilike', - parsed_inv.get('invoice_number'))]) + 'reference', '=ilike', parsed_inv.get('invoice_number') + )]) if existing_invs: raise UserError(_( "This invoice already exists in Odoo. It's " @@ -426,7 +453,7 @@ def _create_invoice(self, parsed_inv): @api.model def post_process_invoice(self, parsed_inv, invoice): - invoice.button_reset_taxes() + invoice.compute_taxes() # Force tax amount if necessary prec = self.env['decimal.precision'].precision_get('Account') if ( @@ -436,14 +463,14 @@ def post_process_invoice(self, parsed_inv, invoice): invoice.amount_total, parsed_inv['amount_total'], precision_digits=prec)): - if not invoice.tax_line: + if not invoice.tax_line_ids: raise UserError(_( "The total amount is different from the untaxed amount, " "but no tax has been configured !")) - initial_tax_amount = invoice.tax_line[0].amount + initial_tax_amount = invoice.tax_line_ids[0].amount tax_amount = parsed_inv['amount_total'] -\ parsed_inv['amount_untaxed'] - invoice.tax_line[0].amount = tax_amount + invoice.tax_line_ids[0].amount = tax_amount cur_symbol = invoice.currency_id.symbol invoice.message_post( 'The total tax amount has been forced to %s %s ' @@ -518,13 +545,19 @@ def update_invoice_lines(self, parsed_inv, invoice, seller): @api.model def _prepare_create_invoice_line(self, product, uom, import_line, invoice): - ailo = self.env['account.invoice.line'] - vals = ailo.product_id_change( - product.id, uom.id, qty=import_line['qty'], type='in_invoice', - partner_id=invoice.partner_id.id, - fposition_id=invoice.fiscal_position.id or False, - currency_id=invoice.currency_id.id, - company_id=invoice.company_id.id)['value'] + new_line = self.env['account.invoice.line'].new({ + 'invoice_id': invoice, + 'qty': import_line['qty'], + 'product_id': product, + }) + new_line._onchange_product_id() + vals = { + f: new_line._fields[f].convert_to_write(v) + if not isinstance(new_line._fields[f], + fields._RelationalMulti) + else v.ids + for f, v in new_line._cache.iteritems() + } vals.update({ 'product_id': product.id, 'price_unit': import_line.get('price_unit'), @@ -537,10 +570,8 @@ def _prepare_create_invoice_line(self, product, uom, import_line, invoice): def _prepare_update_invoice_vals(self, parsed_inv, partner): bdio = self.env['business.document.import'] vals = { - 'supplier_invoice_number': - parsed_inv.get('invoice_number'), + 'reference': parsed_inv.get('invoice_number'), 'date_invoice': parsed_inv.get('date'), - 'check_total': parsed_inv.get('amount_total'), } if parsed_inv.get('date_due'): vals['date_due'] = parsed_inv['date_due'] diff --git a/account_invoice_import/wizard/account_invoice_import_view.xml b/account_invoice_import/wizards/account_invoice_import_view.xml similarity index 100% rename from account_invoice_import/wizard/account_invoice_import_view.xml rename to account_invoice_import/wizards/account_invoice_import_view.xml diff --git a/account_invoice_import_invoice2data/README.rst b/account_invoice_import_invoice2data/README.rst index cdad6462fd..3c7a8fe80e 100644 --- a/account_invoice_import_invoice2data/README.rst +++ b/account_invoice_import_invoice2data/README.rst @@ -46,7 +46,7 @@ If you want to use only your custom invoice templates and ignore the templates p invoice2data_templates_dir = /opt/invoice2data_local_templates invoice2data_exclude_built_in_templates = True -French users should also install the module *l10n_fr_invoice_import* available in the `French localization `_, cf `this PR `_. +French users should also install the module *l10n_fr_invoice_import* available in the `French localization `_. Configuration ============= diff --git a/account_invoice_import_invoice2data/__openerp__.py b/account_invoice_import_invoice2data/__openerp__.py index e963a33756..acf9a1f7d8 100644 --- a/account_invoice_import_invoice2data/__openerp__.py +++ b/account_invoice_import_invoice2data/__openerp__.py @@ -4,7 +4,7 @@ { 'name': 'Account Invoice Import Invoice2data', - 'version': '8.0.1.0.0', + 'version': '9.0.1.0.0', 'category': 'Accounting & Finance', 'license': 'AGPL-3', 'summary': 'Import supplier invoices using the invoice2data lib', @@ -15,5 +15,5 @@ 'data': [], 'demo': ['demo/demo_data.xml'], 'images': ['images/sshot-wizard1.png'], - 'installable': False, + 'installable': True, } diff --git a/account_invoice_import_invoice2data/tests/test_invoice_import.py b/account_invoice_import_invoice2data/tests/test_invoice_import.py index 1b42f9a908..6f2be679e4 100644 --- a/account_invoice_import_invoice2data/tests/test_invoice_import.py +++ b/account_invoice_import_invoice2data/tests/test_invoice_import.py @@ -17,8 +17,14 @@ def setUp(self): 'description': 'FR-VAT-buy-20.0', 'amount': 0.2, 'type': 'percent', - 'account_collected_id': self.env.ref('account.a_expense').id, - 'account_paid_id': self.env.ref('account.a_expense').id, + 'account_collected_id': self.env['account.account'].search([ + ('user_type_id', '=', + self.env.ref('account.data_account_type_expenses').id) + ], limit=1).id, + 'account_paid_id': self.env['account.account'].search([ + ('user_type_id', '=', + self.env.ref('account.data_account_type_expenses').id) + ], limit=1).id, 'base_sign': -1, 'tax_sign': -1, 'type_tax_use': 'purchase', @@ -43,7 +49,7 @@ def test_import_free_invoice(self): invoices = self.env['account.invoice'].search([ ('state', '=', 'draft'), ('type', '=', 'in_invoice'), - ('supplier_invoice_number', '=', '562044387') + ('reference', '=', '562044387') ]) self.assertEquals(len(invoices), 1) inv = invoices[0] @@ -53,15 +59,13 @@ def test_import_free_invoice(self): inv.partner_id, self.env.ref('account_invoice_import_invoice2data.free')) self.assertEquals(inv.journal_id.type, 'purchase') - self.assertEquals( - float_compare(inv.check_total, 29.99, precision_digits=2), 0) self.assertEquals( float_compare(inv.amount_total, 29.99, precision_digits=2), 0) self.assertEquals( float_compare(inv.amount_untaxed, 24.99, precision_digits=2), 0) self.assertEquals( - len(inv.invoice_line), 1) - iline = inv.invoice_line[0] + len(inv.invoice_line_ids), 1) + iline = inv.invoice_line_ids[0] self.assertEquals(iline.name, 'Fiber optic access at the main office') self.assertEquals( iline.product_id, @@ -76,8 +80,7 @@ def test_import_free_invoice(self): # (we re-use the invoice created by the first import !) inv.write({ 'date_invoice': False, - 'supplier_invoice_number': False, - 'check_total': False, + 'reference': False, }) # New import with update of an existing draft invoice @@ -99,10 +102,8 @@ def test_import_free_invoice(self): invoices = self.env['account.invoice'].search([ ('state', '=', 'draft'), ('type', '=', 'in_invoice'), - ('supplier_invoice_number', '=', '562044387') + ('reference', '=', '562044387') ]) self.assertEquals(len(invoices), 1) inv = invoices[0] self.assertEquals(inv.date_invoice, '2015-07-02') - self.assertEquals( - float_compare(inv.check_total, 29.99, precision_digits=2), 0) diff --git a/account_invoice_import_invoice2data/wizard/account_invoice_import.py b/account_invoice_import_invoice2data/wizard/account_invoice_import.py index 73de4b6220..9b349d8bd8 100644 --- a/account_invoice_import_invoice2data/wizard/account_invoice_import.py +++ b/account_invoice_import_invoice2data/wizard/account_invoice_import.py @@ -55,7 +55,7 @@ def invoice2data_parse_invoice(self, file_data): templates) try: invoice2data_res = extract_data(file_name, templates=templates) - except Exception, e: + except Exception as e: raise UserError(_( "PDF Invoice parsing failed. Error message: %s") % e) if not invoice2data_res: diff --git a/base_business_document_import/README.rst b/base_business_document_import/README.rst index 1f32b35033..388e4681eb 100644 --- a/base_business_document_import/README.rst +++ b/base_business_document_import/README.rst @@ -8,9 +8,9 @@ Base Business Document Import This is a technical module ; it doesn't bring any useful feature by itself. This module is the base modules for 2 other modules : -* *account_invoice_import* which imports supplier invoices as PDF or XML files (this module also requires some additionnal modules such as *account_invoice_import_invoice2data*, *account_invoice_import_ubl*, etc... to support specific invoice formats), +* *account_invoice_import* which imports supplier invoices as PDF or XML files (this module also requires some additional modules such as *account_invoice_import_invoice2data*, *account_invoice_import_ubl*, etc... to support specific invoice formats), -* *sale_invoice_import* which imports sale orders as CSV, XML or PDF files (this module also requires some additionnal modules such as *sale_invoice_import_csv* or *sale_invoice_import_ubl* to support specific order formats) +* *sale_invoice_import* which imports sale orders as CSV, XML or PDF files (this module also requires some additional modules such as *sale_invoice_import_csv* or *sale_invoice_import_ubl* to support specific order formats) Configuration ============= diff --git a/base_business_document_import/__openerp__.py b/base_business_document_import/__openerp__.py index e8f43b20ef..8ba0be41bf 100644 --- a/base_business_document_import/__openerp__.py +++ b/base_business_document_import/__openerp__.py @@ -4,7 +4,7 @@ { 'name': 'Base Business Document Import', - 'version': '8.0.1.0.0', + 'version': '9.0.1.0.0', 'category': 'Tools', 'license': 'AGPL-3', 'summary': 'Provides technical tools to import sale orders or supplier ' @@ -17,5 +17,5 @@ 'product_uom_unece', ], 'external_dependencies': {'python': ['PyPDF2']}, - 'installable': False, + 'installable': True, } diff --git a/base_business_document_import/models/business_document_import.py b/base_business_document_import/models/business_document_import.py index 9e42beeb98..ee86b11cf2 100644 --- a/base_business_document_import/models/business_document_import.py +++ b/base_business_document_import/models/business_document_import.py @@ -274,7 +274,7 @@ def _match_partner_bank( def _match_product(self, product_dict, chatter_msg, seller=False): """Example: product_dict = { - 'ean13': '5449000054227', + 'barcode': '5449000054227', 'code': 'COCA1L', } """ @@ -284,15 +284,15 @@ def _match_product(self, product_dict, chatter_msg, seller=False): return product_dict['recordset'] if product_dict.get('id'): return ppo.browse(product_dict['id']) - if product_dict.get('ean13'): + if product_dict.get('barcode'): products = ppo.search([ - ('ean13', '=', product_dict['ean13'])]) + ('barcode', '=', product_dict['barcode'])]) if products: return products[0] if product_dict.get('code'): products = ppo.search([ '|', - ('ean13', '=', product_dict['code']), + ('barcode', '=', product_dict['code']), ('default_code', '=', product_dict['code'])]) if products: return products[0] @@ -316,7 +316,7 @@ def _match_product(self, product_dict, chatter_msg, seller=False): "EAN13: %s\n" "Product code: %s\n" "Supplier: %s\n") % ( - product_dict.get('ean13'), + product_dict.get('barcode'), product_dict.get('code'), seller and seller.name or 'None')) @@ -465,7 +465,7 @@ def _match_tax( type_tax_use='purchase', price_include=False): """Example: tax_dict = { - 'type': 'percent', # required param, 'fixed' or 'percent' + 'amount_type': 'percent', # required param, 'fixed' or 'percent' 'amount': 20.0, # required 'unece_type_code': 'VAT', 'unece_categ_code': 'S', @@ -491,9 +491,10 @@ def _match_tax( domain.append(('price_include', '=', True)) # with the code abose, if you set price_include=None, it will # won't depend on the value of the price_include parameter - assert tax_dict.get('type') in ['fixed', 'percent'], 'bad tax type' + assert tax_dict.get('amount_type') in ['fixed', 'percent'],\ + 'bad tax type' assert 'amount' in tax_dict, 'Missing amount key in tax_dict' - domain.append(('type', '=', tax_dict['type'])) + domain.append(('amount_type', '=', tax_dict['amount_type'])) if tax_dict.get('unece_type_code'): domain.append( ('unece_type_code', '=', tax_dict['unece_type_code'])) @@ -503,7 +504,7 @@ def _match_tax( taxes = ato.search(domain) for tax in taxes: tax_amount = tax.amount - if tax_dict['type'] == 'percent': + if tax_dict['amount_type'] == 'percent': tax_amount *= 100 if not float_compare( tax_dict['amount'], tax_amount, precision_digits=prec): @@ -520,7 +521,7 @@ def _match_tax( tax_dict.get('unece_type_code'), tax_dict.get('unece_categ_code'), tax_dict['amount'], - tax_dict['type'] == 'percent' and '%' or _('(fixed)'))) + tax_dict['amount_type'] == 'percent' and '%' or _('(fixed)'))) def compare_lines( self, existing_lines, import_lines, chatter_msg, @@ -537,7 +538,7 @@ def compare_lines( }] import_lines = [{ 'product': { - 'ean13': '2100002000003', + 'barcode': '2100002000003', 'code': 'EAZY1', }, 'quantity': 2, diff --git a/base_business_document_import/tests/test_business_document_import.py b/base_business_document_import/tests/test_business_document_import.py index aff3bb37f6..4a087b43f2 100644 --- a/base_business_document_import/tests/test_business_document_import.py +++ b/base_business_document_import/tests/test_business_document_import.py @@ -56,7 +56,7 @@ def test_match_shipping_partner(self): 'name': u'Sébastien BEAU', 'email': 'sebastien.beau@akretion.com', 'use_parent_address': True, - 'type': 'default', + 'type': 'contact', }) cpartner3 = rpo.create({ 'parent_id': partner1.id, @@ -115,7 +115,7 @@ def test_match_product(self): ppo = self.env['product.product'] product1 = ppo.create({ 'name': u'Test Product', - 'ean13': '9782203121102', + 'barcode': '9782203121102', 'seller_ids': [ (0, 0, { 'name': self.env.ref('base.res_partner_2').id, @@ -126,7 +126,7 @@ def test_match_product(self): product_dict = {'code': u'A2324 '} res = bdio._match_product(product_dict, []) self.assertEquals(res, self.env.ref('product.product_product_4b')) - product_dict = {'ean13': u'9782203121102'} + product_dict = {'barcode': u'9782203121102'} res = bdio._match_product(product_dict, []) self.assertEquals(res, product1) product_dict = {'code': 'TEST1242'} @@ -169,7 +169,7 @@ def test_match_tax(self): 'type_tax_use': 'purchase', 'price_include': False, 'amount': 0.18, - 'type': 'percent', + 'amount_type': 'percent', 'unece_type_id': self.env.ref('account_tax_unece.tax_type_vat').id, 'unece_categ_id': self.env.ref('account_tax_unece.tax_categ_s').id, }) @@ -179,13 +179,13 @@ def test_match_tax(self): 'type_tax_use': 'purchase', 'price_include': True, 'amount': 0.18, - 'type': 'percent', + 'amount_type': 'percent', 'unece_type_id': self.env.ref('account_tax_unece.tax_type_vat').id, 'unece_categ_id': self.env.ref('account_tax_unece.tax_categ_s').id, }) bdio = self.env['business.document.import'] tax_dict = { - 'type': 'percent', + 'amount_type': 'percent', 'amount': 18, 'unece_type_code': 'VAT', 'unece_categ_code': 'S', From 454c1164ac6de23301d87d8834cc0427fc6fa476 Mon Sep 17 00:00:00 2001 From: Holger Brunn Date: Wed, 10 May 2017 13:25:31 +0200 Subject: [PATCH 2/3] [DEL] we don't need the patched lib here --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 61665a7a6d..e5274781f6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -49,8 +49,7 @@ install: - git clone --depth=1 https://github.com/OCA/maintainer-quality-tools.git ${HOME}/maintainer-quality-tools - export PATH=${HOME}/maintainer-quality-tools/travis:${PATH} - travis_install_nightly -# use patched lib for now; that's okay to merge because nobody could use this before anyways - - pip install https://github.com/hbrunn/invoice2data/tarball/master-extract_lines#egg=invoice2data + - pip install invoice2data - wget -P /tmp http://public.akretion.com/pdftotext-3.04 - sudo mv /tmp/pdftotext-3.04 /usr/local/bin/pdftotext - sudo chmod 755 /usr/local/bin/pdftotext From ebc3d9f4fe9178904923977af0f34bcfdc75e484 Mon Sep 17 00:00:00 2001 From: Holger Brunn Date: Wed, 10 May 2017 17:01:28 +0200 Subject: [PATCH 3/3] [FIX] use standard pdftotext which parses the invoice correctly --- .travis.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index e5274781f6..2720eae020 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,6 +24,7 @@ addons: # Search your packages here: # https://github.com/travis-ci/apt-package-whitelist/blob/master/ubuntu-precise - wkhtmltopdf # only add if needed and check the before_install section below + - poppler-utils # for invoice2data # set up an X server to run wkhtmltopdf. before_install: @@ -50,9 +51,6 @@ install: - export PATH=${HOME}/maintainer-quality-tools/travis:${PATH} - travis_install_nightly - pip install invoice2data - - wget -P /tmp http://public.akretion.com/pdftotext-3.04 - - sudo mv /tmp/pdftotext-3.04 /usr/local/bin/pdftotext - - sudo chmod 755 /usr/local/bin/pdftotext - pip install PyPDF2 # needed for account_invoice*zugferd - pip install phonenumbers