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.
 
 
 
 
 

156 lines
6.5 KiB

# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2025-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 odoo import http
from odoo.http import request
from odoo.addons.website_sale.controllers.main import WebsiteSale
class WebsiteSaleInherit(WebsiteSale):
@http.route()
def shop(self, page=0, category=None, search='', min_price=0.0,
max_price=0.0, ppg=False, **post):
"""Supering to update the product data."""
res = super().shop(page, category, search, min_price, max_price, ppg,
**post)
currency = request.website.currency_id
recommended_products = self.get_personalized_recommendations()
best_sellers = self.get_bestseller_products()
all_products = res.qcontext.get('products', [])
offset = int(post.get('offset', 0))
all_product_data = [{
'name': product.name,
'price': product.list_price,
'image_url': f'/web/image/product.template/{product.id}/image_1920',
'url': f'/shop/product/{product.id}',
'currency_symbol': currency.symbol,
'product_id' :product.id,
'product_variant_id':product.product_variant_id.id,
'type':product.type,
'products_variant_id': product.product_variant_id.id,
} for product in all_products]
visible_products = all_product_data[:12]
recommended_data = [{
'name': product.name,
'price': product.list_price,
'image_url': f'/web/image/product.template/{product.id}/image_1920',
'url': f'/shop/product/{product.id}',
'currency_symbol': currency.symbol,
'product_id' :product.id,
'product_variant_id':product.product_variant_id.id,
'type':product.type,
'products_id': product,
'products_variant_id': product.product_variant_id.id,
} for product in recommended_products]
products_data = [{
'name': product.name,
'price': product.list_price,
'image_url': f'/web/image/product.template/{product.id}/image_1920',
'url': f'/shop/product/{product.id}',
'currency_symbol': currency.symbol,
'product_id' :product.id,
'product_variant_id':product.product_variant_id.id,
'type':product.type,
'products_id': product,
'products_variant_id': product.product_variant_id.id,
} for product in best_sellers]
res.qcontext.update({
'best_sellers': products_data,
'recommended_data': recommended_data,
'all_products': all_product_data,
'visible_products': visible_products,
'total_products': len(all_product_data),
'products_per_page': 12,
'offset': offset + 12
})
return res
def get_bestseller_products(self, **kwargs):
"""Get the top-selling products based on sales quantity."""
query = """
SELECT sol.product_id, SUM(sol.product_uom_qty) as total_qty
FROM sale_order_line sol
JOIN product_product pp ON sol.product_id = pp.id
JOIN product_template pt ON pp.product_tmpl_id = pt.id
WHERE sol.state IN ('sale', 'done')
AND pt.is_published = TRUE
GROUP BY sol.product_id
ORDER BY total_qty DESC
LIMIT 12
"""
request.env.cr.execute(query)
results = request.env.cr.fetchall()
# Get product IDs from query results
product_ids = [row[0] for row in results]
if product_ids:
# Fetch the corresponding product templates
products = request.env['product.product'].sudo().browse(
product_ids)
best_sellers = products.mapped('product_tmpl_id')
else:
# Fallback to the newest products if no sales data
best_sellers = request.env['product.template'].sudo().search([
('is_published', '=', True)], limit=12)
return best_sellers
def get_personalized_recommendations(self):
"""Method to get personalized recommendation on the products."""
# Get the logged-in partner
partner = request.env.user.partner_id
# Fetch the partner's purchase history
orders = request.env['sale.order'].sudo().search([
('partner_id', '=', partner.id),
('state', 'in', ['sale', 'done']), # Only confirmed orders
])
# Collect purchased product template IDs and categories
purchased_templates = set()
purchased_categories = set()
for order in orders:
for line in order.order_line:
purchased_templates.add(
line.product_id.product_tmpl_id.id)
purchased_categories.add(
line.product_id.categ_id.id)
# Fetch recommended product templates based on purchase history
recommended_templates = request.env['product.template'].search([
('categ_id', 'in', list(purchased_categories)),
('id', 'not in', list(purchased_templates)),
('is_published', '=', True), # Only published products
], limit=10) # Limit to 10 recommendations
return recommended_templates
@http.route('/shop/products/attributes', type='json', auth="public", website=True)
def get_products_attributes(self, product_ids=None, **kw):
"""Method to get products."""
result = {}
if product_ids:
products = request.env['product.template'].sudo().browse(product_ids)
for product in products:
result[product.id] = bool(product.valid_product_template_attribute_line_ids)
return result