Skip to content

Commit fd9ad5c

Browse files
alexis-viagurneyalex
authored andcommitted
[MIG] account_invoice_import to v16
First draft migration, to have a first working version. Many more changes are planned.
1 parent 51558eb commit fd9ad5c

13 files changed

+224
-163
lines changed

account_invoice_import/__manifest__.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
{
66
"name": "Account Invoice Import",
7-
"version": "15.0.1.0.0",
7+
"version": "16.0.1.0.0",
88
"category": "Accounting & Finance",
99
"license": "AGPL-3",
1010
"summary": "Import supplier invoices/refunds as PDF or XML files",
@@ -15,7 +15,6 @@
1515
"account",
1616
"base_iban",
1717
"base_business_document_import",
18-
"onchange_helper",
1918
],
2019
"data": [
2120
"security/ir.model.access.csv",

account_invoice_import/models/account_invoice_import_config.py

+19-4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
class AccountInvoiceImportConfig(models.Model):
1010
_name = "account.invoice.import.config"
11+
_inherit = "analytic.mixin"
1112
_description = "Configuration for the import of Supplier Invoices"
1213
_order = "sequence"
1314
_check_company_auto = True
@@ -47,9 +48,6 @@ class AccountInvoiceImportConfig(models.Model):
4748
domain="[('deprecated', '=', False), ('company_id', '=', company_id)]",
4849
check_company=True,
4950
)
50-
account_analytic_id = fields.Many2one(
51-
"account.analytic.account", string="Analytic Account", check_company=True
52-
)
5351
journal_id = fields.Many2one(
5452
"account.journal",
5553
string="Force Purchase Journal",
@@ -72,6 +70,23 @@ class AccountInvoiceImportConfig(models.Model):
7270
domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]",
7371
)
7472

73+
@api.depends("static_product_id", "account_id", "partner_id")
74+
def _compute_analytic_distribution(self):
75+
for config in self:
76+
distribution = self.env[
77+
"account.analytic.distribution.model"
78+
]._get_distribution(
79+
{
80+
"partner_id": config.partner_id.id,
81+
"partner_category_id": config.partner_id.category_id.ids,
82+
"product_id": config.static_product_id.id,
83+
"product_categ_id": config.static_product_id.categ_id.id,
84+
"account_prefix": config.account_id.code,
85+
"company_id": config.company_id.id,
86+
}
87+
)
88+
config.analytic_distribution = distribution or config.analytic_distribution
89+
7590
@api.constrains("invoice_line_method", "account_id", "static_product_id")
7691
def _check_import_config(self):
7792
for config in self:
@@ -110,7 +125,7 @@ def convert_to_import_config(self):
110125
self.ensure_one()
111126
vals = {
112127
"invoice_line_method": self.invoice_line_method,
113-
"account_analytic": self.account_analytic_id or False,
128+
"analytic_distribution": self.analytic_distribution or False,
114129
"journal": self.journal_id or False,
115130
}
116131
if self.invoice_line_method == "1line_no_product":

account_invoice_import/models/res_company.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,14 @@ class ResCompany(models.Model):
1111
adjustment_credit_account_id = fields.Many2one(
1212
"account.account",
1313
check_company=True,
14-
domain="[('deprecated', '=', False), ('company_id', '=', company_id)]",
14+
domain="[('deprecated', '=', False), ('company_id', '=', company_id), "
15+
"('account_type', '=', 'income')]",
1516
)
1617
adjustment_debit_account_id = fields.Many2one(
1718
"account.account",
1819
check_company=True,
19-
domain="[('deprecated', '=', False), ('company_id', '=', company_id)]",
20+
domain="[('deprecated', '=', False), ('company_id', '=', company_id), "
21+
"('account_type', '=', 'expense')]",
2022
)
2123
invoice_import_email = fields.Char(
2224
"Mail Gateway: Destination E-mail",

account_invoice_import/models/res_partner.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def _compute_invoice_import_count(self):
3434
def show_account_invoice_import_config(self):
3535
self.ensure_one()
3636
xmlid = "account_invoice_import.account_invoice_import_config_action"
37-
action = self.env["ir.actions.act_window"]._for_xml_id(xmlid)
37+
action = self.env["ir.actions.actions"]._for_xml_id(xmlid)
3838
action["context"] = {
3939
"default_name": self.name,
4040
"default_partner_id": self.id,

account_invoice_import/tests/test_invoice_import.py

+81-12
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# @author: Simone Orsi <simahawk@gmail.com>
55
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
66

7-
import mock
7+
from unittest import mock
88

99
from odoo import fields
1010
from odoo.tests.common import TransactionCase
@@ -21,18 +21,36 @@ def setUpClass(cls):
2121
{
2222
"code": "612AII",
2323
"name": "expense account invoice import",
24-
"user_type_id": cls.env.ref("account.data_account_type_expenses").id,
24+
"account_type": "expense",
2525
"company_id": cls.company.id,
2626
}
2727
)
2828
cls.income_account = cls.env["account.account"].create(
2929
{
3030
"code": "707AII",
3131
"name": "revenue account invoice import",
32-
"user_type_id": cls.env.ref("account.data_account_type_revenue").id,
32+
"account_type": "income",
3333
"company_id": cls.company.id,
3434
}
3535
)
36+
cls.adj_debit_account = cls.env["account.account"].create(
37+
{
38+
"code": "658AII",
39+
"name": "Adjustment debit account",
40+
"account_type": "expense",
41+
"company_id": cls.company.id,
42+
}
43+
)
44+
cls.adj_credit_account = cls.env["account.account"].create(
45+
{
46+
"code": "758AII",
47+
"name": "Adjustment credit account",
48+
"account_type": "income",
49+
"company_id": cls.company.id,
50+
}
51+
)
52+
cls.company.adjustment_debit_account_id = cls.adj_debit_account.id
53+
cls.company.adjustment_credit_account_id = cls.adj_credit_account.id
3654
purchase_tax_vals = {
3755
"name": "Test 1% VAT",
3856
"description": "ZZ-VAT-buy-1.0",
@@ -50,15 +68,19 @@ def setUpClass(cls):
5068
sale_tax_vals = purchase_tax_vals.copy()
5169
sale_tax_vals.update({"description": "ZZ-VAT-sale-1.0", "type_tax_use": "sale"})
5270
cls.sale_tax = cls.env["account.tax"].create(sale_tax_vals)
53-
cls.product = cls.env["product.product"].create(
54-
{
55-
"name": "Expense product",
56-
"default_code": "AII-TEST-PRODUCT",
57-
"taxes_id": [(6, 0, [cls.sale_tax.id])],
58-
"supplier_taxes_id": [(6, 0, [cls.purchase_tax.id])],
59-
"property_account_income_id": cls.income_account.id,
60-
"property_account_expense_id": cls.expense_account.id,
61-
}
71+
cls.product = (
72+
cls.env["product.product"]
73+
.with_company(cls.company.id)
74+
.create(
75+
{
76+
"name": "Expense product",
77+
"default_code": "AII-TEST-PRODUCT",
78+
"taxes_id": [(6, 0, [cls.sale_tax.id])],
79+
"supplier_taxes_id": [(6, 0, [cls.purchase_tax.id])],
80+
"property_account_income_id": cls.income_account.id,
81+
"property_account_expense_id": cls.expense_account.id,
82+
}
83+
)
6284
)
6385
cls.all_import_config = [
6486
{
@@ -185,6 +207,53 @@ def test_import_in_invoice(self):
185207
)
186208
self.assertEqual(inv.journal_id.id, self.pur_journal2.id)
187209

210+
def test_import_in_invoice_with_global_adjustment(self):
211+
parsed_inv = {
212+
"type": "in_invoice",
213+
"journal": {"code": "XXXP2"},
214+
"invoice_number": "TESTAIIGLOBAL",
215+
"amount_untaxed": 100.05,
216+
"amount_total": 101.0,
217+
"date": "2023-04-08",
218+
"date_due": "2023-05-07",
219+
"partner": {"name": "Wood Corner"},
220+
"lines": [
221+
{
222+
"product": {"code": "AII-TEST-PRODUCT"},
223+
"name": "Super test product",
224+
"qty": 2,
225+
"price_unit": 50,
226+
"taxes": [
227+
{
228+
"amount_type": "percent",
229+
"amount": 1.0,
230+
"unece_type_code": "VAT",
231+
"unece_categ_code": "S",
232+
}
233+
],
234+
}
235+
],
236+
}
237+
import_config = {"invoice_line_method": "nline_auto_product"}
238+
inv = (
239+
self.env["account.invoice.import"]
240+
.with_company(self.company.id)
241+
.create_invoice(parsed_inv, import_config)
242+
)
243+
self.assertEqual(inv.move_type, parsed_inv["type"])
244+
self.assertFalse(
245+
inv.currency_id.compare_amounts(
246+
inv.amount_untaxed, parsed_inv["amount_untaxed"]
247+
)
248+
)
249+
self.assertFalse(
250+
inv.currency_id.compare_amounts(
251+
inv.amount_total, parsed_inv["amount_total"]
252+
)
253+
)
254+
# Check that we have an adjustment line
255+
self.assertEqual(len(inv.invoice_line_ids), 2)
256+
188257
def test_import_out_invoice(self):
189258
parsed_inv = {
190259
"type": "out_invoice",

account_invoice_import/views/account_invoice_import_config.xml

+6-8
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
<field name="name" />
2323
<field name="partner_id" />
2424
<field name="company_id" groups="base.group_multi_company" />
25+
<field name="company_id" invisible="1" />
2526
<field name="active" invisible="1" />
2627
</group>
2728
<group string="Accounting Parameters" name="accounting">
@@ -40,8 +41,10 @@
4041
attrs="{'invisible': [('invoice_line_method', 'not in', ('1line_static_product', 'nline_static_product'))], 'required': [('invoice_line_method', 'in', ('1line_static_product', 'nline_static_product'))]}"
4142
/>
4243
<field
43-
name="account_analytic_id"
44+
name="analytic_distribution"
45+
widget="analytic_distribution"
4446
groups="analytic.group_analytic_accounting"
47+
options="{'product_field': 'static_product_id', 'account_field': 'account_id', 'business_domain': 'bill', 'force_applicability': 'optional'}"
4548
/>
4649
<field
4750
name="label"
@@ -70,7 +73,8 @@
7073
/>
7174
<field name="invoice_line_method" />
7275
<field
73-
name="account_analytic_id"
76+
name="analytic_distribution"
77+
widget="analytic_distribution"
7478
groups="analytic.group_analytic_accounting"
7579
optional="show"
7680
/>
@@ -102,12 +106,6 @@
102106
string="Method for Invoice Line"
103107
context="{'group_by': 'invoice_line_method'}"
104108
/>
105-
<filter
106-
name="account_analytic_groupby"
107-
string="Analytic Account"
108-
context="{'group_by': 'account_analytic_id'}"
109-
groups="analytic.group_analytic_accounting"
110-
/>
111109
<filter
112110
name="journal_groupby"
113111
string="Force Purchase Journal"

account_invoice_import/views/account_journal_dashboard.xml

+17-7
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,25 @@
99
<field name="model">account.journal</field>
1010
<field name="inherit_id" ref="account.account_journal_dashboard_kanban_view" />
1111
<field name="arch" type="xml">
12-
<button
13-
class="btn btn-primary o_button_upload_bill oe_kanban_action_button"
14-
journal_type="purchase"
12+
<xpath
13+
expr="//t[@id='account.JournalBodySalePurchase']//widget[@name='account_file_uploader']"
1514
position="attributes"
1615
>
17-
<attribute name="type">action</attribute>
18-
<attribute name="name">%(account_invoice_import_action)d</attribute>
19-
<attribute name="class">btn btn-primary</attribute>
20-
</button>
16+
<attribute name="invisible">1</attribute>
17+
</xpath>
18+
<xpath
19+
expr="//t[@id='account.JournalBodySalePurchase']//widget[@name='account_file_uploader']"
20+
position="after"
21+
>
22+
<button
23+
string="Upload"
24+
type="action"
25+
name="%(account_invoice_import_action)d"
26+
groups="account.group_account_invoice"
27+
journal_type="purchase"
28+
class="btn btn-primary d-block"
29+
/>
30+
</xpath>
2131
</field>
2232
</record>
2333
</odoo>

account_invoice_import/views/res_config_settings.xml

+28-10
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,33 @@
1212
<xpath expr="//div[@id='invoicing_settings']" position="after">
1313
<h2
1414
attrs="{'invisible': [('has_accounting_entries','=',False)]}"
15-
>Electronic Invoices Import</h2>
15+
>Vendor Bill Import</h2>
1616
<div class="row mt16 o_settings_container" id="account_invoice_import">
17-
<div class="col-xs-12 col-md-12 o_setting_box">
18-
<div class="o_setting_left_pane" />
19-
<div class="o_setting_right_pane">
17+
<div
18+
class="col-xs-12 col-md-12 o_setting_box"
19+
id="account_invoice_import_misc"
20+
>
21+
<div class="o_setting_left_pane" />
22+
<div class="o_setting_right_pane">
2023
<div class="row">
2124
<label
2225
class="col-md-5"
2326
for="adjustment_debit_account_id"
2427
/>
25-
<field name="adjustment_debit_account_id" />
28+
<field
29+
name="adjustment_debit_account_id"
30+
options="{'no_create': True}"
31+
/>
2632
</div>
2733
<div class="row">
2834
<label
2935
class="col-md-5"
3036
for="adjustment_credit_account_id"
3137
/>
32-
<field name="adjustment_credit_account_id" />
38+
<field
39+
name="adjustment_credit_account_id"
40+
options="{'no_create': True}"
41+
/>
3342
</div>
3443
<div class="row">
3544
<label
@@ -38,15 +47,24 @@
3847
/>
3948
<field name="invoice_import_email" />
4049
</div>
41-
<div class="row">
42-
<label
50+
</div>
51+
</div>
52+
<div
53+
class="col-xs-12 col-md-12 o_setting_box"
54+
id="account_invoice_import_bank_account"
55+
>
56+
<div class="o_setting_left_pane">
57+
<field name="invoice_import_create_bank_account" />
58+
</div>
59+
<div class="o_setting_right_pane">
60+
<div class="row">
61+
<label
4362
class="col-md-5"
4463
for="invoice_import_create_bank_account"
4564
/>
46-
<field name="invoice_import_create_bank_account" />
65+
</div>
4766
</div>
4867
</div>
49-
</div>
5068
</div>
5169
</xpath>
5270
</field>

account_invoice_import/views/res_partner.xml

+5-5
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@
88
<record id="view_partner_property_form" model="ir.ui.view">
99
<field name="model">res.partner</field>
1010
<field name="inherit_id" ref="account.view_partner_property_form" />
11-
<field
12-
name="groups_id"
13-
eval="[(4, ref('account.group_account_invoice')), (4, ref('account.group_account_readonly'))]"
14-
/>
1511
<field name="arch" type="xml">
1612
<button
1713
name="%(base.action_res_partner_bank_account_form)d"
1814
position="after"
1915
>
20-
<div name="invoice_import_configs" colspan="2">
16+
<div
17+
name="invoice_import_configs"
18+
colspan="2"
19+
groups="account.group_account_readonly,account.group_account_invoice"
20+
>
2121
<button
2222
type="object"
2323
class="btn-link"

0 commit comments

Comments
 (0)