提交 189a24b1 authored 作者: 伍姿英's avatar 伍姿英

Merge branch 'release/3.6.3'

# -*- coding: utf-8 -*-
from . import models
\ No newline at end of file
{
'name': 'Multi Record Search',
'version': '16.0.1.0.0',
'category': 'Tools',
'summary': 'Multi Search Mixin for Odoo Models',
'description': """
This module provides a mixin that allows searching multiple records at once using special syntax:
{term1 term2 term3}
[term1, term2, term3]
空格,逗号,换行 这些可以在系统参数进行自定义,用{}或[]包围
The mixin can be inherited by any model to enable multi-search functionality.
""",
'author': 'SeaTek',
'license': 'LGPL-3',
'website': 'https://seateklab.vn/',
'depends': ['base', 'web'],
'data': [
'data/data.xml',
],
"images": ["static/description/banner.png"],
'installable': True,
'auto_install': False,
'application': False,
}
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<record id="multi_record_search_separators" model="ir.config_parameter">
<field name="key">multi_record_search_separators</field>
<field name="value">[',', ',', ' ', '\n', ' ']</field>
</record>
</odoo>
\ No newline at end of file
# -*- coding: utf-8 -*-
from . import multi_search
\ No newline at end of file
import re
import logging
from odoo import models, api, fields, _
from odoo.osv import expression
_logger = logging.getLogger(__name__)
# Extend Base Model to apply multi-search globally
class BaseModel(models.AbstractModel):
_inherit = 'base'
@api.model
def _get_multi_search_pattern(self, value):
"""Check is multi-search pattern or not."""
if not isinstance(value, str):
return False, []
if value.startswith('{') and value.endswith('}') or value.startswith('[') and value.endswith(']'):
content = value[1:-1]
if not content:
return False, []
# 直接根据逗号或空格或换行符分割
separators = self.env['ir.config_parameter'].sudo().get_param('multi_record_search_separators',
default="[',', ',', ' ', '\n', ' ']")
separators = eval(separators)
for sep in separators:
content = content.replace(sep, '!')
search_terms = [term.strip() for term in content.split('!') if term.strip()]
if search_terms:
return bool(search_terms), search_terms
# search_terms = [term.strip() for term in content.split() if term.strip()]
return bool(search_terms), search_terms
# # 直接根据逗号或空格或换行符分割
# separators = self.env['ir.config_parameter'].sudo().get_param('multi_record_search_separators',
# default="[',', ',', ' ', '\n', ' ']")
# separators = eval(separators)
# # 判断value是否包含分隔符
# if any(sep in value for sep in separators) or value.startswith('{') and value.endswith('}') or value.startswith(
# '[') and value.endswith(']'):
# print('value:%s' % value)
# # {record1 record2 ...}
# if value.startswith('{') and value.endswith('}'):
# content = value[1:-1].strip()
# if not content:
# return False, []
#
# search_terms = [term.strip() for term in content.split() if term.strip()]
# return bool(search_terms), search_terms
#
# # [record1, record2, ...]
# elif value.startswith('[') and value.endswith(']'):
# content = value[1:-1].strip()
# if not content:
# return False, []
#
# search_terms = [term.strip() for term in content.split(',') if term.strip()]
# return bool(search_terms), search_terms
# else:
#
# for sep in separators:
# value = value.replace(sep, '!')
# search_terms = [term.strip() for term in value.split('!') if term.strip()]
# if search_terms:
# return bool(search_terms), search_terms
return False, []
@api.model
def _search(self, args, offset=0, limit=None, order=None, count=False, access_rights_uid=None):
"""Override _search for all models"""
try:
new_args = self._process_multi_search_args(args)
return super(BaseModel, self)._search(
new_args, offset=offset, limit=limit, order=order,
count=count, access_rights_uid=access_rights_uid
)
except Exception as e:
_logger.warning("Multi-search processing failed, falling back to normal search: %s", str(e))
# Fallback to normal search if multi-search fails
return super(BaseModel, self)._search(
args, offset=offset, limit=limit, order=order,
count=count, access_rights_uid=access_rights_uid
)
@api.model
def _process_multi_search_args(self, args):
if not args:
return args
new_args = []
i = 0
while i < len(args):
arg = args[i]
if arg in ('&', '|', '!'):
new_args.append(arg)
i += 1
continue
if isinstance(arg, (list, tuple)) and len(arg) == 3:
field_name, operator, value = arg
# Check multi-search
is_multi_search, search_terms = self._get_multi_search_pattern(value)
if is_multi_search and search_terms:
term_domains = []
for term in search_terms:
term_domains.append([(field_name, operator, term)])
if len(term_domains) == 1:
new_args.extend(term_domains[0])
else:
try:
or_domain = expression.OR(term_domains)
new_args.extend(or_domain)
except Exception as e:
_logger.warning("Failed to create OR domain for multi-search: %s", str(e))
# Fallback
new_args.append(arg)
i += 1
continue
new_args.append(arg)
i += 1
return new_args
@api.model
def name_search(self, name='', args=None, operator='ilike', limit=100):
"""Override name_search for all models"""
if name:
is_multi_search, search_terms = self._get_multi_search_pattern(name)
if is_multi_search and search_terms:
# Create domain for multi-search
name_domains = []
for term in search_terms:
name_domains.append([(self._rec_name, operator, term)])
if len(name_domains) == 1:
search_domain = name_domains[0]
else:
try:
search_domain = expression.OR(name_domains)
except Exception as e:
_logger.warning("Failed to create OR domain for name_search: %s", str(e))
# Fallback to normal search
return super(BaseModel, self).name_search(
name=name, args=args, operator=operator, limit=limit
)
if args:
search_domain = expression.AND([args, search_domain])
# Find with domain
records = self.search(search_domain, limit=limit)
return records.name_get()
# Fallback to normal name_search
return super(BaseModel, self).name_search(
name=name, args=args, operator=operator, limit=limit
)
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论