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.
399 lines
16 KiB
399 lines
16 KiB
# -*- coding: utf-8 -*-
|
|
##############################################################################
|
|
#
|
|
# Cybrosys Technologies Pvt. Ltd.
|
|
#
|
|
# Copyright (C) 2021-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
|
|
# Author: Cybrosys Techno Solutions (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
|
|
# GENERAL PUBLIC LICENSE (AGPL v3) along with this program.
|
|
# If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
##############################################################################
|
|
|
|
from odoo import fields, models, api, _
|
|
from odoo.exceptions import UserError
|
|
from psycopg2 import sql
|
|
|
|
|
|
|
|
class MasterSearch(models.Model):
|
|
_name = 'master.search'
|
|
_description = "Model for master search"
|
|
_rec_name = 'name'
|
|
_order = "create_date desc"
|
|
|
|
name = fields.Char(string="Name", default=lambda self: _('Search'))
|
|
res_customers_id = fields.Many2many('res.partner',
|
|
'res_customers_search_rel',
|
|
'res_customers_id', 'search_id',
|
|
string="Locations")
|
|
search_string = fields.Char(string="Search")
|
|
search_mode = fields.Selection(
|
|
[('all', 'All'), ('active', 'Active'), ('inactive', 'Inactive')],
|
|
string="Search Mode", default="active")
|
|
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')
|
|
master_search_ids = fields.Many2many('master.search',
|
|
'master_search_self_rel', 'search_id',
|
|
'search_id1',
|
|
compute="_get_recent_searches",
|
|
limit=1)
|
|
history_count = fields.Integer(string="History Count",
|
|
compute="_get_history_count")
|
|
customer_ids = fields.Many2many('res.partner', 'master_search_company_rel',
|
|
'search_id', 'company_id')
|
|
product_ids = fields.Many2many('product.template',
|
|
'master_search_product_rel', 'search_id',
|
|
'company_id')
|
|
transaction_details = fields.Many2many('stock.picking',
|
|
'master_search_transaction_details_rel',
|
|
'search_id',
|
|
'company_id', string="Inventory")
|
|
customer_count = fields.Integer(string="Company Count",
|
|
compute="_get_operator_count")
|
|
product_count = fields.Integer(string="Product Count",
|
|
compute="_get_product_count")
|
|
transaction_count = fields.Integer(string="Transaction Count",
|
|
compute="_get_transaction_count")
|
|
sale_count = fields.Integer(string="Sale Count", compute="_get_sale_count")
|
|
purchase_count = fields.Integer(string="Sale Count",
|
|
compute="_get_purchase_count")
|
|
account_count = fields.Integer(string="Account Count",
|
|
compute="_get_account_count")
|
|
user_id = fields.Many2one('res.users', string="User",
|
|
default=lambda self: self.env.user)
|
|
match_entire = fields.Boolean(string="Match entire sentence")
|
|
sale_details = fields.Many2many('sale.order',
|
|
'master_search_sale_details_rel',
|
|
'search_id',
|
|
'company_id', string="Sale")
|
|
purchase_details = fields.Many2many('purchase.order',
|
|
'master_search_purchase_details_rel',
|
|
'search_id',
|
|
'company_id', string="Sale")
|
|
account_details = fields.Many2many('account.move',
|
|
'master_search_account_details_rel',
|
|
'search_id',
|
|
'company_id', string="Account")
|
|
|
|
@api.depends('search_string')
|
|
def _get_recent_searches(self):
|
|
""" Get recent searches """
|
|
# unlink search result with empty string
|
|
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()
|
|
# get search histories avoid null strings
|
|
recent_searches = self.env['master.search'].search([
|
|
('search_string', 'not in', ['', False])])
|
|
# commended for viewing last search
|
|
# self.master_search_ids = recent_searches.filtered(
|
|
# lambda x: x.id != self.id) if self.id else recent_searches
|
|
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_details)
|
|
|
|
@api.depends('sale_count')
|
|
def _get_sale_count(self):
|
|
""" Get sale details count """
|
|
self.sale_count = len(self.sale_details)
|
|
|
|
@api.depends('purchase_count')
|
|
def _get_purchase_count(self):
|
|
""" Get purchase details count """
|
|
self.purchase_count = len(self.purchase_details)
|
|
|
|
@api.depends('account_count')
|
|
def _get_account_count(self):
|
|
""" Get account details count """
|
|
self.account_count = len(self.account_details)
|
|
|
|
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(" ")
|
|
# delete all the lines
|
|
self.customer_ids = self.product_ids = self.transaction_details = False
|
|
# search for entire sentence
|
|
if self.match_entire:
|
|
return self._search_query(self.search_string)
|
|
# search for all the words
|
|
for key in search_keys:
|
|
search_vals = 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'")
|
|
|
|
# search for customers
|
|
self._search_customer(key, active_qry) \
|
|
if self.search_by in ['any', 'customer'] else False
|
|
# search for products
|
|
self._search_products(key, active_qry, company_id) \
|
|
if self.search_by in ['any', 'product'] else False
|
|
# search for inventory transactions
|
|
self._search_inventory_transactions(key, active_qry, company_id) \
|
|
if self.search_by in ['any', 'transaction details'] else False
|
|
# search for inventory transactions
|
|
self._search_sale_transactions(key, active_qry, company_id) \
|
|
if self.search_by in ['any', 'sale details'] else False
|
|
# search for purchase transactions
|
|
self._search_purchase_transactions(key, active_qry, company_id) \
|
|
if self.search_by in ['any', 'purchase details'] else False
|
|
# search for account transactions
|
|
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_details += 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_details += 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_details += 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_details += 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
|
|
|