Skip to content

Commit

Permalink
[14.0][MIG] account_invoice_merge
Browse files Browse the repository at this point in the history
  • Loading branch information
xavier-bouquiaux committed Jul 26, 2022
1 parent 6ad80c6 commit 989edf2
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 34 deletions.
5 changes: 4 additions & 1 deletion account_invoice_merge/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
"website": "https://github.com/OCA/account-invoicing",
"license": "AGPL-3",
"depends": ["account"],
"data": ["wizard/invoice_merge_view.xml"],
"data": [
"wizard/invoice_merge_view.xml",
"security/ir.model.access.csv",
],
"installable": True,
}
36 changes: 26 additions & 10 deletions account_invoice_merge/models/account_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,22 @@ class AccountMove(models.Model):
_inherit = "account.move"

@api.model
def _get_invoice_key_cols(self):
def _get_invoice_key_cols_out(self):
return [
"partner_id",
"user_id",
"type",
"move_type",
"currency_id",
"journal_id",
"company_id",
"bank_partner_id",
]

@api.model
def _get_invoice_key_cols_in(self):
return [
"partner_id",
"move_type",
"currency_id",
"journal_id",
"company_id",
Expand All @@ -38,7 +49,7 @@ def _get_invoice_line_key_cols(self):
"product_uom_id",
]
for field in ["sale_line_ids"]:
if field in self._fields:
if field in self.env["account.move.line"]._fields:
fields.append(field)
return fields

Expand All @@ -51,7 +62,7 @@ def _get_first_invoice_fields(self, invoice):
"user_id": invoice.user_id.id,
"currency_id": invoice.currency_id.id,
"company_id": invoice.company_id.id,
"type": invoice.type,
"move_type": invoice.move_type,
# "account_id": invoice.account_id.id,
"state": "draft",
"ref": invoice.ref or "",
Expand All @@ -76,7 +87,7 @@ def do_merge(
* Account invoices are in draft
* Account invoices belong to the same partner
* Account invoices are have same company, partner, address, currency,
journal, currency, salesman, account, type
journal, currency, salesman, account, move_type
Lines will only be merged if:
* Invoice lines are exactly the same except for the quantity and unit
Expand Down Expand Up @@ -106,7 +117,12 @@ def make_key(br, fields):
seen_client_refs = {}

for account_invoice in self._get_draft_invoices():
invoice_key = make_key(account_invoice, self._get_invoice_key_cols())
if account_invoice.move_type in ("in_invoice", "in_refund"):
invoice_key = make_key(account_invoice, self._get_invoice_key_cols_in())
else:
invoice_key = make_key(
account_invoice, self._get_invoice_key_cols_out()
)
new_invoice = new_invoices.setdefault(invoice_key, ({}, []))
origins = seen_origins.setdefault(invoice_key, set())
client_refs = seen_client_refs.setdefault(invoice_key, set())
Expand Down Expand Up @@ -203,7 +219,7 @@ def make_key(br, fields):
invoice_line = invoice_line_obj.search(
[
("id", "in", so_line.invoice_lines.ids),
("invoice_id", "=", new_invoice_id),
("move_id", "=", new_invoice_id),
]
)
if invoice_line:
Expand All @@ -212,12 +228,12 @@ def make_key(br, fields):
# recreate link (if any) between original analytic account line
# (invoice time sheet for example) and this new invoice
anal_line_obj = self.env["account.analytic.line"]
if "invoice_id" in anal_line_obj._fields:
if "move_id" in anal_line_obj._fields:
for new_invoice_id in invoices_info:
anal_todos = anal_line_obj.search(
[("invoice_id", "in", invoices_info[new_invoice_id])]
[("move_id", "in", invoices_info[new_invoice_id])]
)
anal_todos.write({"invoice_id": new_invoice_id})
anal_todos.write({"move_id": new_invoice_id})

for new_invoice in allnewinvoices:
new_invoice._compute_amount()
Expand Down
2 changes: 2 additions & 0 deletions account_invoice_merge/security/ir.model.access.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
access_invoice_merge,access_invoice_merge,model_invoice_merge,account.group_account_invoice,1,1,1,1
64 changes: 51 additions & 13 deletions account_invoice_merge/tests/test_account_invoice_merge.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ def setUp(self):
self.invoice_line1 = self._create_inv_line(self.invoice1)
self.invoice_line2 = self._create_inv_line(self.invoice2)
self.invoice_line3 = self._create_inv_line(self.invoice3)
self.user2 = self.env["res.users"].create(
{
"login": "test2",
"name": "test2",
}
)

def _create_partner(self):
partner = self.par_model.create(
Expand Down Expand Up @@ -65,13 +71,17 @@ def _create_inv_line(self, invoice):
)
return invoice.invoice_line_ids - lines

def _create_invoice(self, partner, name):
def _create_invoice(self, partner, name, journal=False, move_type=False):
if not journal:
journal = self.journal
if not move_type:
move_type = "out_invoice"
invoice = self.inv_model.create(
{
"partner_id": partner.id,
"name": name,
"type": "out_invoice",
"journal_id": self.journal.id,
"move_type": move_type,
"journal_id": journal.id,
}
)
return invoice
Expand All @@ -91,12 +101,14 @@ def test_account_invoice_merge_1(self):
wiz_id.fields_view_get()
action = wiz_id.merge_invoices()

self.assertDictContainsSubset(
{
"type": "ir.actions.act_window",
"xml_id": "account.action_move_out_invoice_type",
},
action,
self.assertEqual(
action["type"],
"ir.actions.act_window",
"There was an error and the two invoices were not merged.",
)
self.assertEqual(
action["xml_id"],
"account.action_move_out_invoice_type",
"There was an error and the two invoices were not merged.",
)

Expand Down Expand Up @@ -129,7 +141,7 @@ def test_dirty_check(self):
# Check with two different invoice type
# Create the invoice 4 with a different account
invoice4 = self._create_invoice(self.partner1, "D")
invoice4.write({"type": "out_refund"})
invoice4.write({"move_type": "out_refund"})
self._create_inv_line(invoice4)
invoices = self.invoice1 | invoice4
with self.assertRaises(UserError):
Expand All @@ -152,10 +164,10 @@ def test_dirty_check(self):

# Check with an another company
# Create the invoice 6 and change the company
invoice6 = self._create_invoice(self.partner1, "E")
self._create_inv_line(invoice6)
new_company = self.env["res.company"].create({"name": "Hello World"})
invoice6.company_id = new_company.id
new_journal = self.journal.with_company(new_company).copy()
invoice6 = self._create_invoice(self.partner1, "E", new_journal)
self._create_inv_line(invoice6)
invoices = self.invoice1 | invoice6
with self.assertRaises(UserError):
wiz_id.with_context(
Expand All @@ -170,3 +182,29 @@ def test_dirty_check(self):
active_ids=invoices.ids,
active_model=invoices._name,
).fields_view_get()

def test_account_invoice_merge_3(self):

expenses_journal = self.env["account.journal"].create(
{
"name": "Vendor Bills - Test",
"code": "TEXJ",
"type": "purchase",
"refund_sequence": True,
}
)
inv_a = self._create_invoice(
self.partner1, "A", journal=expenses_journal, move_type="in_invoice"
)
inv_b = self._create_invoice(
self.partner1, "A", journal=expenses_journal, move_type="in_invoice"
)
inv_b.write({"user_id": self.user2.id})
self.assertNotEqual(inv_a.user_id, inv_b.user_id)
invoices = inv_a | inv_b
wiz_id = self.wiz.with_context(
active_ids=invoices.ids,
active_model=invoices._name,
).create({})
wiz_id.fields_view_get()
wiz_id.merge_invoices()
26 changes: 16 additions & 10 deletions account_invoice_merge/wizard/invoice_merge.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,15 @@ class InvoiceMerge(models.TransientModel):
@api.model
def _get_not_mergeable_invoices_message(self, invoices):
"""Overridable function to custom error message"""
key_fields = invoices._get_invoice_key_cols()
move_type_set = set(invoices.mapped("move_type"))
if "in_invoice" in move_type_set or "in_refund" in move_type_set:
key_fields = invoices._get_invoice_key_cols_in()
else:
key_fields = invoices._get_invoice_key_cols_out()
# key_fields = invoices._get_invoice_key_cols_out()
error_msg = {}
if len(invoices) != len(invoices._get_draft_invoices()):
error_msg["state"] = _("Megeable State (ex : %s)") % (
error_msg["state"] = _("Mergeable State (ex : %s)") % (
invoices and fields.first(invoices).state or _("Draft")
)
for field in key_fields:
Expand Down Expand Up @@ -86,11 +91,12 @@ def merge_invoices(self):
keep_references=self.keep_references, date_invoice=self.date_invoice
)
xid = {
"out_invoice": "action_move_out_invoice_type",
"out_refund": "action_move_out_refund_type",
"in_invoice": "action_move_in_invoice_type",
"in_refund": "action_move_in_refund_type",
}[fields.first(invoices).type]
action = aw_obj.for_xml_id("account", xid)
action.update({"domain": [("id", "in", ids + list(allinvoices.keys()))]})
return action
"out_invoice": "account.action_move_out_invoice_type",
"out_refund": "account.action_move_out_refund_type",
"in_invoice": "account.action_move_in_invoice_type",
"in_refund": "account.action_move_in_refund_type",
}[fields.first(invoices).move_type]

res = aw_obj._for_xml_id(xid)
res["domain"] = [("id", "in", ids + list(allinvoices.keys()))]
return res

0 comments on commit 989edf2

Please sign in to comment.