From a98a8f542fe2d1abc2cc6365b2b8d08f3afa2f4a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andrius=20Laukavi=C4=8Dius?= <anlaukavic@gmail.com>
Date: Thu, 12 Jan 2023 08:26:54 +0000
Subject: [PATCH] [FIX] hr_expense: improve computed field performance

If you have large amount of product.template records (e.g. over 40k),
`hr_expense` module can't be installed as you would get MemoryError. It
would consume all memory while computing `can_be_expensed` field.

For that, using `_auto_init` to make it less of a memory hog.

closes odoo/odoo#109729

Signed-off-by: Habib Ayob (ayh) <ayh@odoo.com>
---
 addons/hr_expense/models/product_template.py | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/addons/hr_expense/models/product_template.py b/addons/hr_expense/models/product_template.py
index fdd1c9602acb..c0d771210825 100644
--- a/addons/hr_expense/models/product_template.py
+++ b/addons/hr_expense/models/product_template.py
@@ -2,6 +2,7 @@
 # Part of Odoo. See LICENSE file for full copyright and licensing details.
 
 from odoo import api, fields, models
+from odoo.tools.sql import column_exists, create_column
 
 
 class ProductTemplate(models.Model):
@@ -10,6 +11,18 @@ class ProductTemplate(models.Model):
     can_be_expensed = fields.Boolean(string="Can be Expensed", compute='_compute_can_be_expensed',
         store=True, readonly=False, help="Specify whether the product can be selected in an expense.")
 
+    def _auto_init(self):
+        if not column_exists(self.env.cr, "product_template", "can_be_expensed"):
+            create_column(self.env.cr, "product_template", "can_be_expensed", "boolean")
+            self.env.cr.execute(
+                """
+                UPDATE product_template
+                SET can_be_expensed = false
+                WHERE type NOT IN ('consu', 'service')
+                """
+            )
+        return super()._auto_init()
+
     @api.model
     def default_get(self, fields):
         result = super(ProductTemplate, self).default_get(fields)
-- 
GitLab