import logging from odoo import fields from odoo.http import request _logger = logging.getLogger(__name__) def _resolve_pricelist(self, request_obj=None): try: req = request_obj or request env = req.env website = req.website except RuntimeError: env = getattr(self, "env", None) or self.env website = env["website"].get_current_website() pricelist = None try: param_value = ( env["ir.config_parameter"] .sudo() .get_param("website_sale_aplicoop.pricelist_id") ) if param_value: pricelist = ( env["product.pricelist"].browse(int(param_value)).exists() or None ) except Exception as e: _logger.warning("_resolve_pricelist: error reading config param: %s", e) if not pricelist: try: pricelist = website._get_current_pricelist() except Exception as e: _logger.warning( "_resolve_pricelist: fallback to website pricelist failed: %s", e ) if not pricelist: pricelist = env["product.pricelist"].sudo().search([], limit=1) return pricelist def _prepare_product_display_info(self, product, product_price_info, request_obj=None): price_data = product_price_info.get(product.id, {}) price = ( price_data.get("price", product.list_price) if price_data else product.list_price ) price_safe = float(price) if price else 0.0 uom_category_name = "" quantity_step = 1 price_unit_suffix = "" if product.uom_id: uom = product.uom_id.sudo() if uom.category_id: uom_category_name = uom.category_id.sudo().name or "" try: try: req = request_obj or request ir_model_data = req.env["ir.model.data"].sudo() except RuntimeError: ir_model_data = product.env["ir.model.data"].sudo() external_id = ir_model_data.search( [ ("model", "=", "uom.category"), ("res_id", "=", uom.category_id.id), ], limit=1, ) if external_id: fractional_categories = [ "uom.product_uom_categ_kgm", "uom.product_uom_categ_vol", "uom.uom_categ_length", "uom.uom_categ_surface", ] full_xmlid = f"{external_id.module}.{external_id.name}" if full_xmlid in fractional_categories: quantity_step = 0.1 if full_xmlid == "uom.product_uom_categ_kgm": price_unit_suffix = "/Kg" except Exception as e: _logger.warning( "_prepare_product_display_info: Error detecting UoM category XML ID for product %s: %s", product.id, str(e), ) try: req = request_obj or request tr_env = req.env except RuntimeError: tr_env = product.env out_of_stock_label = tr_env._("Out of stock") add_to_cart_label = tr_env._( "Add %(product_name)s to cart", product_name=product.name ) return { "display_price": price_safe, "safe_uom_category": uom_category_name, "quantity_step": quantity_step, "price_unit_suffix": price_unit_suffix, "out_of_stock_label": out_of_stock_label, "add_to_cart_label": add_to_cart_label, } def _get_pricing_info( self, product, pricelist, quantity=1.0, partner=None, request_obj=None, ): req = request_obj or request try: env = req.env website = req.website except RuntimeError: env = product.env website = env["website"].get_current_website() partner = partner or env.user.partner_id currency = pricelist.currency_id website_company = ( website.company_id if website and getattr(website, "company_id", False) else False ) company = website_company or product.company_id or env.company price, rule_id = pricelist._get_product_price_rule( product=product, quantity=quantity, target_currency=currency ) price_before_discount = price pricelist_item = env["product.pricelist.item"].sudo().browse(rule_id) if pricelist_item and pricelist_item._show_discount_on_shop(): price_before_discount = pricelist_item._compute_price_before_discount( product=product, quantity=quantity or 1.0, date=fields.Date.context_today(pricelist), uom=product.uom_id, currency=currency, ) has_discounted_price = price_before_discount > price fiscal_position = ( website.fiscal_position_id.sudo() if website and getattr(website, "fiscal_position_id", False) else env["account.fiscal.position"].sudo() ) product_taxes = product.sudo().taxes_id._filter_taxes_by_company(company) taxes = fiscal_position.map_tax(product_taxes) if product_taxes else product_taxes tax_display = "total_included" def compute_display(amount): if not taxes: return amount return taxes.compute_all(amount, currency, 1, product, partner)[tax_display] display_price = compute_display(price) display_list_price = compute_display(price_before_discount) return { "price_unit": price, "price": display_price, "list_price": display_list_price, "has_discounted_price": has_discounted_price, "discount": display_list_price - display_price, "tax_included": tax_display == "total_included", } def _compute_price_info(self, products, pricelist, request_obj=None): product_price_info = {} def _tax_included_default(product_record): try: req = request_obj or request return req.website.show_line_subtotals_tax_selection != "tax_excluded" except RuntimeError: website = product_record.env["website"].get_current_website() if not website: return True return website.show_line_subtotals_tax_selection != "tax_excluded" for product in products: product_variant = ( product.product_variant_ids[0] if product.product_variant_ids else False ) if product_variant and pricelist: try: try: req = request_obj or request partner = req.env.user.partner_id except RuntimeError: partner = product_variant.env.user.partner_id pricing = _get_pricing_info( self, product_variant, pricelist, quantity=1.0, partner=partner, request_obj=request_obj, ) product_price_info[product.id] = pricing except Exception as e: _logger.warning( "_compute_price_info: Error getting price for product %s (id=%s): %s. Using list_price fallback.", product.name, product.id, str(e), ) product_price_info[product.id] = { "price_unit": product.list_price, "price": product.list_price, "list_price": product.list_price, "has_discounted_price": False, "discount": 0.0, "tax_included": _tax_included_default(product), } else: product_price_info[product.id] = { "price_unit": product.list_price, "price": product.list_price, "list_price": product.list_price, "has_discounted_price": False, "discount": 0.0, "tax_included": _tax_included_default(product), } return product_price_info def _get_product_supplier_info(self, products): product_supplier_info = {} for product in products: supplier_name = "" if product.seller_ids: partner = product.seller_ids[0].partner_id.sudo() supplier_name = partner.name or "" if partner.city: supplier_name += f" ({partner.city})" product_supplier_info[product.id] = supplier_name return product_supplier_info def _get_delivery_product_display_price( self, delivery_product, pricelist=None, request_obj=None ): if not delivery_product: return 5.74 try: base_price = float(delivery_product.list_price or 0.0) try: req = request_obj or request website = req.website partner = req.env.user.partner_id company = ( website.company_id or delivery_product.company_id or req.env.company ) except RuntimeError: env = delivery_product.env website = env["website"].get_current_website() partner = env.user.partner_id company = website.company_id or delivery_product.company_id or env.company product_taxes = delivery_product.sudo().taxes_id._filter_taxes_by_company( company ) fiscal_position = ( website.fiscal_position_id.sudo() if website and getattr(website, "fiscal_position_id", False) else delivery_product.env["account.fiscal.position"] ) taxes = ( fiscal_position.map_tax(product_taxes) if product_taxes else product_taxes ) if not taxes: return base_price currency = website.currency_id totals = taxes.compute_all( base_price, currency=currency, quantity=1.0, product=delivery_product, partner=partner, ) return float(totals.get("total_included", base_price) or 0.0) except Exception as e: _logger.warning( "_get_delivery_product_display_price: Error computing delivery display price for product %s (id=%s): %s. Using list_price fallback.", delivery_product.name, delivery_product.id, str(e), ) return float(delivery_product.list_price or 0.0)