Skip to content

Instantly share code, notes, and snippets.

@katyukha
Created December 24, 2014 00:05
Show Gist options
  • Save katyukha/5d3f1939c7a320d821d7 to your computer and use it in GitHub Desktop.
Save katyukha/5d3f1939c7a320d821d7 to your computer and use it in GitHub Desktop.
Code comments related to https://github.com/odoo/odoo/pull/618
def _price_rule_get_multi(self, cr, uid, pricelist, products_by_qty_by_partner, context=None):
context = context or {}
date = context.get('date') or time.strftime('%Y-%m-%d')
products = map(lambda x: x[0], products_by_qty_by_partner)
currency_obj = self.pool.get('res.currency')
product_obj = self.pool.get('product.template')
product_uom_obj = self.pool.get('product.uom')
price_type_obj = self.pool.get('product.price.type')
if not products:
return {}
# CODE BLOCK *_get_pricelist_version*
version = False
for v in pricelist.version_id:
if ((v.date_start is False) or (v.date_start <= date)) and ((v.date_end is False) or (v.date_end >= date)):
version = v
break
if not version:
raise osv.except_osv(_('Warning!'), _("At least one pricelist has no active version !\nPlease create or activate one."))
# END CODE BLOCK
# CODE BLOCK *_get_price_rules*
categ_ids = {}
for p in products:
categ = p.categ_id
while categ:
categ_ids[categ.id] = True
categ = categ.parent_id
categ_ids = categ_ids.keys()
is_product_template = products[0]._name == "product.template"
if is_product_template:
prod_tmpl_ids = [tmpl.id for tmpl in products]
prod_ids = [product.id for product in tmpl.product_variant_ids for tmpl in products]
else:
prod_ids = [product.id for product in products]
prod_tmpl_ids = [product.product_tmpl_id.id for product in products]
# Load all rules
cr.execute(
'SELECT i.id '
'FROM product_pricelist_item AS i '
'WHERE (product_tmpl_id IS NULL OR product_tmpl_id = any(%s)) '
'AND (product_id IS NULL OR (product_id = any(%s))) '
'AND ((categ_id IS NULL) OR (categ_id = any(%s))) '
'AND (price_version_id = %s) '
'ORDER BY sequence, min_quantity desc',
(prod_tmpl_ids, prod_ids, categ_ids, version.id))
item_ids = [x[0] for x in cr.fetchall()]
items = self.pool.get('product.pricelist.item').browse(cr, uid, item_ids, context=context)
# END CODE BLOCK
price_types = {}
results = {}
for product, qty, partner in products_by_qty_by_partner:
uom_price_already_computed = False
results[product.id] = 0.0
price = False
rule_id = False
for rule in items:
# CODE BLOCK *_check_rule*
if 'uom' in context and product.uom_id and context['uom'] != product.uom_id.id:
try:
qty_in_product_uom = product_uom_obj._compute_qty(cr, uid, context['uom'], qty, product.uom_id.id, dict(context.items() + [('raise-exception', False)]))
except except_orm:
qty_in_product_uom = qty
else:
qty_in_product_uom = qty
if rule.min_quantity and qty_in_product_uom<rule.min_quantity:
continue
if is_product_template:
if rule.product_tmpl_id and product.id != rule.product_tmpl_id.id:
continue
if rule.product_id:
continue
else:
if rule.product_tmpl_id and product.product_tmpl_id.id != rule.product_tmpl_id.id:
continue
if rule.product_id and product.id != rule.product_id.id:
continue
if rule.categ_id:
cat = product.categ_id
while cat:
if cat.id == rule.categ_id.id:
break
cat = cat.parent_id
if not cat:
continue
# END CODE BLOCK
# CODE BLOCK *_get_base_price*
if rule.base == -1:
# CODE BLOCK *_get_base_price_pricelist*
if rule.base_pricelist_id:
price_tmp = self._price_get_multi(cr, uid,
rule.base_pricelist_id, [(product,
qty, False)], context=context)[product.id]
ptype_src = rule.base_pricelist_id.currency_id.id
uom_price_already_computed = True
price = currency_obj.compute(cr, uid,
ptype_src, pricelist.currency_id.id,
price_tmp, round=False,
context=context)
# END CODE BLOCK
elif rule.base == -2:
# CODE BLOCK *_get_base_price_partner*
seller = False
for seller_id in product.seller_ids:
if (not partner) or (seller_id.name.id != partner):
continue
seller = seller_id
if not seller and product.seller_ids:
seller = product.seller_ids[0]
if seller:
qty_in_seller_uom = qty
from_uom = context.get('uom') or product.uom_id.id
seller_uom = seller.product_uom and seller.product_uom.id or False
if seller_uom and from_uom and from_uom != seller_uom:
qty_in_seller_uom = product_uom_obj._compute_qty(cr, uid, from_uom, qty, to_uom_id=seller_uom)
else:
uom_price_already_computed = True
for line in seller.pricelist_ids:
if line.min_quantity <= qty_in_seller_uom:
price = line.price
# END CODE BLOCK
else:
# CODE BLOCK *_get_base_price_field*
if rule.base not in price_types:
price_types[rule.base] = price_type_obj.browse(cr, uid, int(rule.base))
price_type = price_types[rule.base]
uom_price_already_computed = True
price = currency_obj.compute(cr, uid,
price_type.currency_id.id, pricelist.currency_id.id,
product_obj._price_get(cr, uid, [product],
price_type.field, context=context)[product.id], round=False, context=context)
# END CODE BLOCK
# END CODE BLOCK
if price is not False:
# CODE BLOCK *_apply_rule*
price_limit = price
price = price * (1.0+(rule.price_discount or 0.0))
if rule.price_round:
price = tools.float_round(price, precision_rounding=rule.price_round)
if context.get('uom'):
# compute price_surcharge based on reference uom
factor = product_uom_obj.browse(cr, uid, context.get('uom'), context=context).factor
else:
factor = 1.0
price += (rule.price_surcharge or 0.0) / factor
if rule.price_min_margin:
price = max(price, price_limit+rule.price_min_margin)
if rule.price_max_margin:
price = min(price, price_limit+rule.price_max_margin)
# END CODE BLOCK
rule_id = rule.id
break
if price:
if 'uom' in context and not uom_price_already_computed:
uom = product.uos_id or product.uom_id
price = product_uom_obj._compute_price(cr, uid, uom.id, price, context['uom'])
results[product.id] = (price, rule_id)
return results
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment