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
							 | 
						|
								
							 |