from odoo import models from odoo.http import request import math from datetime import datetime import pytz class ProductProduct(models.Model): _inherit = 'product.product' def api_single_response(self, product_product): product_pricelist_default_discount_id = self.env['ir.config_parameter'].get_param('product.pricelist.default_discount_id') product_pricelist_default_discount_id = int(product_pricelist_default_discount_id) product_template = product_product.product_tmpl_id stock = product_product.qty_stock_vendor stock = stock if stock > 0 else 1 data = { 'id': product_product.id, 'parent': { 'id': product_template.id, 'name': product_template.name, 'image': self.env['ir.attachment'].api_image('product.template', 'image_256', product_template.id), }, 'code': product_product.default_code or '', 'name': product_product.display_name, 'price': self.env['product.pricelist'].compute_price(product_pricelist_default_discount_id, product_product.id), 'stock': stock, 'weight': product_product.weight, 'attributes': [x.name for x in product_product.product_template_attribute_value_ids], 'manufacture' : self.api_manufacture(product_product) } return data def v2_api_single_response(self, product_product): product_template = product_product.product_tmpl_id stock = product_product.qty_stock_vendor stock = 1 if stock == 0 else stock data = { 'id': product_product.id, 'parent': { 'id': product_template.id, 'name': product_template.name, 'image': self.env['ir.attachment'].api_image('product.template', 'image_256', product_template.id), }, 'code': product_product.default_code or '', 'name': product_product.display_name, 'price': product_product.calculate_website_price(), 'stock': stock, 'weight': product_product.weight, 'attributes': [x.name for x in product_product.product_template_attribute_value_ids], 'manufacture' : self.api_manufacture(product_product) } return data def has_active_program(self): program_line = self.env['promotion.program.line'] product_promotions = program_line.get_active_promotions(self.id) return True if len(product_promotions) > 0 else False def calculate_website_price(self, pricelist=False): price_for = self.env.context.get('price_for', 'odoo') pricelist = pricelist or self.env.context.get('user_pricelist') default_price_tier = '1_v2' price_tier = [] if pricelist: price_tier = pricelist.get_tier_level() price_tier = price_tier if price_tier else default_price_tier pricelist = self._get_pricelist_tier(price_tier) discount_key = f'discount_tier{price_tier}' price_key = f'price_tier{price_tier}' discount_percentage = pricelist.get(discount_key, 0) price_discount = pricelist.get(price_key, 0) if price_for == 'web': discount_percentage = 0 price = price_discount else: price = self._v2_get_website_price_include_tax() flashsale = self._get_flashsale_price() flashsale_price = flashsale.get('flashsale_price', 0) flashsale_discount = flashsale.get('flashsale_discount', 0) if flashsale_price > 0 and flashsale_price < price_discount: price_discount = flashsale_price discount_percentage = flashsale_discount return { 'price': price, 'discount_percentage': discount_percentage, 'price_discount': price_discount if price_discount > 0 else price } def api_manufacture(self, product_template): if product_template.x_manufacture: manufacture = product_template.x_manufacture return { 'id': manufacture.id, 'name': manufacture.x_name, 'image_promotion_1': self.env['ir.attachment'].api_image('x_manufactures', 'image_promotion_1', manufacture.id), 'image_promotion_2': self.env['ir.attachment'].api_image('x_manufactures', 'image_promotion_2', manufacture.id), } return {} def _is_have_flashsale(self): active_flashsale = self.env['product.pricelist'].get_active_flash_sale() for pricelist in active_flashsale: found_product = self.env['product.pricelist.item'].search([('pricelist_id', '=', pricelist.id), ('product_id', '=', self.id)]) if found_product: return True return False def _get_website_price_include_tax(self): default_pricelist_id = int(1) query = [ ('pricelist_id.id', '=', default_pricelist_id), ('product_id.id', '=', self.id) ] pl_item1 = self.env['product.pricelist.item'].search(query, limit=1) retValue = pl_item1.fixed_price retValue = math.floor(retValue) return retValue def _v2_get_website_price_include_tax(self): default_pricelist_id = int(17022) query = [ ('pricelist_id.id', '=', default_pricelist_id), ('product_id.id', '=', self.id) ] pl_item1 = self.env['product.pricelist.item'].search(query, limit=1) retValue = pl_item1.fixed_price retValue = math.floor(retValue) return retValue def _get_website_price_exclude_tax(self): default_divide_tax = float(1.12) price_incl = self._get_website_price_include_tax() res = price_incl / default_divide_tax return math.floor(res) def _v2_get_website_price_exclude_tax(self): default_divide_tax = float(1.12) price_incl = self._v2_get_website_price_include_tax() res = price_incl / default_divide_tax return math.floor(res) def _get_website_price_after_disc_and_tax(self): default_divide_tax = float(1.12) price_after_disc = self._get_website_price_after_disc() res = price_after_disc / default_divide_tax res = math.ceil(res) return res def _v2_get_website_price_after_disc_and_tax(self): default_divide_tax = float(1.12) price_after_disc = self._v2_get_website_price_after_disc() res = price_after_disc / default_divide_tax res = math.ceil(res) return res def _get_website_tax(self): default_percent_tax = float(12) price_after_disc = self._get_website_price_after_disc_and_tax() res = price_after_disc * default_percent_tax / 100 return math.floor(res) def _v2_get_website_tax(self): default_percent_tax = float(12) price_after_disc = self._v2_get_website_price_after_disc_and_tax() res = price_after_disc * default_percent_tax / 100 return math.floor(res) def _get_website_price_after_disc(self): discount = self._get_website_disc(0) price_incl = self._get_website_price_include_tax() res = 0 if discount > 0: res = price_incl - (price_incl * discount / 100) else: res = price_incl return math.floor(res) def _v2_get_website_price_after_disc(self): discount = self._get_website_disc(0) price_incl = self._v2_get_website_price_include_tax() res = 0 if discount > 0: res = price_incl - (price_incl * discount / 100) else: res = price_incl return math.floor(res) def _get_website_disc(self, partner_id): default_discount_id = int(4) # compile partner partner = self.env['res.partner'].search([('id', '=', partner_id)], limit=1) if partner: if not partner.parent_id: # it means this is a parent default_discount_id = partner.custom_pricelist_id else: # it means this is NOT parent default_discount_id = partner.parent_id.custom_pricelist_id query = [ ('pricelist_id.id', '=', default_discount_id), ('product_id.id', '=', self.id) ] pl_item2 = self.env['product.pricelist.item'].search(query, limit=1) retValue = pl_item2.price_discount return retValue def _get_pricelist_tier1(self): return self._get_pricelist_tier(1) def _get_pricelist_tier2(self): return self._get_pricelist_tier(2) def _get_pricelist_tier3(self): return self._get_pricelist_tier(3) def _get_pricelist_tier(self, tier_number): config_param_name = f'product.pricelist.tier{tier_number}' product_pricelist_tier = int(self.env['ir.config_parameter'].get_param(config_param_name)) default_divide_tax = float(1.11) base_price = discount = price = 0 pricelist_item = self.env['product.pricelist.item'].search([ ('pricelist_id', '=', int(product_pricelist_tier)), ('product_id', '=', self.id) ], limit=1) base_price_incl = self._get_website_price_include_tax() if tier_number in ['1_v2', '2_v2', '3_v2', '4_v2', '5_v2']: base_price_incl = self._v2_get_website_price_include_tax() if pricelist_item and base_price_incl: discount = pricelist_item.price_discount price = base_price_incl - (base_price_incl * discount / 100) price = price / default_divide_tax price = math.floor(price) data = { f'discount_tier{tier_number}': discount if base_price_incl else 0, f'price_tier{tier_number}': price if base_price_incl else 0, } return data def _get_flashsale_price(self): price_for = self.env.context.get('price_for', 'odoo') result = {} current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S') item = self.env['product.pricelist.item'].search([ ('pricelist_id.is_flash_sale', '=', True), ('pricelist_id.start_date', '<=', current_time), ('pricelist_id.end_date', '>=', current_time), ('product_id', '=', self.id) ], limit=1) if not item: return result tier1_id = self.env['ir.config_parameter'].get_param('product.pricelist.tier1_v2', 0) base_pricelist = self.env['product.pricelist.item'].search([ ('pricelist_id', '=', int(tier1_id)), ('product_id', '=', self.id) ], limit=1) base_price = 0 if base_pricelist: base_price = base_pricelist.computed_price # base_price = base_pricelist.computed_price / 1.11 discount = 0 price_flashsale = 0 default_divide_tax = float(1.11) default_tax = float(11) if item.price_discount > 0: discount = item.price_discount price_flashsale = base_price - (base_price * discount // 100) price_flashsale = price_flashsale / default_divide_tax elif item.fixed_price > 0: price_flashsale = item.fixed_price # ask darren for include or exclude price_flashsale = price_flashsale + (price_flashsale * default_tax / 100) discount = (base_price - price_flashsale) * 100 / base_price discount = (math.ceil(discount*100)/100) price_flashsale = item.fixed_price # price_flashsale = price_flashsale / default_divide_tax # darren must fill the fixed price with price exclude if price_for == 'odoo': base_price = self._v2_get_website_price_exclude_tax() discount = (base_price - price_flashsale) / base_price * 100 jkt_tz = pytz.timezone('Asia/Jakarta') result.update({ 'flashsale_id': item.pricelist_id.id, 'flashsale_name': item.pricelist_id.name, 'flashsale_tag': item.pricelist_id.flashsale_tag, 'flashsale_start_date': item.pricelist_id.start_date.replace(tzinfo=pytz.utc).astimezone(jkt_tz).strftime('%Y-%m-%d %H:%M:%S'), 'flashsale_end_date': item.pricelist_id.end_date.replace(tzinfo=pytz.utc).astimezone(jkt_tz).strftime('%Y-%m-%d %H:%M:%S'), 'flashsale_base_price': base_price, 'flashsale_discount': discount, 'flashsale_price': price_flashsale }) return result