diff options
| author | Rafi Zadanly <zadanlyr@gmail.com> | 2023-08-26 12:13:28 +0700 |
|---|---|---|
| committer | Rafi Zadanly <zadanlyr@gmail.com> | 2023-08-26 12:13:28 +0700 |
| commit | 315b832420eb8314e809b1c0f549304d423b45f3 (patch) | |
| tree | bf31b1f24ffa511308bec829b7e57ff09eabd294 | |
| parent | 52f4b12c0b211f958c2704346d7da24d1d4767c6 (diff) | |
Create apache solr queue and implement to product.template and website.categories.homepage
| -rwxr-xr-x | indoteknik_custom/__manifest__.py | 1 | ||||
| -rw-r--r-- | indoteknik_custom/models/solr/__init__.py | 1 | ||||
| -rw-r--r-- | indoteknik_custom/models/solr/apache_solr_queue.py | 69 | ||||
| -rw-r--r-- | indoteknik_custom/models/solr/product_product.py | 26 | ||||
| -rw-r--r-- | indoteknik_custom/models/solr/product_template.py | 48 | ||||
| -rw-r--r-- | indoteknik_custom/models/solr/website_categories_homepage.py | 52 | ||||
| -rwxr-xr-x | indoteknik_custom/security/ir.model.access.csv | 1 | ||||
| -rw-r--r-- | indoteknik_custom/views/apache_solr_queue.xml | 74 | ||||
| -rw-r--r-- | indoteknik_custom/views/product_product.xml | 2 | ||||
| -rwxr-xr-x | indoteknik_custom/views/product_template.xml | 2 | ||||
| -rw-r--r-- | indoteknik_custom/views/website_categories_homepage.xml | 2 |
11 files changed, 226 insertions, 52 deletions
diff --git a/indoteknik_custom/__manifest__.py b/indoteknik_custom/__manifest__.py index 7c38382c..2e2b6761 100755 --- a/indoteknik_custom/__manifest__.py +++ b/indoteknik_custom/__manifest__.py @@ -91,6 +91,7 @@ 'views/product_attribute_value.xml', 'views/mail_template_po.xml', 'views/price_group.xml', + 'views/apache_solr_queue.xml', 'report/report.xml', 'report/report_banner_banner.xml', 'report/report_banner_banner2.xml', diff --git a/indoteknik_custom/models/solr/__init__.py b/indoteknik_custom/models/solr/__init__.py index 450e1dae..45ef4299 100644 --- a/indoteknik_custom/models/solr/__init__.py +++ b/indoteknik_custom/models/solr/__init__.py @@ -1,4 +1,5 @@ from . import apache_solr +from . import apache_solr_queue from . import product_pricelist_item from . import product_product from . import product_template diff --git a/indoteknik_custom/models/solr/apache_solr_queue.py b/indoteknik_custom/models/solr/apache_solr_queue.py new file mode 100644 index 00000000..eb5a99a8 --- /dev/null +++ b/indoteknik_custom/models/solr/apache_solr_queue.py @@ -0,0 +1,69 @@ +from odoo import models, fields +from datetime import datetime +import logging + + +_logger = logging.getLogger(__name__) + +class ApacheSolrQueue(models.Model): + _name = 'apache.solr.queue' + + display_name = fields.Char('Display Name', compute="_compute_display_name") + res_model = fields.Char('Resource Model') + res_id = fields.Integer('Resource ID') + function_name = fields.Char('Function Name') + execute_status = fields.Selection([ + ('success', 'Success'), + ('failed', 'Failed'), + ('not_found', 'Record not found') + ], 'Execute Status') + execute_date = fields.Datetime('Execute Date') + + def _compute_display_name(self): + for rec in self: + try: + res_model = rec.res_model + res_id = int(rec.res_id) + model_instance = self.env[res_model].browse(res_id) + rec.display_name = model_instance.display_name or '' + except: + rec.display_name = '' + + def process_queue_item(self, limit=100): + records = self.search([('execute_status', '=', False)], order='create_date asc', limit=limit) + for rec in records: + rec.execute_queue() + + def execute_queue(self): + for rec in self: + try: + res_model = rec.res_model + res_id = int(rec.res_id) + function_name = rec.function_name + _logger.info(f'Execute Queue: {res_model}.{function_name}() -> {res_id}') + + domain = [('id', '=', res_id)] + if res_model in ['product.template']: + domain.append(('active', 'in', [True, False])) + + model_instance = self.env[res_model].search(domain) + if model_instance: + getattr(model_instance, function_name)() + rec.execute_status = 'success' + else: + rec.execute_status = 'not_found' + except: + rec.execute_status = 'failed' + rec.execute_date = datetime.utcnow() + self.env.cr.commit() + + def create_unique(self, payload={}): + count = self.search_count([ + ('res_model', '=', payload['res_model']), + ('res_id', '=', payload['res_id']), + ('function_name', '=', payload['function_name']), + ('execute_status', '=', False) + ]) + if count == 0: + self.create(payload) + diff --git a/indoteknik_custom/models/solr/product_product.py b/indoteknik_custom/models/solr/product_product.py index 5090b8d5..f3107afa 100644 --- a/indoteknik_custom/models/solr/product_product.py +++ b/indoteknik_custom/models/solr/product_product.py @@ -14,6 +14,12 @@ class ProductProduct(models.Model): def solr(self): return self.env['apache.solr'].connect('variants') + + def action_sync_to_solr(self): + product_ids = self.env.context.get('active_ids', []) + products = self.search([('id', 'in', product_ids)]) + for product in products: + product.product_tmpl_id._create_solr_queue('_sync_product_template_to_solr') def _sync_variants_to_solr(self): solr_model = self.env['apache.solr'] @@ -59,8 +65,6 @@ class ProductProduct(models.Model): if not document.get('has_price_info_b'): variant._sync_price_to_solr() - self.solr().commit() - def _sync_price_to_solr(self): solr_model = self.env['apache.solr'] @@ -105,17 +109,7 @@ class ProductProduct(models.Model): if not document.get('has_product_info_b'): variant._sync_variants_to_solr() - - self.solr().commit() - - def sync_to_solr(self): - product_ids = self.env.context.get('active_ids', []) - products = self.search([('id', 'in', product_ids)]) - - updated_template_ids = [] - for product in products: - template = product.product_tmpl_id - if template.id in updated_template_ids: - continue - template._sync_product_template_to_solr() - updated_template_ids.append(template.id)
\ No newline at end of file + + def _sync_delete_solr(self): + for rec in self: + self.solr().delete(rec.id)
\ No newline at end of file diff --git a/indoteknik_custom/models/solr/product_template.py b/indoteknik_custom/models/solr/product_template.py index 6089adda..ba670a81 100644 --- a/indoteknik_custom/models/solr/product_template.py +++ b/indoteknik_custom/models/solr/product_template.py @@ -15,16 +15,31 @@ class ProductTemplate(models.Model): def solr(self): return self.env['apache.solr'].connect('product') + def _create_solr_queue(self, function_name): + for rec in self: + self.env['apache.solr.queue'].create_unique({ + 'res_model': self._name, + 'res_id': rec.id, + 'function_name': function_name + }) + @api.constrains('active') + def _create_solr_queue_sync_active(self): + self._create_solr_queue('_sync_active_template_solr') + + @api.constrains('name', 'default_code', 'weight', 'x_manufacture', 'public_categ_ids', 'search_rank', 'search_rank_weekly', 'image_1920') + def _create_solr_queue_sync_product_template(self): + self._create_solr_queue('_sync_product_template_to_solr') + + def action_sync_to_solr(self): + template_ids = self.env.context.get('active_ids', []) + templates = self.search([('id', 'in', template_ids)]) + templates._create_solr_queue('_sync_product_template_to_solr') + def _sync_active_template_solr(self): for template in self: if not template.active or template.type != 'product': - self.solr().delete(template.id) - - variant_ids = [x.id for x in template.product_variant_ids] - template.product_variant_ids.solr().delete(variant_ids) - - self.solr().commit() + template._sync_delete_solr() else: template._sync_product_template_to_solr() template._sync_price_to_solr() @@ -32,16 +47,6 @@ class ProductTemplate(models.Model): products = self.env['product.product'].search([('product_tmpl_id', '=', template.id), ('active', 'in', [True, False])]) products._sync_variants_to_solr() - @api.constrains( - 'name', - 'default_code', - 'weight', - 'x_manufacture', - 'public_categ_ids', - 'search_rank', - 'search_rank_weekly', - 'image_1920' - ) def _sync_product_template_to_solr(self): solr_model = self.env['apache.solr'] @@ -152,7 +157,10 @@ class ProductTemplate(models.Model): self.solr().commit() - def sync_to_solr(self): - template_ids = self.env.context.get('active_ids', []) - templates = self.search([('id', 'in', template_ids)]) - templates._sync_product_template_to_solr()
\ No newline at end of file + def _sync_delete_solr(self): + for rec in self: + self.solr().delete(rec.id) + for variant in rec.product_variant_ids: + variant._sync_delete_solr() + self.solr().optimize() + self.solr().commit()
\ No newline at end of file diff --git a/indoteknik_custom/models/solr/website_categories_homepage.py b/indoteknik_custom/models/solr/website_categories_homepage.py index 59e7f32f..21812acf 100644 --- a/indoteknik_custom/models/solr/website_categories_homepage.py +++ b/indoteknik_custom/models/solr/website_categories_homepage.py @@ -14,20 +14,51 @@ class WebsiteCategoriesHomepage(models.Model): def update_last_update_solr(self): self.last_update_solr = datetime.utcnow() + def _create_solr_queue(self, function_name): + for rec in self: + self.env['apache.solr.queue'].create_unique({ + 'res_model': self._name, + 'res_id': rec.id, + 'function_name': function_name + }) + @api.constrains('status') + def _create_solr_queue_sync_status(self): + self._create_solr_queue('_sync_status_category_homepage_solr') + + @api.constrains('category_id', 'image', 'url', 'sequence', 'product_ids') + def _create_solr_queue_sync_category_homepage(self): + self._create_solr_queue('_sync_category_homepage_to_solr') + + def action_sync_to_solr(self): + category_ids = self.env.context.get('active_ids', []) + categories = self.search([('id', 'in', category_ids)]) + categories._create_solr_queue('_sync_category_homepage_to_solr') + + def unlink(self): + res = super(WebsiteCategoriesHomepage, self).unlink() + for rec in self: + self.env['apache.solr.queue'].create_unique({ + 'res_model': self._name, + 'res_id': rec.id, + 'function_name': '_sync_delete_solr' + }) + return res + def _sync_status_category_homepage_solr(self): for rec in self: if rec.status == 'tayang': rec._sync_category_homepage_to_solr() else: - self.solr().delete(rec.id) - self.solr().commit() + rec._sync_delete_solr() - @api.constrains('category_id', 'image', 'url', 'sequence', 'product_ids') def _sync_category_homepage_to_solr(self): solr_model = self.env['apache.solr'] for category in self: + if category.status == 'tidak_tayang': + continue + document = solr_model.get_single_doc('product_category_homepage', category.id) products = [self.env['product.template'].api_single_response(x) for x in category.product_ids] @@ -45,13 +76,8 @@ class WebsiteCategoriesHomepage(models.Model): self.solr().commit() - def sync_to_solr(self): - category_ids = self.env.context.get('active_ids', []) - categories = self.search([('id', 'in', category_ids)]) - categories._sync_category_homepage_to_solr() - - def unlink(self): - res = super(WebsiteCategoriesHomepage, self).unlink() - self.solr().delete([x.id for x in self]) - self.solr().commit() - return res
\ No newline at end of file + def _sync_delete_solr(self): + for rec in self: + self.solr().delete(rec.id) + self.solr().optimize() + self.solr().commit()
\ No newline at end of file diff --git a/indoteknik_custom/security/ir.model.access.csv b/indoteknik_custom/security/ir.model.access.csv index 6f9ba9e4..c9732614 100755 --- a/indoteknik_custom/security/ir.model.access.csv +++ b/indoteknik_custom/security/ir.model.access.csv @@ -67,3 +67,4 @@ access_account_move_multi_update,access.account.move.multi_update,model_account_ access_airway_bill,access.airway.bill,model_airway_bill,,1,1,1,1 access_airway_bill_manifest,access.airway.bill.manifest,model_airway_bill_manifest,,1,1,1,1 access_price_group,access.price.group,model_price_group,,1,1,1,1 +access_apache_solr_queue,access.apache.solr.queue,model_apache_solr_queue,,1,1,1,1 diff --git a/indoteknik_custom/views/apache_solr_queue.xml b/indoteknik_custom/views/apache_solr_queue.xml new file mode 100644 index 00000000..092871d6 --- /dev/null +++ b/indoteknik_custom/views/apache_solr_queue.xml @@ -0,0 +1,74 @@ +<odoo> + <record id="view_apache_solr_queue" model="ir.ui.view"> + <field name="name">apache.solr.queue.tree</field> + <field name="model">apache.solr.queue</field> + <field name="arch" type="xml"> + <tree editable="top" default_order="execute_date desc"> + <field name="display_name" readonly="1" /> + <field name="res_model" required="1" /> + <field name="res_id" required="1" /> + <field name="function_name" required="1" /> + <field name="execute_status" widget="badge" readonly="1" + decoration-danger="execute_status == 'failed'" + decoration-success="execute_status == 'success'" + decoration-primary="execute_status == 'not_found'" + /> + <field name="execute_date" readonly="1" /> + <field name="create_date" readonly="1" /> + </tree> + </field> + </record> + + <record id="apache_solr_queue_view_search" model="ir.ui.view"> + <field name="name">apache.solr.queue.search</field> + <field name="model">apache.solr.queue</field> + <field name="mode">primary</field> + <field name="arch" type="xml"> + <search string="Search Queue"> + <field name="res_model"/> + <field name="res_id"/> + <field name="function_name"/> + <filter string="Active Queue" name="active_queue" domain="[('execute_status', '=', False)]"/> + </search> + </field> + </record> + + <record id="action_apache_solr_queue" model="ir.actions.act_window"> + <field name="name">Solr Queue</field> + <field name="res_model">apache.solr.queue</field> + <field name="search_view_id" ref="apache_solr_queue_view_search"/> + <field name="context">{'search_default_active_queue': 1}</field> + <field name="view_mode">tree</field> + </record> + + <menuitem + id="menu_apache_solr_queue" + name="Solr Queue" + parent="base.menu_users" + sequence="32" + action="action_apache_solr_queue" + /> + + <record id="ir_actions_server_apache_solr_queue_execute" model="ir.actions.server"> + <field name="name">Execute</field> + <field name="model_id" ref="indoteknik_custom.model_apache_solr_queue"/> + <field name="binding_model_id" ref="indoteknik_custom.model_apache_solr_queue"/> + <field name="state">code</field> + <field name="code">records.execute_queue()</field> + </record> + + <data noupdate="1"> + <record id="cron_apache_solr_queue_process" model="ir.cron"> + <field name="name">Solr Queue: Process</field> + <field name="interval_number">6</field> + <field name="interval_type">minutes</field> + <field name="numbercall">-1</field> + <field name="doall" eval="False"/> + <field name="model_id" ref="model_apache_solr_queue"/> + <field name="code">model.process_queue_item(limit=100)</field> + <field name="state">code</field> + <field name="priority">55</field> + <field name="active">True</field> + </record> + </data> +</odoo>
\ No newline at end of file diff --git a/indoteknik_custom/views/product_product.xml b/indoteknik_custom/views/product_product.xml index 3a10b4e0..6d547712 100644 --- a/indoteknik_custom/views/product_product.xml +++ b/indoteknik_custom/views/product_product.xml @@ -18,7 +18,7 @@ <field name="model_id" ref="product.model_product_product"/> <field name="binding_model_id" ref="product.model_product_product"/> <field name="state">code</field> - <field name="code">model.sync_to_solr()</field> + <field name="code">model.action_sync_to_solr()</field> </record> </data> </odoo>
\ No newline at end of file diff --git a/indoteknik_custom/views/product_template.xml b/indoteknik_custom/views/product_template.xml index bbbcc4e1..b2939867 100755 --- a/indoteknik_custom/views/product_template.xml +++ b/indoteknik_custom/views/product_template.xml @@ -82,7 +82,7 @@ <field name="model_id" ref="product.model_product_template"/> <field name="binding_model_id" ref="product.model_product_template"/> <field name="state">code</field> - <field name="code">model.sync_to_solr()</field> + <field name="code">model.action_sync_to_solr()</field> </record> </data> </odoo>
\ No newline at end of file diff --git a/indoteknik_custom/views/website_categories_homepage.xml b/indoteknik_custom/views/website_categories_homepage.xml index bd64f201..aa54ca7a 100644 --- a/indoteknik_custom/views/website_categories_homepage.xml +++ b/indoteknik_custom/views/website_categories_homepage.xml @@ -56,7 +56,7 @@ <field name="model_id" ref="indoteknik_custom.model_website_categories_homepage"/> <field name="binding_model_id" ref="indoteknik_custom.model_website_categories_homepage"/> <field name="state">code</field> - <field name="code">model.sync_to_solr()</field> + <field name="code">model.action_sync_to_solr()</field> </record> <menuitem |
