Created
December 24, 2014 00:05
-
-
Save katyukha/5d3f1939c7a320d821d7 to your computer and use it in GitHub Desktop.
Code comments related to https://github.com/odoo/odoo/pull/618
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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