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.
		
		
		
		
		
			
		
			
				
					
					
						
							389 lines
						
					
					
						
							15 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							389 lines
						
					
					
						
							15 KiB
						
					
					
				| # -*- coding: utf-8 -*- | |
| ############################################################################# | |
| # | |
| #    Cybrosys Technologies Pvt. Ltd. | |
| # | |
| #    Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | |
| #    Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>) | |
| # | |
| #    You can modify it under the terms of the GNU LESSER | |
| #    GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. | |
| # | |
| #    You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE | |
| #    (LGPL v3) along with this program. | |
| #    If not, see <http://www.gnu.org/licenses/>. | |
| # | |
| ############################################################################# | |
| from datetime import datetime | |
| from werkzeug.exceptions import Forbidden, NotFound | |
| from odoo import fields, http, SUPERUSER_ID, tools, _ | |
| from odoo.addons.http_routing.models.ir_http import slug | |
| from odoo.addons.website.controllers.main import QueryURL | |
| from odoo import http | |
| from odoo.http import request | |
| from odoo.addons.website_sale.controllers import main | |
| 
 | |
| from odoo.tools import lazy | |
| 
 | |
| 
 | |
| class WebsiteSale(main.WebsiteSale): | |
|     def shop(self, page=0, category=None, search='', min_price=0.0, | |
|              max_price=0.0, ppg=False, **post): | |
|         """This function helps to override the functionalites of a website shop""" | |
|         add_qty = int(post.get('add_qty', 1)) | |
|         try: | |
|             min_price = float(min_price) | |
|         except ValueError: | |
|             min_price = 0 | |
|         try: | |
|             max_price = float(max_price) | |
|         except ValueError: | |
|             max_price = 0 | |
| 
 | |
|         Category = request.env['product.public.category'] | |
|         if category: | |
|             category = Category.search([('id', '=', int(category))], limit=1) | |
|             if not category or not category.can_access_from_current_website(): | |
|                 raise NotFound() | |
|         else: | |
|             category = Category | |
| 
 | |
|         website = request.env['website'].get_current_website() | |
|         if ppg: | |
|             try: | |
|                 ppg = int(ppg) | |
|                 post['ppg'] = ppg | |
|             except ValueError: | |
|                 ppg = False | |
|         if not ppg: | |
|             ppg = website.shop_ppg or 20 | |
| 
 | |
|         ppr = website.shop_ppr or 4 | |
| 
 | |
|         attrib_list = request.httprequest.args.getlist('attrib') | |
|         attrib_values = [[int(x) for x in v.split("-")] for v in attrib_list if | |
|                          v] | |
|         attributes_ids = {v[0] for v in attrib_values} | |
|         attrib_set = {v[1] for v in attrib_values} | |
| 
 | |
|         keep = QueryURL('/shop', **self._shop_get_query_url_kwargs( | |
|             category and int(category), search, min_price, max_price, **post)) | |
| 
 | |
|         now = datetime.timestamp(datetime.now()) | |
|         pricelist = request.env['product.pricelist'].browse( | |
|             request.session.get('website_sale_current_pl')) | |
|         if not pricelist or request.session.get('website_sale_pricelist_time', | |
|                                                 0) < now - 60 * 60:  # test: 1 hour in session | |
|             pricelist = website.get_current_pricelist() | |
|             request.session['website_sale_pricelist_time'] = now | |
|             request.session['website_sale_current_pl'] = pricelist.id | |
| 
 | |
|         request.update_context(pricelist=pricelist.id, | |
|                                partner=request.env.user.partner_id) | |
| 
 | |
|         filter_by_price_enabled = website.is_view_active( | |
|             'website_sale.filter_products_price') | |
|         if filter_by_price_enabled: | |
|             company_currency = website.company_id.currency_id | |
|             conversion_rate = request.env['res.currency']._get_conversion_rate( | |
|                 company_currency, pricelist.currency_id, | |
|                 request.website.company_id, fields.Date.today()) | |
|         else: | |
|             conversion_rate = 1 | |
| 
 | |
|         url = "/shop" | |
|         if search: | |
|             post["search"] = search | |
|         if attrib_list: | |
|             post['attrib'] = attrib_list | |
| 
 | |
|         options = self._get_search_options( | |
|             category=category, | |
|             attrib_values=attrib_values, | |
|             pricelist=pricelist, | |
|             min_price=min_price, | |
|             max_price=max_price, | |
|             conversion_rate=conversion_rate, | |
|             **post | |
|         ) | |
|         fuzzy_search_term, product_count, search_product = self._shop_lookup_products( | |
|             attrib_set, options, post, search, website) | |
| 
 | |
|         filter_by_price_enabled = website.is_view_active( | |
|             'website_sale.filter_products_price') | |
|         if filter_by_price_enabled: | |
|             # TODO Find an alternative way to obtain the domain through the search metadata. | |
|             Product = request.env['product.template'].with_context( | |
|                 bin_size=True) | |
|             domain = self._get_search_domain(search, category, attrib_values) | |
| 
 | |
|             # This is ~4 times more efficient than a search for the cheapest and most expensive products | |
|             from_clause, where_clause, where_params = Product._where_calc( | |
|                 domain).get_sql() | |
|             query = f""" | |
|                 SELECT COALESCE(MIN(list_price), 0) * {conversion_rate}, COALESCE(MAX(list_price), 0) * {conversion_rate} | |
|                   FROM {from_clause} | |
|                  WHERE {where_clause} | |
|             """ | |
|             request.env.cr.execute(query, where_params) | |
|             available_min_price, available_max_price = request.env.cr.fetchone() | |
| 
 | |
|             if min_price or max_price: | |
|                 if min_price: | |
|                     min_price = min_price if min_price <= available_max_price else available_min_price | |
|                     post['min_price'] = min_price | |
|                 if max_price: | |
|                     max_price = max_price if max_price >= available_min_price else available_max_price | |
|                     post['max_price'] = max_price | |
| 
 | |
|         website_domain = website.website_domain() | |
|         categs_domain = [('parent_id', '=', False)] + website_domain | |
|         if search: | |
|             search_categories = Category.search( | |
|                 [('product_tmpl_ids', 'in', | |
|                   search_product.ids)] + website_domain | |
|             ).parents_and_self | |
|             categs_domain.append(('id', 'in', search_categories.ids)) | |
|         else: | |
|             search_categories = Category | |
|         categs = lazy(lambda: Category.search(categs_domain)) | |
| 
 | |
|         if category: | |
|             url = "/shop/category/%s" % slug(category) | |
| 
 | |
|         pager = website.pager(url=url, total=product_count, page=page, | |
|                               step=ppg, scope=7, url_args=post) | |
|         offset = pager['offset'] | |
|         product_count = request.env['product.template'].search_count( | |
|             [('pd', '=', True)]) | |
|         if product_count == 0: | |
|             products = search_product[offset:offset + ppg] | |
|         else: | |
|             products = request.env['product.template'].search( | |
|                 [('pd', '=', True)]) | |
| 
 | |
|         ProductAttribute = request.env['product.attribute'] | |
|         if products: | |
|             # get all products without limit | |
|             attributes = lazy(lambda: ProductAttribute.search([ | |
|                 ('product_tmpl_ids', 'in', search_product.ids), | |
|                 ('visibility', '=', 'visible'), | |
|             ])) | |
|         else: | |
|             attributes = lazy(lambda: ProductAttribute.browse(attributes_ids)) | |
| 
 | |
|         layout_mode = request.session.get('website_sale_shop_layout_mode') | |
|         if not layout_mode: | |
|             if website.viewref('website_sale.products_list_view').active: | |
|                 layout_mode = 'list' | |
|             else: | |
|                 layout_mode = 'grid' | |
|             request.session['website_sale_shop_layout_mode'] = layout_mode | |
| 
 | |
|         products_prices = lazy(lambda: products._get_sales_prices(pricelist)) | |
| 
 | |
|         values = { | |
|             'search': fuzzy_search_term or search, | |
|             'original_search': fuzzy_search_term and search, | |
|             'order': post.get('order', ''), | |
|             'category': category, | |
|             'attrib_values': attrib_values, | |
|             'attrib_set': attrib_set, | |
|             'pager': pager, | |
|             'pricelist': pricelist, | |
|             'add_qty': add_qty, | |
|             'products': products, | |
|             'search_product': search_product, | |
|             'search_count': product_count,  # common for all searchbox | |
|             'bins': lazy( | |
|                 lambda: main.TableCompute().process(products, ppg, ppr)), | |
|             'ppg': ppg, | |
|             'ppr': ppr, | |
|             'categories': categs, | |
|             'attributes': attributes, | |
|             'keep': keep, | |
|             'search_categories_ids': search_categories.ids, | |
|             'layout_mode': layout_mode, | |
|             'products_prices': products_prices, | |
|             'get_product_prices': lambda product: lazy( | |
|                 lambda: products_prices[product.id]), | |
|             'float_round': tools.float_round, | |
|         } | |
|         if filter_by_price_enabled: | |
|             values['min_price'] = min_price or available_min_price | |
|             values['max_price'] = max_price or available_max_price | |
|             values['available_min_price'] = tools.float_round( | |
|                 available_min_price, 2) | |
|             values['available_max_price'] = tools.float_round( | |
|                 available_max_price, 2) | |
|         if category: | |
|             values['main_object'] = category | |
|         values.update(self._get_additional_shop_values(values)) | |
|         return request.render("website_sale.products", values) | |
| 
 | |
| 
 | |
| class WebsiteEcoFoodNewArrivals(http.Controller): | |
| 
 | |
|     @http.route('/eco_food_new_arrivals', auth="public", type='json', | |
|                 website=True) | |
|     def eco_food_new_arrivals(self): | |
|         """this function used to create new arrivals products""" | |
| 
 | |
|         new_arrival = request.env['new.arrival'].sudo().search([]) | |
|         products = { | |
|             'new_arrival': new_arrival.new_arrivals_ids.read() | |
|         } | |
|         return products | |
| 
 | |
|     @http.route('/add_to_cart/<int:id>', auth="public", type='http', | |
|                 website=True) | |
|     def add_to_cart(self, id): | |
|         """this function is used for adding to cart""" | |
|         product = \ | |
|         request.env['product.product'].search([('product_tmpl_id', '=', id)])[ | |
|             0] | |
|         so = request.website.sale_get_order(force_create=True) | |
|         so._cart_update( | |
|             product_id=product.id, | |
|             add_qty=1, | |
|             set_qty=1 | |
|         ) | |
| 
 | |
|         return request.redirect('/shop/cart') | |
| 
 | |
|     @http.route('/add_to_wishlist_new_arrival/<int:product_id>', auth="public", | |
|                 type='http', website=True) | |
|     def add_to_wishlist(self, product_id, **kw): | |
|         """this function is used for adding to wishlist""" | |
|         prod_id = request.env['product.template'].browse(product_id) | |
|         product_ids = prod_id._create_first_product_variant().id | |
|         website = request.website | |
|         pricelist = website.pricelist_id | |
|         product = request.env['product.product'].browse(product_ids) | |
| 
 | |
|         price = product._get_combination_info_variant( | |
|             pricelist=website.pricelist_id, | |
|         )['price'] | |
| 
 | |
|         Wishlist = request.env['product.wishlist'] | |
|         if request.website.is_public_user(): | |
|             Wishlist = Wishlist.sudo() | |
|             partner_id = False | |
|         else: | |
|             partner_id = request.env.user.partner_id.id | |
| 
 | |
|         wish = Wishlist._add_to_wishlist( | |
|             pricelist.id, | |
|             pricelist.currency_id.id, | |
|             request.website.id, | |
|             price, | |
|             product_ids, | |
|             partner_id | |
|         ) | |
| 
 | |
|         if not partner_id: | |
|             request.session['wishlist_ids'] = request.session.get( | |
|                 'wishlist_ids', []) + [wish.id] | |
| 
 | |
|         return request.redirect('/shop/wishlist') | |
| 
 | |
|     @http.route('/cart_quantity_minus', auth="public", type='json', | |
|                 website=True) | |
|     def cart_quantity_minus(self, line_id): | |
|         """this function is used for cart quantity minus""" | |
| 
 | |
|         so = request.website.sale_get_order() | |
|         for rec in so.order_line: | |
|             if rec.id == line_id: | |
|                 rec.product_uom_qty -= 1 | |
| 
 | |
|     @http.route('/cart_quantity_plus', auth="public", type='json', | |
|                 website=True) | |
|     def cart_quantity_plus(self, line_id): | |
|         """this function is used for cart quantity plus""" | |
| 
 | |
|         so = request.website.sale_get_order() | |
|         for rec in so.order_line: | |
|             if rec.id == line_id: | |
|                 rec.product_uom_qty += 1 | |
| 
 | |
|     @http.route('/cart/del/my/product', auth="public", type='json', | |
|                 website=True) | |
|     def delete_cart_products(self, line_id): | |
|         """this function is used for cart quantity delete product""" | |
| 
 | |
|         so = request.website.sale_get_order() | |
|         id = int(line_id) | |
|         for rec in so.order_line: | |
|             if rec.id == id: | |
|                 rec.unlink() | |
| 
 | |
|     @http.route('/get_best_seller', auth="public", type='json', website=True) | |
|     def get_best_seller(self): | |
|         """this function is used for get bestseller product""" | |
| 
 | |
|         best_seller = request.env['dynamic.products'].sudo().search([]) | |
|         values = { | |
|             'best_seller': best_seller.product_tmpl_ids.read() | |
|         } | |
|         return values | |
| 
 | |
|     @http.route('/get_featured_products', auth="public", type='json', | |
|                 website=True) | |
|     def get_featured_products(self): | |
|         """this function is used for get featured products""" | |
|         featured_product = request.env['featured.products'].sudo().search([], | |
|                                                                           limit=8) | |
| 
 | |
|         product = [rec.read()[0] for rec in featured_product] | |
|         slide1 = [] | |
|         slide2 = [] | |
|         slide3 = [] | |
|         slide4 = [] | |
| 
 | |
|         for rec in featured_product.featured_products_ids: | |
|             if len(slide1) < 2: | |
|                 slide1.append(rec.read()) | |
|             elif len(slide2) < 2: | |
|                 slide2.append(rec.read()) | |
|             elif len(slide3) < 2: | |
|                 slide3.append(rec.read()) | |
|             elif len(slide4) < 2: | |
|                 slide4.append(rec.read()) | |
| 
 | |
|         values = { | |
|             'slide1': slide1, | |
|             'slide2': slide2, | |
|             'slide3': slide3, | |
|             'slide4': slide4, | |
|         } | |
|         return values | |
| 
 | |
|     @http.route('/get_recently_added_products', auth="public", type='json', | |
|                 website=True) | |
|     def get_recently_added_products(self): | |
|         """this is the function that will return the most recently added products""" | |
|         recently_added_prod = request.env[ | |
|             'recently_added.products'].sudo().search([], order='id desc', | |
|                                                      limit=16) | |
| 
 | |
|         recent = [rec.read()[0] for rec in recently_added_prod] | |
|         slide1 = [] | |
|         slide2 = [] | |
| 
 | |
|         for rec in recently_added_prod.recent_products_ids: | |
|             if len(slide1) < 6: | |
|                 slide1.append(rec.read()) | |
|             elif len(slide2) < 6: | |
|                 slide2.append(rec.read()) | |
| 
 | |
|         values = { | |
|             'slide1': slide1, | |
|             'slide2': slide2 | |
|         } | |
|         return values
 | |
| 
 |