You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

317 lines
15 KiB

# -*- coding: utf-8 -*-
##############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Aysha Shalin (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC
# LICENSE (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from odoo import api, fields, models, _
from odoo.exceptions import UserError
class MasterSearch(models.Model):
""" Master search model for easy search """
_name = 'master.search'
_description = "Model for master search"
_rec_name = 'name'
_order = "create_date desc"
name = fields.Char(string="Name", default=lambda self: _('Search'),
help='Searched names')
search_string = fields.Char(string="Search", help='Details to search')
search_mode = fields.Selection(
[('all', 'All'), ('active', 'Active'),
('inactive', 'Inactive')],
string="Search Mode", default="active", help='Search Details based on')
search_by = fields.Selection(
[('any', 'Any'), ('customer', 'Customer'),
('product', 'Product'),
('sale details', 'Sale'),
('purchase details', 'Purchase'),
('transaction details', 'Inventory'),
('account details', 'Accounting')],
string="Search By", default='any', help='Search in which model')
master_search_ids = fields.Many2many('master.search',
'master_search_self_rel',
'search_id',
'search_id1',
compute="_get_recent_searches",
limit=1, help='Recent search details')
history_count = fields.Integer(string="History Count",
compute="_get_history_count",
help='Recent search History Count')
customer_ids = fields.Many2many('res.partner',
'master_search_company_rel',
'search_id', 'company_id',
help='To fetch datas of customer search')
product_ids = fields.Many2many('product.template',
'master_search_product_rel',
'search_id', 'company_id',
help='To fetch datas of product search')
transaction_ids = fields.Many2many('stock.picking',
'master_search_transaction_rel',
'search_id',
'company_id',
string="Inventory",
help='To fetch datas of inventory'
' search')
customer_count = fields.Integer(string="Company Count",
compute="_get_operator_count",
help='To fetched customer search count')
product_count = fields.Integer(string="Product Count",
compute="_get_product_count",
help='To fetched product search count')
transaction_count = fields.Integer(string="Transaction Count",
compute="_get_transaction_count",
help='To fetched inventory search '
'count')
sale_count = fields.Integer(string="Sale Count", compute="_get_sale_count",
help='To fetched sale search count')
purchase_count = fields.Integer(string="Sale Count",
compute="_get_purchase_count",
help='To fetched purchase search count')
account_count = fields.Integer(string="Account Count",
compute="_get_account_count",
help='To fetched account search count')
user_id = fields.Many2one('res.users', string="User",
default=lambda self: self.env.user)
match_entire = fields.Boolean(string="Match entire sentence",
help='Only matched datas to be viewed')
sale_ids = fields.Many2many('sale.order',
'master_search_sale_details_rel',
'search_id', 'company_id',
string="Sale", help='To fetch datas of sale '
'search')
purchase_ids = fields.Many2many('purchase.order',
'master_search_purchase_details_rel',
'search_id', 'company_id',
string="Sale", help='To fetch datas of'
' purchase search')
account_ids = fields.Many2many('account.move',
'master_search_account_details_rel',
'search_id', 'company_id',
string="Account", help='To fetch datas of'
'account search')
@api.depends('search_string')
def _get_recent_searches(self):
""" Get recent searches """
try:
current_id = self.id if isinstance(self.id, int) \
else self._origin.id
except:
current_id = False
pass
empty_search = self.env['master.search'].search(
[('search_string', 'in', ['', False]),
('id', 'not in', [current_id, False]
if current_id else [False])])
if empty_search:
empty_search.unlink()
recent_searches = self.env['master.search'].search([
('search_string', 'not in', ['', False])])
self.master_search_ids = recent_searches
def action_unlink_search(self):
""" Unlink search """
self.unlink()
action = self.env.ref('master_search.master_search_action').read()[0]
return action
@api.depends('master_search_ids')
def _get_history_count(self):
""" Get history count """
self.history_count = len(self.master_search_ids)
@api.depends('product_ids')
def _get_product_count(self):
""" Get product count """
self.product_count = len(self.product_ids)
@api.depends('customer_ids')
def _get_operator_count(self):
""" Get customer count """
self.customer_count = len(self.customer_ids)
@api.depends('transaction_count')
def _get_transaction_count(self):
""" Get transaction details count """
self.transaction_count = len(self.transaction_ids)
@api.depends('sale_count')
def _get_sale_count(self):
""" Get sale details count """
self.sale_count = len(self.sale_ids)
@api.depends('purchase_count')
def _get_purchase_count(self):
""" Get purchase details count """
self.purchase_count = len(self.purchase_ids)
@api.depends('account_count')
def _get_account_count(self):
""" Get account details count """
self.account_count = len(self.account_ids)
def action_clear_search(self):
""" clear search input """
self.search_string = ""
self.name = "Search"
@api.model_create_multi
def create(self, vals_list):
""" Function for unlink first result and raise error if no string """
res = super(MasterSearch, self).create(vals_list)
search_index = self.env['master.search'].search_count(
[('user_id', '=', self.env.user.id)])
# unlink old search result if count greater than 10
if search_index > 10:
last_search = self.env['master.search'].search(
[('id', '!=', res.id), ('user_id', '=', self.env.user.id)],
order="create_date asc", limit=1)
last_search.unlink() if last_search else False
return res
def action_search(self):
""" search for the string and store search data """
if self.search_string and "*" in self.search_string:
return
if not self.search_string:
raise UserError(_("Please provide a search string!"))
search_keys = self.search_string.split(" ")
self.customer_ids = self.product_ids = self.transaction_ids = False
if self.match_entire:
return self._search_query(self.search_string)
for key in search_keys:
self._search_query(key)
self.name = self.search_string
def _search_query(self, key):
""" search for the model with given key and update result """
company_id = self.env.user.company_id.id
if self.search_mode == 'all':
active_qry = """ and obj.active in ({},{})
""".format("'FALSE'", "'TRUE'")
elif self.search_mode == 'active':
active_qry = """ and obj.active in ({})""".format("'TRUE'")
else:
active_qry = """ and obj.active in ({})""".format("'FALSE'")
self._search_customer(key, active_qry) \
if self.search_by in ['any', 'customer'] else False
self._search_products(key, active_qry, company_id) \
if self.search_by in ['any', 'product'] else False
self._search_inventory_transactions(key, active_qry, company_id) \
if self.search_by in ['any', 'transaction details'] else False
self._search_sale_transactions(key, active_qry, company_id) \
if self.search_by in ['any', 'sale details'] else False
self._search_purchase_transactions(key, active_qry, company_id) \
if self.search_by in ['any', 'purchase details'] else False
self._search_account_transactions(key, active_qry, company_id) \
if self.search_by in ['any', 'account details'] else False
def _search_account_transactions(self, key, active_qry, company_id):
""" Search for all account transactions """
sp_query = """ SELECT am.id from account_move am
LEFT JOIN res_partner p on p.id = am.partner_id
WHERE am.company_id = {op_id} AND (am.name ILIKE '%{key}%' OR
p.name ILIKE '%{key}%' OR am.state ILIKE '%{key}%')
GROUP BY am.id,p.name
"""
self._cr.execute(
sp_query.format(op_id=company_id, key=key, active=active_qry))
moves = self._cr.dictfetchall()
move_ids = self.env['account.move'].browse([i['id'] for i in moves])
self.account_ids += move_ids
def _search_purchase_transactions(self, key, active_qry, company_id):
""" Search for all purchase transactions """
sp_query = """ SELECT po.id from purchase_order po
LEFT JOIN res_partner p on p.id = po.partner_id
WHERE po.company_id = {op_id} AND (po.name ILIKE '%{key}%' OR
p.name ILIKE '%{key}%' OR po.state ILIKE '%{key}%')
GROUP BY po.id,p.name
"""
self._cr.execute(
sp_query.format(op_id=company_id, key=key, active=active_qry))
purchases = self._cr.dictfetchall()
purchase_ids = self.env['purchase.order'].browse(
[i['id'] for i in purchases])
self.purchase_ids += purchase_ids
def _search_sale_transactions(self, key, active_qry, company_id):
""" Search for all sale transactions """
sp_query = """ SELECT sl.id from sale_order sl
LEFT JOIN res_partner p on p.id = sl.partner_id
LEFT JOIN product_pricelist pl ON pl.id = sl.pricelist_id
LEFT JOIN account_payment_term pt ON pt.id = sl.payment_term_id
WHERE sl.company_id = {op_id} AND (sl.name ILIKE '%{key}%' OR
p.name ILIKE '%{key}%' OR sl.state ILIKE '%{key}%' OR
pl.name::text ILIKE '%{key}%')
GROUP BY sl.id,p.name,pl.name,pt.name
"""
self._cr.execute(
sp_query.format(op_id=company_id, key=key, active=active_qry))
sales = self._cr.dictfetchall()
sale_ids = self.env['sale.order'].browse([i['id'] for i in sales])
self.sale_ids += sale_ids
def _search_inventory_transactions(self, key, active_qry, company_id):
""" Search for all inventory transactions """
sp_query = """ SELECT sp.id from stock_picking sp
LEFT JOIN res_partner p on p.id = sp.partner_id
LEFT JOIN stock_picking_type t ON t.id = sp.picking_type_id
WHERE sp.company_id = {op_id} AND (sp.name ILIKE '%{key}%' OR
p.name ILIKE '%{key}%' OR sp.state ILIKE '%{key}%' OR
t.name::text ILIKE '%{key}%') GROUP BY sp.id,p.name,t.name
"""
self._cr.execute(
sp_query.format(op_id=company_id, key=key, active=active_qry))
transactions = self._cr.dictfetchall()
transaction_ids = self.env['stock.picking'].browse(
[i['id'] for i in transactions])
self.transaction_ids += transaction_ids
def _search_products(self, key, active_qry, company_id):
""" search for products """
pt_query = """ SELECT pt.id FROM product_template pt
LEFT JOIN product_category pc ON pc.id = pt.categ_id
WHERE (pt.name::text ILIKE '%{key}%' OR
pt.default_code ILIKE '%{key}%' OR pt.type ILIKE '%{key}%' OR
pt.description::text ILIKE '%{key}%' OR pc.name ILIKE '%{key}%')
"""
self._cr.execute(pt_query.format(op_id=company_id, key=key,
active=active_qry).replace(
'obj', 'pt'))
template_ids = self._cr.dictfetchall()
product_template_ids = self.env['product.template'].browse(
[i['id'] for i in template_ids])
self.product_ids += product_template_ids
def _search_customer(self, key, active_qry):
""" search for customer """
query = """ SELECT r.id from res_partner r WHERE
(r.parent_id is NULL ) AND r.type = 'contact' {active} AND
(r.name ILIKE '%{key}%' OR r.street ILIKE '%{key}%' OR
r.street2 ILIKE '%{key}%' OR r.city ILIKE '%{key}%' OR
r.zip ILIKE '%{key}%' OR r.email ILIKE '%{key}%') """
query_params = query.format(key=key, active=active_qry).replace(
'obj', 'r')
self._cr.execute(query_params)
customers = self._cr.dictfetchall()
customer_ids = self.env['res.partner'].browse(
[i['id'] for i in customers])
self.customer_ids += customer_ids