Skip to content

Commit

Permalink
[MIG] project_purchase_link: Migration to 16.0
Browse files Browse the repository at this point in the history
  • Loading branch information
AnizR committed Feb 10, 2023
1 parent b76282e commit 14c0eec
Show file tree
Hide file tree
Showing 4 changed files with 218 additions and 72 deletions.
2 changes: 1 addition & 1 deletion project_purchase_link/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

{
"name": "Project Purchase Link",
"version": "14.0.1.0.0",
"version": "16.0.1.0.0",
"license": "AGPL-3",
"depends": ["project", "purchase", "hr_timesheet"],
"author": "AvanzOSC, " "Odoo Community Association (OCA)",
Expand Down
203 changes: 162 additions & 41 deletions project_purchase_link/models/project_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,84 +23,205 @@ class ProjectProject(models.Model):
)

def _compute_purchase_info(self):
# read group
query = self.env["purchase.order.line"]._search(
[
("order_id.state", "!=", "cancel"),
]
)
# check if analytic_distribution contains id of analytic account
query.add_where(
"purchase_order_line.analytic_distribution ?| array[%s]",
[str(project.analytic_account_id.id) for project in self],
)

query.order = None
query_string, query_param = query.select(
"jsonb_object_keys(purchase_order_line.analytic_distribution) as account_id",
"COUNT(DISTINCT(order_id)) as order_count",
"SUM(price_subtotal) as total",
)
query_string = (
f"{query_string} GROUP BY "
"jsonb_object_keys(purchase_order_line.analytic_distribution)"
)

self._cr.execute(query_string, query_param)
data = {
int(record.get("account_id")): (
record.get("order_count"),
record.get("total"),
)
for record in self._cr.dictfetchall()
}

for project in self:
groups = self.env["purchase.order.line"].read_group(
[
("account_analytic_id", "=", project.analytic_account_id.id),
("order_id.state", "!=", "cancel"),
],
["price_subtotal"],
["order_id"],
project.purchase_count, project.purchase_line_total = data.get(
project.analytic_account_id.id, (0, 0)
)
purchase_line_total = 0
for group in groups:
purchase_line_total += group["price_subtotal"]
project.purchase_count = len(groups)
project.purchase_line_total = purchase_line_total

def _compute_purchase_invoice_info(self):
for project in self:
groups = self.env["account.move.line"].read_group(
[
("analytic_account_id", "=", project.analytic_account_id.id),
("move_id.state", "!=", "cancel"),
],
["price_subtotal"],
["move_id"],
query = self.env["account.move.line"]._search(
[
("move_id.state", "!=", "cancel"),
]
)
# check if analytic_distribution contains id of analytic account
query.add_where(
"account_move_line.analytic_distribution ?| array[%s]",
[str(project.analytic_account_id.id) for project in self],
)

query.order = None
query_string, query_param = query.select(
"jsonb_object_keys(account_move_line.analytic_distribution) as account_id",
"COUNT(DISTINCT(move_id)) as move_count",
"SUM(price_subtotal) as total",
)
query_string = (
f"{query_string} GROUP BY"
" jsonb_object_keys(account_move_line.analytic_distribution)"
)

self._cr.execute(query_string, query_param)
data = {
int(record.get("account_id")): (
record.get("move_count"),
record.get("total"),
)
purchase_invoice_line_total = 0
for group in groups:
purchase_invoice_line_total += group["price_subtotal"]
project.purchase_invoice_count = len(groups)
project.purchase_invoice_line_total = purchase_invoice_line_total
for record in self._cr.dictfetchall()
}
for project in self:
(
project.purchase_invoice_count,
project.purchase_invoice_line_total,
) = data.get(project.analytic_account_id.id, (0, 0))

def _domain_purchase_order(self):
query = self.env["purchase.order.line"]._search(
[
("order_id.state", "!=", "cancel"),
]
)
# check if analytic_distribution contains id of analytic account
query.add_where(
"purchase_order_line.analytic_distribution ?| array[%s]",
[str(project.analytic_account_id.id) for project in self],
)

query.order = None
query_string, query_param = query.select(
"purchase_order_line.order_id as order_id",
)
self._cr.execute(query_string, query_param)
purchase_lines_ids = [
int(record.get("order_id")) for record in self._cr.dictfetchall()
]
domain = [("id", "in", purchase_lines_ids)]
return domain

def button_open_purchase_order(self):
self.ensure_one()
purchase_lines = self.env["purchase.order.line"].search(
[("account_analytic_id", "in", self.mapped("analytic_account_id").ids)]
)
domain = [("id", "in", purchase_lines.mapped("order_id").ids)]
return {
"name": _("Purchase Order"),
"domain": domain,
"domain": self._domain_purchase_order(),
"type": "ir.actions.act_window",
"view_mode": "tree,form",
"res_model": "purchase.order",
}

def _domain_purchase_order_line(self):
query = self.env["purchase.order.line"]._search(
[
("order_id.state", "!=", "cancel"),
]
)
# check if analytic_distribution contains id of analytic account
query.add_where(
"purchase_order_line.analytic_distribution ?| array[%s]",
[str(project.analytic_account_id.id) for project in self],
)

query.order = None
query_string, query_param = query.select(
"purchase_order_line.id as id",
)
self._cr.execute(query_string, query_param)
purchase_lines_ids = [
int(record.get("id")) for record in self._cr.dictfetchall()
]
domain = [("id", "in", purchase_lines_ids)]
return domain

def button_open_purchase_order_line(self):
self.ensure_one()
domain = [("account_analytic_id", "in", self.mapped("analytic_account_id").ids)]
return {
"name": _("Purchase Order Lines"),
"domain": domain,
"domain": self._domain_purchase_order_line(),
"type": "ir.actions.act_window",
"view_mode": "tree,form",
"res_model": "purchase.order.line",
}

def _domain_purchase_invoice(self):
query = self.env["account.move.line"]._search(
[
("move_id.state", "!=", "cancel"),
]
)
# check if analytic_distribution contains id of analytic account
query.add_where(
"account_move_line.analytic_distribution ?| array[%s]",
[str(project.analytic_account_id.id) for project in self],
)
query.order = None
query_string, query_param = query.select(
"DISTINCT(account_move_line.move_id) as move_id",
)
self._cr.execute(query_string, query_param)
purchase_invoice_ids = [
int(record.get("move_id")) for record in self._cr.dictfetchall()
]
domain = [("id", "in", purchase_invoice_ids)]
return domain

def button_open_purchase_invoice(self):
self.ensure_one()
action = self.env.ref("account.action_move_in_invoice_type")
action_dict = action.read()[0] if action else {}
lines = self.env["account.move.line"].search(
[("analytic_account_id", "in", self.mapped("analytic_account_id").ids)]
)
domain = expression.AND(
[
[("id", "in", lines.mapped("move_id").ids)],
safe_eval(action.domain or "[]"),
]
[safe_eval(action.domain or "[]"), self._domain_purchase_invoice()]
)
action_dict.update({"domain": domain})
return action_dict

def _domain_purchase_invoice_line(self):
query = self.env["account.move.line"]._search(
[
("move_id.state", "!=", "cancel"),
]
)
# check if analytic_distribution contains id of analytic account
query.add_where(
"account_move_line.analytic_distribution ?| array[%s]",
[str(project.analytic_account_id.id) for project in self],
)
query.order = None
query_string, query_param = query.select(
"account_move_line.id as id",
)
self._cr.execute(query_string, query_param)
purchase_invoice_lines_ids = [
int(record.get("id")) for record in self._cr.dictfetchall()
]
domain = [("id", "in", purchase_invoice_lines_ids)]
return domain

def button_open_purchase_invoice_line(self):
self.ensure_one()
domain = [("analytic_account_id", "in", self.mapped("analytic_account_id").ids)]
return {
"name": _("Purchase Invoice Lines"),
"domain": domain,
"domain": self._domain_purchase_invoice_line(),
"type": "ir.actions.act_window",
"view_mode": "tree,form",
"res_model": "account.move.line",
Expand Down
1 change: 1 addition & 0 deletions project_purchase_link/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
* Oihane Crucelaegui <oihanecrucelaegi@avanzosc.es>
* Ana Juaristi <anajuaristi@avanzosc.es>
* Alberto Martín Cortada <alberto.martin@guadaltech.es>
* Zina Rasoamanana <zina.rasoamanana@acsone.eu>
84 changes: 54 additions & 30 deletions project_purchase_link/tests/test_project_purchase_link.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,33 @@
# Copyright 2019 Oihane Crucelaegui - AvanzOSC
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html

# from odoo.osv import expression
from odoo.osv import expression
from odoo.tests import common
from odoo.tools.safe_eval import safe_eval

# from odoo.tools.safe_eval import safe_eval


class TestProjectPurchaseUtilities(common.SavepointCase):
class TestProjectPurchaseUtilities(common.TransactionCase):
@classmethod
def setUpClass(cls):
super(TestProjectPurchaseUtilities, cls).setUpClass()
super().setUpClass()
cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
cls.project_model = cls.env["project.project"]
cls.project = cls.project_model.create({"name": "Test Project"})
cls.purchase_model = cls.env["purchase.order"]
cls.purchase = cls.purchase_model.search(
[("state", "in", ("draft", "sent")), ("order_line", "!=", False)], limit=1
cls.partner = cls.env.ref("base.res_partner_2")
cls.product = cls.env["product.product"].create(
{
"name": "Product Product 4",
"standard_price": 500.0,
"list_price": 750.0,
"type": "consu",
"categ_id": cls.env.ref("product.product_category_all").id,
}
)
cls.purchase = cls.purchase_model.create(
{
"partner_id": cls.partner.id,
}
)
cls.invoice_model = cls.env["account.move"]
cls.invoice_line_model = cls.env["account.move.line"]
Expand All @@ -27,15 +39,30 @@ def test_project_purchase(self):
self.assertFalse(self.project.purchase_line_total)
self.assertFalse(self.project.purchase_invoice_count)
self.assertFalse(self.project.purchase_invoice_line_total)
self.purchase.order_line[:1].write(
self.purchase.write(
{
"account_analytic_id": self.project.analytic_account_id.id,
"price_unit": 50,
"product_qty": 4,
"qty_received": 4,
"order_line": [
(
0,
0,
{
"name": "Test line",
"analytic_distribution": {
self.project.analytic_account_id.id: 100
},
"price_unit": 50,
"product_qty": 4,
"qty_received": 4,
"product_uom": self.product.uom_id.id,
"product_id": self.product.id,
},
)
]
}
)
self.project.invalidate_cache()

self.env.invalidate_all()

self.assertEqual(self.project.purchase_count, 1)
self.assertEqual(self.project.purchase_line_total, 200)
self.assertFalse(self.project.purchase_invoice_count)
Expand All @@ -54,33 +81,30 @@ def test_project_purchase(self):
"move_id": invoice.id,
"name": line.name,
"account_id": account_id,
"analytic_account_id": line.account_analytic_id.id,
"analytic_distribution": line.analytic_distribution,
}
self.invoice_line_model.create(vals)
self.project.invalidate_cache()
self.env.invalidate_all()
self.assertEqual(self.project.purchase_invoice_count, 1)
purchase_domain = [
(
"account_analytic_id",
"in",
self.project.mapped("analytic_account_id").ids,
)
]

purchase_domain = self.project._domain_purchase_order_line()

lines = self.env["purchase.order.line"].search(purchase_domain)
order_domain = [("id", "in", lines.mapped("order_id").ids)]
purchase_dict = self.project.button_open_purchase_order()
self.assertEqual(purchase_dict.get("domain"), order_domain)
purchase_line_dict = self.project.button_open_purchase_order_line()
self.assertEqual(purchase_line_dict.get("domain"), purchase_domain)
invoice_domain = [("id", "in", [invoice.id])] # only one test invoice (line)

action = self.env.ref("account.action_move_in_invoice_type")
invoice_domain = expression.AND(
[safe_eval(action.domain or "[]"), self.project._domain_purchase_invoice()]
) # only one test invoice (line)

invoice_dict = self.project.button_open_purchase_invoice()
self.assertEqual(invoice_dict.get("domain"), invoice_domain)
invoice_line_domain = [
(
"analytic_account_id",
"in",
[self.project.analytic_account_id.id], # one test invoice (line)
)
]

invoice_line_domain = self.project._domain_purchase_invoice_line()

invoice_line_dict = self.project.button_open_purchase_invoice_line()
self.assertEqual(invoice_line_dict.get("domain"), invoice_line_domain)

0 comments on commit 14c0eec

Please sign in to comment.