Skip to content

Commit

Permalink
[ADD] migration of account_invoice_import_invoice2data and dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
hbrunn committed May 10, 2017
1 parent 3b0cca8 commit 39ba10d
Show file tree
Hide file tree
Showing 22 changed files with 139 additions and 103 deletions.
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
EDI Modules

[//]: # (addons)

Unported addons
---------------
addon | version | summary
Expand Down
2 changes: 1 addition & 1 deletion account_invoice_import/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 2 additions & 5 deletions account_invoice_import/__init__.py
Original file line number Diff line number Diff line change
@@ -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
10 changes: 5 additions & 5 deletions account_invoice_import/__openerp__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -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,
}
4 changes: 4 additions & 0 deletions account_invoice_import/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
from . import partner
from . import account_invoice_import_config
from . import account_invoice
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -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')])
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
</record>

<menuitem id="account_invoice_import_config_menu"
parent="account.menu_configuration_misc"
parent="account.menu_finance_configuration"
action="account_invoice_import_config_action" sequence="100"/>

</data>
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -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
Expand All @@ -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')
Expand All @@ -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'),
Expand All @@ -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(_(
Expand All @@ -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 = {}
Expand All @@ -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'):
Expand All @@ -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')

Expand Down Expand Up @@ -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 "
Expand Down Expand Up @@ -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 (
Expand All @@ -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 '
Expand Down Expand Up @@ -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'),
Expand All @@ -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']
Expand Down
2 changes: 1 addition & 1 deletion account_invoice_import_invoice2data/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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 <https://github.com/OCA/l10n-france/>`_, cf `this PR <https://github.com/OCA/l10n-france/pull/55>`_.
French users should also install the module *l10n_fr_invoice_import* available in the `French localization <https://github.com/OCA/l10n-france/>`_.

Configuration
=============
Expand Down
4 changes: 2 additions & 2 deletions account_invoice_import_invoice2data/__openerp__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -15,5 +15,5 @@
'data': [],
'demo': ['demo/demo_data.xml'],
'images': ['images/sshot-wizard1.png'],
'installable': False,
'installable': True,
}
Loading

0 comments on commit 39ba10d

Please sign in to comment.