Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[14.0] Add lines management to create multiline invoices #608

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions account_invoice_import_invoice2data/demo/demo_data.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,26 @@
<field name="static_product_id" ref="internet_access" />
</record>

<record id="gandi" model="res.partner">
<field name="name">Gandi</field>
<field name="is_company" eval="True" />
<field name="supplier_rank">1</field>
<field name="customer_rank">0</field>
<field name="street">63 Boulevard Massena</field>
<field name="zip">75013</field>
<field name="city">Paris</field>
<field name="country_id" ref="base.fr" />
<field name="website">https://www.gandi.net</field>
<field name="vat">FR81423093459</field>
</record>

<record id="gandi_import_config" model="account.invoice.import.config">
<field name="name">Gandi</field>
<field name="partner_id" ref="gandi" />
<field name="invoice_line_method">nline_static_product</field>
<field name="label">Fiber optic access at the main office</field>
<field name="static_product_id" ref="internet_access" />
</record>


</odoo>
Binary file not shown.
82 changes: 81 additions & 1 deletion account_invoice_import_invoice2data/tests/test_invoice_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

import base64
import datetime

from mock import patch

from odoo import fields
from odoo.tests.common import TransactionCase
Expand All @@ -27,7 +30,13 @@ def setUp(self):
)
internet_product.supplier_taxes_id = [(6, 0, [frtax.id])]

def test_import_free_invoice(self):
def test_import_free_1line_invoice(self):
# Check for invoice_line_method is set correctly
free_import_config = self.env.ref(
"account_invoice_import_invoice2data.free_import_config"
)
self.assertEqual(free_import_config.invoice_line_method, "1line_static_product")

filename = "invoice_free_fiber_201507.pdf"
f = file_open("account_invoice_import_invoice2data/tests/pdf/" + filename, "rb")
pdf_file = f.read()
Expand Down Expand Up @@ -100,3 +109,74 @@ def test_import_free_invoice(self):
self.assertEqual(len(invoices), 1)
inv = invoices[0]
self.assertEqual(fields.Date.to_string(inv.invoice_date), "2015-07-02")

@patch(
"odoo.addons.account_invoice_import_invoice2data.wizard.account_invoice_import.extract_data" # noqa: B950
)
def test_import_gandi_nline_invoice(self, patched):
patched.return_value = self.mock_extract_data()

# Check for invoice_line_method is set correctly
gandi_import_config = self.env.ref(
"account_invoice_import_invoice2data.gandi_import_config"
)
self.assertEqual(
gandi_import_config.invoice_line_method, "nline_static_product"
)

filename = "invoice_gandi_websites_2022030201155.pdf"
f = file_open("account_invoice_import_invoice2data/tests/pdf/" + filename, "rb")
pdf_file = f.read()
pdf_file_b64 = base64.b64encode(pdf_file)
wiz = self.env["account.invoice.import"].create(
{
"invoice_file": pdf_file_b64,
"invoice_filename": filename,
}
)
f.close()
wiz.import_invoice()
# Check result of invoice creation
invoices = self.env["account.move"].search(
[
("state", "=", "draft"),
("move_type", "=", "in_invoice"),
("ref", "=", "2022010100001"),
]
)
self.assertEqual(len(invoices), 1)
inv = invoices[0]
self.assertEqual(inv.move_type, "in_invoice")
self.assertEqual(fields.Date.to_string(inv.invoice_date), "2022-01-01")
self.assertEqual(
inv.partner_id, self.env.ref("account_invoice_import_invoice2data.gandi")
)
self.assertEqual(inv.journal_id.type, "purchase")
self.assertEqual(float_compare(inv.amount_total, 109.97, precision_digits=2), 0)
self.assertEqual(
float_compare(inv.amount_untaxed, 91.64, precision_digits=2), 0
)
self.assertEqual(len(inv.invoice_line_ids), 7)

def mock_extract_data(self):
return {
"issuer": "Gandi",
"amount": 109.97,
"amount_untaxed": 91.64,
"date": datetime.datetime(2022, 1, 1, 0, 0),
"invoice_number": "2022010100001",
"vat": "FR81423093459",
"partner_name": "Gandi",
"siren": "423 093 459",
"lines": [
{"name": "site1.com", "taxes": 20.0, "price_unit": 12.0},
{"name": "site2.fr", "taxes": 20.0, "price_unit": 13.91},
{"name": "site3.fr", "taxes": 20.0, "price_unit": 13.91},
{"name": "site4.com", "taxes": 20.0, "price_unit": 12.0},
{"price_unit": 12.0},
{"name": "site6.fr", "price_unit": 13.91},
{"taxes": 20.0, "price_unit": 13.91},
],
"currency": "EUR",
"desc": "Invoice from Gandi",
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,22 @@ def invoice2data_to_parsed_inv(self, invoice2data_res):
"date_start": invoice2data_res.get("date_start"),
"date_end": invoice2data_res.get("date_end"),
}

lines = []
for line in invoice2data_res.get("lines", []):
if "name" not in line:
line["name"] = ""
else:
line["name"] = " ".join(line["name"].split())
if "qty" not in line:
line["qty"] = 1
if "taxes" not in line:
line["taxes"] = []
line["taxes"] = self.invoice2data_parse_taxes(line["taxes"])
lines += [line]
if len(lines) > 0:
parsed_inv["lines"] = lines

for field in ["invoice_number", "description"]:
if isinstance(invoice2data_res.get(field), list):
parsed_inv[field] = " ".join(invoice2data_res[field])
Expand All @@ -97,3 +113,25 @@ def invoice2data_to_parsed_inv(self, invoice2data_res):
if key.startswith("date") and value:
parsed_inv[key] = fields.Date.to_string(value)
return parsed_inv

@api.model
def invoice2data_parse_taxes(self, taxes=None):
def get_tax(tax_amount):
try:
tax = float(tax_amount)
except (ValueError, TypeError):
tax_id = self.env.user.company_id.account_purchase_tax_id
if tax_id:
tax = tax_id.amount
else:
tax = 0.0
return {
"amount_type": "percent",
"amount": tax,
}

if type(taxes) == list and len(taxes) > 0:
taxes_list = [get_tax(tax_amount) for tax_amount in taxes]
else:
taxes_list = [get_tax(taxes)]
return taxes_list