def uos_change(self, cr, uid, ids, product_uos, product_uos_qty=0, product_id=None): if not product_uos: return {"value": {}} product_obj = self.pool.get("product.product") if not product_id: return {"value": {"product_uom": product_uos, "product_uom_qty": product_uos_qty}} # , 'domain': {}} product = product_obj.browse(cr, uid, product_id) value = super(sale_order_line, self).uos_change(cr, uid, ids, product_uos, product_uos_qty, product_id)["value"] if product.coef_amount: product_uom_qty = product_uos_qty * product.coef_amount else: product_uom_qty = product_uos_qty product_uom_qty = rounding(product_uom_qty, product.uom_id.rounding) or 1.0 product_uos_qty = rounding(product_uos_qty, product.uos_id.rounding) value.update( {"product_uos_qty": product_uos_qty, "product_uos": product.uos_id.id, "product_uom_qty": product_uom_qty} ) return {"value": value}
def _compute_qty_obj(self, cr, uid, from_unit, qty, to_unit, context={}): if from_unit.category_id.id <> to_unit.category_id.id: # raise osv.except_osv(_('Warning !'),_('Conversion from Product UoM %s to Default UoM %s is not possible as they both belong to different Category!')% (from_unit.name,to_unit.name)) return qty if from_unit.factor_inv_data: amount = qty * from_unit.factor_inv_data else: amount = qty / from_unit.factor if to_unit: if to_unit.factor_inv_data: amount = rounding(amount / to_unit.factor_inv_data, to_unit.rounding) else: amount = rounding(amount * to_unit.factor, to_unit.rounding) return amount
def uos_change(self, cr, uid, ids, product_uos, product_uos_qty=0, product_id=None): if not product_uos: return {'value': {}} product_obj = self.pool.get('product.product') if not product_id: return { 'value': { 'product_uom': product_uos, 'product_uom_qty': product_uos_qty } } #, 'domain': {}} product = product_obj.browse(cr, uid, product_id) value = super(sale_order_line, self).uos_change(cr, uid, ids, product_uos, product_uos_qty, product_id)['value'] if product.coef_amount: product_uom_qty = product_uos_qty * product.coef_amount else: product_uom_qty = product_uos_qty product_uom_qty = rounding(product_uom_qty, product.uom_id.rounding) or 1.0 product_uos_qty = rounding(product_uos_qty, product.uos_id.rounding) value.update({ 'product_uos_qty': product_uos_qty, 'product_uos': product.uos_id.id, 'product_uom_qty': product_uom_qty, }) return {'value': value}
def _compute_qty_obj(self, cr, uid, from_unit, qty, to_unit, round=True, context=None): if context is None: context = {} if from_unit.category_id.id <> to_unit.category_id.id: if context.get("raise-exception", True): raise osv.except_osv( _("Error !"), _( "Conversion from Product UoM %s to Default UoM %s is not possible as they both belong to different Category!." ) % (from_unit.name, to_unit.name), ) else: return qty amount = qty / from_unit.factor if to_unit: amount = rounding(amount * to_unit.factor, to_unit.rounding) if round: amount = rounding(amount, to_unit.rounding) return amount
def _compute_qty_obj(self, cr, uid, from_unit, qty, to_unit, context=None): if context is None: context = {} if from_unit.category_id.id <> to_unit.category_id.id: if context.get('raise-exception', True): raise osv.except_osv(_('Error!'), _('Conversion from Product UoM %s to Default UoM %s is not possible as they both belong to different Category!.') % (from_unit.name, to_unit.name,)) else: return qty amount = qty / from_unit.factor if to_unit: amount = rounding(amount * to_unit.factor, to_unit.rounding) return amount
def _compute_qty_obj(self, cr, uid, from_unit, qty, to_unit, context=None): if context is None: context = {} if from_unit.category_id.id <> to_unit.category_id.id: if context.get('raise-exception', True): raise osv.except_osv(_('Error !'), _('Conversion from Product UoM m to Default UoM PCE is not possible as they both belong to different Category!.')) else: return qty amount = qty / from_unit.factor if to_unit: amount = rounding(amount * to_unit.factor, to_unit.rounding) return amount
def uom_change(self, cr, uid, ids, product_uom, product_uom_qty=0, product_id=None, context=None): if context == None: context = {} product_obj = self.pool.get('product.product') if not product_id: return {'value': {'product_uos': product_uom, 'product_uos_qty': product_uom_qty}, 'domain': {}} product = product_obj.browse(cr, uid, product_id) value = { 'product_uos': product.uos_id.id, 'product_uos_qty': rounding(product_uom_qty / product.coef_amount, product.uos_id.rounding), } return {'value': value}
def uos_change(self, cr, uid, ids, product_uos, product_uos_qty=0, product_id=None, context=None): if context == None: context = {} product_obj = self.pool.get('product.product') if not product_id: return {'value': {'product_uom': product_uos, 'product_qty': product_uos_qty}, 'domain': {}} product = product_obj.browse(cr, uid, product_id, context=context) value = { 'product_uom': product.uom_id.id, } try: value.update({ 'product_qty': rounding(product_uos_qty * product.coef_amount, product.uom_id.rounding) }) except ZeroDivisionError: pass return {'value': value}
def price_get_multi_travel(self, cr, uid, pricelist_ids, products_by_qty_by_partner, merchandise_id=False, context=None): u"""Prix d'un trajet selon les listes de prix. @param pricelist_ids: @param merchandise_id: @param products_by_qty: @param partner: @param context: { 'date': Date of the pricelist (%Y-%m-%d),} @return: a dict of dict with product_id as key and a dict 'price by pricelist' as value """ list_product = [] def _create_parent_category_list(id, lst): if not id: return [] parent = product_category_tree.get(id) if parent: lst.append(parent) return _create_parent_category_list(parent, lst) else: return lst # _create_parent_category_list if context is None: context = {} date = context.get('date') or time.strftime('%Y-%m-%d') #if 'date' in context: # date = context['date'] currency_obj = self.pool.get('res.currency') product_obj = self.pool.get('product.product') #product_template_obj = self.pool.get('product.template') product_category_obj = self.pool.get('product.category') product_uom_obj = self.pool.get('product.uom') supplierinfo_obj = self.pool.get('product.supplierinfo') price_type_obj = self.pool.get('product.price.type') comission_merchandise = 0 # product.pricelist.version: if not pricelist_ids: pricelist_ids = self.pool.get('product.pricelist').search( cr, uid, [], context=context) pricelist_version_ids = self.pool.get( 'product.pricelist.version').search(cr, uid, [ ('pricelist_id', 'in', pricelist_ids), '|', ('date_start', '=', False), ('date_start', '<=', date), '|', ('date_end', '=', False), ('date_end', '>=', date), ]) if len(pricelist_ids) != len(pricelist_version_ids): raise osv.except_osv( _('Attention !'), _(u"Il y'a au moins une liste de prix sans version active !\nVeuillez s'il vous plaît créer ou activer une." )) # product.product: product_ids = [i[0] for i in products_by_qty_by_partner] #products = dict([(item['id'], item) for item in product_obj.read(cr, uid, product_ids, ['categ_id', 'product_tmpl_id', 'uos_id', 'uom_id'])]) products = product_obj.browse(cr, uid, product_ids, context=context) products_dict = dict([(item.id, item) for item in products]) # product.category: product_category_ids = product_category_obj.search(cr, uid, []) product_categories = product_category_obj.read(cr, uid, product_category_ids, ['parent_id']) product_category_tree = dict([(item['id'], item['parent_id'][0]) for item in product_categories if item['parent_id']]) results = {} for product_id, qty, partner in products_by_qty_by_partner: for pricelist_id in pricelist_ids: price = False tmpl_id = products_dict[ product_id].product_tmpl_id and products_dict[ product_id].product_tmpl_id.id or False categ_id = products_dict[product_id].categ_id and products_dict[ product_id].categ_id.id or False categ_ids = _create_parent_category_list(categ_id, [categ_id]) if categ_ids: categ_where = '(categ_id IN (' + ','.join( map(str, categ_ids)) + '))' else: categ_where = '(categ_id IS NULL)' if partner: partner_where = 'base <> -2 OR %s IN (SELECT name FROM product_supplierinfo WHERE product_id = %s) ' partner_args = (partner, tmpl_id) # product_id -> tmpl_id else: partner_where = 'base <> -2 ' partner_args = () if tmpl_id: cr.execute( 'SELECT i.*, pl.currency_id ' 'FROM product_pricelist_item AS i, ' 'product_pricelist_version AS v, product_pricelist AS pl ' 'WHERE (product_tmpl_id IS NULL OR product_tmpl_id = %s) ' 'AND (product_id IS NULL OR product_id = %s) ' 'AND (' + categ_where + ' OR (categ_id IS NULL)) ' 'AND (' + partner_where + ') ' 'AND price_version_id = %s ' 'AND (min_quantity IS NULL OR min_quantity <= %s) ' 'AND i.price_version_id = v.id AND v.pricelist_id = pl.id ' 'ORDER BY sequence', (tmpl_id, product_id) + partner_args + (pricelist_version_ids[0], qty)) res1 = cr.dictfetchall() uom_price_already_computed = False for res in res1: if res: if res['base'] == -1: if not res['base_pricelist_id']: price = 0.0 else: price_tmp = self.price_get( cr, uid, [res['base_pricelist_id']], product_id, qty, context=context)[res['base_pricelist_id']] ptype_src = self.browse( cr, uid, res['base_pricelist_id']).currency_id.id uom_price_already_computed = True price = currency_obj.compute( cr, uid, ptype_src, res['currency_id'], price_tmp, round=False, context=context) elif res['base'] == -2: # this section could be improved by moving the queries outside the loop: where = [] if partner: where = [('name', '=', partner)] sinfo = supplierinfo_obj.search( cr, uid, [('product_id', '=', tmpl_id)] + where) price = 0.0 if sinfo: qty_in_product_uom = qty product_default_uom = product_obj.read( cr, uid, [product_id], ['uom_id'])[0]['uom_id'][0] supplier = supplierinfo_obj.browse( cr, uid, sinfo, context=context)[0] seller_uom = supplier.product_uom and supplier.product_uom.id or False if seller_uom and product_default_uom and product_default_uom != seller_uom: uom_price_already_computed = True qty_in_product_uom = product_uom_obj._compute_qty( cr, uid, product_default_uom, qty, to_uom_id=seller_uom) cr.execute('SELECT * ' \ 'FROM pricelist_partnerinfo ' \ 'WHERE suppinfo_id IN %s' \ 'AND min_quantity <= %s ' \ 'ORDER BY min_quantity DESC LIMIT 1', (tuple(sinfo),qty_in_product_uom,)) res2 = cr.dictfetchone() if res2: price = res2['price'] else: price_type = price_type_obj.browse( cr, uid, int(res['base'])) uom_price_already_computed = True price = currency_obj.compute( cr, uid, price_type.currency_id.id, res['currency_id'], product_obj.price_get( cr, uid, [product_id], price_type.field, context=context)[product_id], round=False, context=context) if price is not False: price_limit = price price = price * (1.0 + (res['price_discount'] or 0.0)) price = rounding( price, res['price_round'] ) #TOFIX: rounding with tools.float_rouding price += (res['price_surcharge'] or 0.0) if res['price_min_margin']: price = max( price, price_limit + res['price_min_margin']) if res['price_max_margin']: price = min( price, price_limit + res['price_max_margin']) price_merchandise = self.pool.get( 'product.pricelist.item' ).get_total_price_merchandise( cr, uid, pricelist_version_ids[0], product_id, merchandise_id) comission_merchandise = self.pool.get( 'product.pricelist.item' ).get_comission_merchandise( cr, uid, pricelist_version_ids[0], product_id, merchandise_id) comission_is_fixes = self.pool.get( 'product.pricelist.item' ).get_comission_is_fixed(cr, uid, pricelist_version_ids[0], product_id, merchandise_id) comission_fixe = self.pool.get( 'product.pricelist.item').get_comission_fixe( cr, uid, pricelist_version_ids[0], product_id, merchandise_id) if price_merchandise: price = price_merchandise comission = comission_merchandise break else: # False means no valid line found ! But we may not raise an # exception here because it breaks the search price = False if price: results['item_id'] = res['id'] if 'uom' in context and not uom_price_already_computed: product = products_dict[product_id] uom = product.uos_id or product.uom_id price = product_uom_obj._compute_price( cr, uid, uom.id, price, context['uom']) price_merchandise = self.pool.get( 'product.pricelist.item' ).get_total_price_merchandise(cr, uid, pricelist_version_ids[0], product_id, merchandise_id) comission_merchandise = self.pool.get( 'product.pricelist.item' ).get_comission_merchandise(cr, uid, pricelist_version_ids[0], product_id, merchandise_id) comission_is_fixes = self.pool.get( 'product.pricelist.item').get_comission_is_fixed( cr, uid, pricelist_version_ids[0], product_id, merchandise_id) comission_fixe = self.pool.get( 'product.pricelist.item').get_comission_fixe( cr, uid, pricelist_version_ids[0], product_id, merchandise_id) if price_merchandise: price = price_merchandise if results.get(product_id): results[product_id][pricelist_id] = price else: results['comission_merchandise'] = comission_merchandise try: results['comission_is_fixe'] = comission_is_fixes results['comission_fixe'] = comission_fixe except: pass results[product_id] = {pricelist_id: price} return results
def _price_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.product') product_uom_obj = self.pool.get('product.uom') price_type_obj = self.pool.get('product.price.type') 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 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() prod_ids = [x.id for x in products] prod_tmpl_ids = [x.product_tmpl_id.id for x 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) 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 for rule in items: if rule.min_quantity and qty < rule.min_quantity: continue 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 if rule.base == -1: 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) elif rule.base == -2: for seller in product.seller_ids: if (not partner) or (seller.name.id <> partner): continue product_default_uom = product.uom_id.id seller_uom = seller.product_uom and seller.product_uom.id or False if seller_uom and product_default_uom and product_default_uom != seller_uom: uom_price_already_computed = True qty = product_uom_obj._compute_qty( cr, uid, product_default_uom, qty, to_uom_id=seller_uom) for line in seller.pricelist_ids: if line.min_quantity <= qty: price = line.price else: 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) if price is not False: price_limit = price price = price * (1.0 + (rule.price_discount or 0.0)) price = rounding( price, rule.price_round ) #TOFIX: rounding with tools.float_rouding price += (rule.price_surcharge or 0.0) 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) break if price: if 'uom' in context and not uom_price_already_computed: product = products_dict[product.id] 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 return results
def _price_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.product') product_uom_obj = self.pool.get('product.uom') price_type_obj = self.pool.get('product.price.type') 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 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() prod_ids = [x.id for x in products] prod_tmpl_ids = [x.product_tmpl_id.id for x 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) 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 for rule in items: if rule.min_quantity and qty<rule.min_quantity: continue 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 if rule.base == -1: 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) elif rule.base == -2: for seller in product.seller_ids: if (not partner) or (seller.name.id<>partner): continue product_default_uom = product.uom_id.id seller_uom = seller.product_uom and seller.product_uom.id or False if seller_uom and product_default_uom and product_default_uom != seller_uom: uom_price_already_computed = True qty = product_uom_obj._compute_qty(cr, uid, product_default_uom, qty, to_uom_id=seller_uom) for line in seller.pricelist_ids: if line.min_quantity <= qty: price = line.price else: 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) if price is not False: price_limit = price price = price * (1.0+(rule.price_discount or 0.0)) price = rounding(price, rule.price_round) #TOFIX: rounding with tools.float_rouding price += (rule.price_surcharge or 0.0) 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) break if price: if 'uom' in context and not uom_price_already_computed: product = products_dict[product.id] 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 return results
def price_get_calendar(self, cr, uid, pricelist_id, product_id, qty, partner=None, \ time_slot=None, context=None): if context is None: context = {} def _create_parent_category_list(id, lst): if not id: return [] parent = product_category_tree.get(id) if parent: lst.append(parent) return _create_parent_category_list(parent, lst) else: return lst date = time.strftime('%Y-%m-%d') if 'date' in context: date = context['date'] currency_obj = self.pool.get('res.currency') product_obj = self.pool.get('product.product') product_template_obj = self.pool.get('product.template') product_category_obj = self.pool.get('product.category') product_uom_obj = self.pool.get('product.uom') supplierinfo_obj = self.pool.get('product.supplierinfo') price_type_obj = self.pool.get('product.price.type') if not time_slot: res = super(product_pricelist, self).price_get(cr, uid, ids, prod_id, qty, partner=partner, context=context) return res product = self.pool.get('product.product').browse(cr, uid, product_id, context=context) pricelist_version_ids = self.pool.get( 'product.pricelist.version').search(cr, uid, [ ('pricelist_id', '=', pricelist_id), '|', ('date_start', '=', False), ('date_start', '<=', date), '|', ('date_end', '=', False), ('date_end', '>=', date), ]) if not len(pricelist_version_ids): raise osv.except_osv( _('Warning !'), _("At least one pricelist has no active version !\nPlease create or activate one." )) # product.category: product_category_ids = product_category_obj.search(cr, uid, []) product_categories = product_category_obj.read(cr, uid, product_category_ids, ['parent_id']) product_category_tree = dict([(item['id'], item['parent_id'][0]) for item in product_categories if item['parent_id']]) results = {} price = False tmpl_id = product.product_tmpl_id and product.product_tmpl_id.id or False categ_id = product.categ_id and product.categ_id.id or False categ_ids = _create_parent_category_list(categ_id, [categ_id]) if categ_ids: categ_where = '(categ_id IN (' + ','.join(map(str, categ_ids)) + '))' else: categ_where = '(categ_id IS NULL)' cr.execute( 'SELECT i.*, pl.currency_id ' 'FROM product_pricelist_item AS i, ' 'product_pricelist_version AS v, product_pricelist AS pl ' #', attendance_pricelist_rel as att ' 'WHERE (product_tmpl_id IS NULL OR product_tmpl_id = %s) ' 'AND (product_id IS NULL OR product_id = %s) ' 'AND (' + categ_where + ' OR (categ_id IS NULL)) ' 'AND price_version_id = %s ' 'AND (min_quantity IS NULL OR min_quantity <= %s) ' 'AND i.price_version_id = v.id AND v.pricelist_id = pl.id ' #'AND att.item_id = i.id ' 'AND i.time_slot = %s ' 'ORDER BY sequence', (tmpl_id, product_id, pricelist_version_ids[0], qty, time_slot)) res1 = cr.dictfetchall() uom_price_already_computed = False for res in res1: if res: if res['base'] == -1: if not res['base_pricelist_id']: price = 0.0 else: price_tmp = self.price_get( cr, uid, [res['base_pricelist_id']], product_id, qty, context=context)[res['base_pricelist_id']] ptype_src = self.browse( cr, uid, res['base_pricelist_id']).currency_id.id uom_price_already_computed = True price = currency_obj.compute(cr, uid, ptype_src, res['currency_id'], price_tmp, round=False) elif res['base'] == -2: # this section could be improved by moving the queries outside the loop: where = [] if partner: where = [('name', '=', partner)] sinfo = supplierinfo_obj.search( cr, uid, [('product_id', '=', tmpl_id)] + where) price = 0.0 if sinfo: qty_in_product_uom = qty product_default_uom = product_template_obj.read( cr, uid, [tmpl_id], ['uom_id'])[0]['uom_id'][0] supplier = supplierinfo_obj.browse(cr, uid, sinfo, context=context)[0] seller_uom = supplier.product_uom and supplier.product_uom.id or False if seller_uom and product_default_uom and product_default_uom != seller_uom: uom_price_already_computed = True qty_in_product_uom = product_uom_obj._compute_qty( cr, uid, product_default_uom, qty, to_uom_id=seller_uom) cr.execute('SELECT * ' \ 'FROM pricelist_partnerinfo ' \ 'WHERE suppinfo_id IN %s' \ 'AND min_quantity <= %s ' \ 'ORDER BY min_quantity DESC LIMIT 1', (tuple(sinfo),qty_in_product_uom,)) res2 = cr.dictfetchone() if res2: price = res2['price'] else: price_type = price_type_obj.browse(cr, uid, int(res['base'])) uom_price_already_computed = True price = currency_obj.compute( cr, uid, price_type.currency_id.id, res['currency_id'], product_obj.price_get(cr, uid, [product_id], price_type.field, context=context)[product_id], round=False, context=context) if price is not False: price_limit = price price = price * (1.0 + (res['price_discount'] or 0.0)) price = rounding( price, res['price_round'] ) #TOFIX: rounding with tools.float_rouding price += (res['price_surcharge'] or 0.0) if res['price_min_margin']: price = max(price, price_limit + res['price_min_margin']) if res['price_max_margin']: price = min(price, price_limit + res['price_max_margin']) break else: # False means no valid line found ! But we may not raise an # exception here because it breaks the search price = False if price: results['item_id'] = res['id'] 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']) if results.get(product_id): results[product_id][pricelist_id] = price else: results[product_id] = {pricelist_id: price} res = results[product_id][pricelist_id] return res
def price_get_multi(self, cr, uid, pricelist_ids, products_by_qty_by_partner, context=None): """multi products 'price_get'. @param pricelist_ids: @param products_by_qty: @param partner: @param context: { 'date': Date of the pricelist (%Y-%m-%d),} @return: a dict of dict with product_id as key and a dict 'price by pricelist' as value """ def _create_parent_category_list(id, lst): if not id: return [] parent = product_category_tree.get(id) if parent: lst.append(parent) return _create_parent_category_list(parent, lst) else: return lst # _create_parent_category_list if context is None: context = {} date = time.strftime('%Y-%m-%d') if 'date' in context: date = context['date'] currency_obj = self.pool.get('res.currency') product_obj = self.pool.get('product.product') product_template_obj = self.pool.get('product.template') product_category_obj = self.pool.get('product.category') product_uom_obj = self.pool.get('product.uom') supplierinfo_obj = self.pool.get('product.supplierinfo') price_type_obj = self.pool.get('product.price.type') product_pricelist_version_obj = self.pool.get('product.pricelist.version') # product.pricelist.version: if pricelist_ids: pricelist_version_ids = pricelist_ids else: # all pricelists: pricelist_version_ids = self.pool.get('product.pricelist').search(cr, uid, [], context=context) pricelist_version_ids = list(set(pricelist_version_ids)) plversions_search_args = [ ('pricelist_id', 'in', pricelist_version_ids), '|', ('date_start', '=', False), ('date_start', '<=', date), '|', ('date_end', '=', False), ('date_end', '>=', date), ] plversion_ids = product_pricelist_version_obj.search(cr, uid, plversions_search_args) if len(pricelist_version_ids) != len(plversion_ids): msg = "At least one pricelist has no active version !\nPlease create or activate one." raise osv.except_osv(_('Warning !'), _(msg)) # product.product: product_ids = [i[0] for i in products_by_qty_by_partner] #products = dict([(item['id'], item) for item in product_obj.read(cr, uid, product_ids, ['categ_id', 'product_tmpl_id', 'uos_id', 'uom_id'])]) products = product_obj.browse(cr, uid, product_ids, context=context) products_dict = dict([(item.id, item) for item in products]) # product.category: product_category_ids = product_category_obj.search(cr, uid, []) product_categories = product_category_obj.read(cr, uid, product_category_ids, ['parent_id']) product_category_tree = dict([(item['id'], item['parent_id'][0]) for item in product_categories if item['parent_id']]) results = {} for product_id, qty, partner in products_by_qty_by_partner: for pricelist_id in pricelist_version_ids: price = False tmpl_id = products_dict[product_id].product_tmpl_id and products_dict[product_id].product_tmpl_id.id or False categ_id = products_dict[product_id].categ_id and products_dict[product_id].categ_id.id or False categ_ids = _create_parent_category_list(categ_id, [categ_id]) if categ_ids: categ_where = '(categ_id IN (' + ','.join(map(str, categ_ids)) + '))' else: categ_where = '(categ_id IS NULL)' cr.execute( 'SELECT i.*, pl.currency_id ' 'FROM product_pricelist_item AS i, ' 'product_pricelist_version AS v, product_pricelist AS pl ' 'WHERE (product_tmpl_id IS NULL OR product_tmpl_id = %s) ' 'AND (product_id IS NULL OR product_id = %s) ' 'AND (' + categ_where + ' OR (categ_id IS NULL)) ' 'AND price_version_id = %s ' 'AND (min_quantity IS NULL OR min_quantity <= %s) ' 'AND i.price_version_id = v.id AND v.pricelist_id = pl.id ' 'ORDER BY sequence', (tmpl_id, product_id, plversion_ids[0], qty)) res1 = cr.dictfetchall() uom_price_already_computed = False for res in res1: if res: if res['base'] == -1: if not res['base_pricelist_id']: price = 0.0 else: price_tmp = self.price_get(cr, uid, [res['base_pricelist_id']], product_id, qty, context=context)[res['base_pricelist_id']] ptype_src = self.browse(cr, uid, res['base_pricelist_id']).currency_id.id uom_price_already_computed = True price = currency_obj.compute(cr, uid, ptype_src, res['currency_id'], price_tmp, round=False) elif res['base'] == -2: # this section could be improved by moving the queries outside the loop: where = [] if partner: where = [('name', '=', partner) ] sinfo = supplierinfo_obj.search(cr, uid, [('product_id', '=', tmpl_id)] + where) price = 0.0 if sinfo: qty_in_product_uom = qty product_default_uom = product_template_obj.read(cr, uid, [tmpl_id], ['uom_id'])[0]['uom_id'][0] supplier = supplierinfo_obj.browse(cr, uid, sinfo, context=context)[0] seller_uom = supplier.product_uom and supplier.product_uom.id or False if seller_uom and product_default_uom and product_default_uom != seller_uom: uom_price_already_computed = True qty_in_product_uom = product_uom_obj._compute_qty(cr, uid, product_default_uom, qty, to_uom_id=seller_uom) cr.execute('SELECT * ' \ 'FROM pricelist_partnerinfo ' \ 'WHERE suppinfo_id IN %s' \ 'AND min_quantity <= %s ' \ 'ORDER BY min_quantity DESC LIMIT 1', (tuple(sinfo),qty_in_product_uom,)) res2 = cr.dictfetchone() if res2: price = res2['price'] else: price_type = price_type_obj.browse(cr, uid, int(res['base'])) uom_price_already_computed = True price = currency_obj.compute(cr, uid, price_type.currency_id.id, res['currency_id'], product_obj.price_get(cr, uid, [product_id], price_type.field, context=context)[product_id], round=False, context=context) if price is not False: price_limit = price price = price * (1.0+(res['price_discount'] or 0.0)) price = rounding(price, res['price_round']) price += (res['price_surcharge'] or 0.0) if res['price_min_margin']: price = max(price, price_limit+res['price_min_margin']) if res['price_max_margin']: price = min(price, price_limit+res['price_max_margin']) break else: # False means no valid line found ! But we may not raise an # exception here because it breaks the search price = False if price: results['item_id'] = res['id'] if 'uom' in context and not uom_price_already_computed: product = products_dict[product_id] uom = product.uos_id or product.uom_id price = self.pool.get('product.uom')._compute_price(cr, uid, uom.id, price, context['uom']) if results.get(product_id): results[product_id][pricelist_id] = price else: results[product_id] = {pricelist_id: price} return results
def commission_get_multi(self, cr, uid, pricelist_ids, products_by_qty_by_partner, merchandise_id=False, context=None): u"""Calcul de la commission en fonction des listes de prix. @param pricelist_ids: @param products_by_qty: @param partner: @param context: { 'date': Date of the pricelist (%Y-%m-%d),} @return: a dict of dict with product_id as key and a dict 'price by pricelist' as value """ def _create_parent_category_list(id, lst): if not id: return [] parent = product_category_tree.get(id) if parent: lst.append(parent) return _create_parent_category_list(parent, lst) else: return lst # _create_parent_category_list if context is None: context = {} date = time.strftime('%Y-%m-%d') if 'date' in context: date = context['date'] currency_obj = self.pool.get('res.currency') product_obj = self.pool.get('product.product') #product_template_obj = self.pool.get('product.template') product_category_obj = self.pool.get('product.category') product_uom_obj = self.pool.get('product.uom') supplierinfo_obj = self.pool.get('product.supplierinfo') price_type_obj = self.pool.get('product.price.type') # product.pricelist.version: if not pricelist_ids: pricelist_ids = self.pool.get('product.pricelist').search( cr, uid, [], context=context) pricelist_version_ids = self.pool.get( 'product.pricelist.version').search(cr, uid, [ ('pricelist_id', 'in', pricelist_ids), '|', ('date_start', '=', False), ('date_start', '<=', date), '|', ('date_end', '=', False), ('date_end', '>=', date), ]) if len(pricelist_ids) != len(pricelist_version_ids): raise osv.except_osv( _('Warning !'), _("At least one pricelist has no active version !\nPlease create or activate one." )) # product.product: product_ids = [i[0] for i in products_by_qty_by_partner] products = product_obj.browse(cr, uid, product_ids, context=context) products_dict = dict([(item.id, item) for item in products]) # product.category: product_category_ids = product_category_obj.search(cr, uid, []) product_categories = product_category_obj.read(cr, uid, product_category_ids, ['parent_id']) product_category_tree = dict([(item['id'], item['parent_id'][0]) for item in product_categories if item['parent_id']]) fixed = True commission_value_type = 0 results = {} for product_id, qty, partner in products_by_qty_by_partner: for pricelist_id in pricelist_ids: price = False commission = False #template _id tmpl_id = products_dict[ product_id].product_tmpl_id and products_dict[ product_id].product_tmpl_id.id or False categ_id = products_dict[product_id].categ_id and products_dict[ product_id].categ_id.id or False categ_ids = _create_parent_category_list(categ_id, [categ_id]) if categ_ids: categ_where = '(categ_id IN (' + ','.join( map(str, categ_ids)) + '))' else: categ_where = '(categ_id IS NULL)' if partner: partner_where = 'base <> -2 OR %s IN (SELECT name FROM product_supplierinfo WHERE product_id = %s) ' partner_args = (partner, tmpl_id) # product_id -> tmpl_id else: partner_where = 'base <> -2 ' partner_args = () cr.execute( 'SELECT i.*, pl.currency_id ' 'FROM product_pricelist_item AS i, ' 'product_pricelist_version AS v, product_pricelist AS pl ' 'WHERE (product_tmpl_id IS NULL OR product_tmpl_id = %s) ' 'AND (product_id IS NULL OR product_id = %s) ' 'AND (' + categ_where + ' OR (categ_id IS NULL)) ' 'AND (' + partner_where + ') ' 'AND price_version_id = %s ' 'AND (min_quantity IS NULL OR min_quantity <= %s) ' 'AND i.price_version_id = v.id AND v.pricelist_id = pl.id ' 'ORDER BY sequence', (tmpl_id, product_id) + partner_args + (pricelist_version_ids[0], qty)) res1 = cr.dictfetchall() uom_price_already_computed = False for res in res1: if res: ## calcul du prix if res['base'] == -1: if not res['base_pricelist_id']: price = 0.0 else: price_tmp = self.price_get( cr, uid, [res['base_pricelist_id']], product_id, qty, context=context)[res['base_pricelist_id']] ptype_src = self.browse( cr, uid, res['base_pricelist_id']).currency_id.id uom_price_already_computed = True price = currency_obj.compute( cr, uid, ptype_src, res['currency_id'], price_tmp, round=False, context=context) elif res['base'] == -2: # this section could be improved by moving the queries outside the loop: where = [] if partner: where = [('name', '=', partner)] sinfo = supplierinfo_obj.search( cr, uid, [('product_id', '=', tmpl_id)] + where) price = 0.0 if sinfo: qty_in_product_uom = qty product_default_uom = product_obj.read( cr, uid, [product_id], ['uom_id'])[0]['uom_id'][0] supplier = supplierinfo_obj.browse( cr, uid, sinfo, context=context)[0] seller_uom = supplier.product_uom and supplier.product_uom.id or False if seller_uom and product_default_uom and product_default_uom != seller_uom: uom_price_already_computed = True qty_in_product_uom = product_uom_obj._compute_qty( cr, uid, product_default_uom, qty, to_uom_id=seller_uom) cr.execute('SELECT * ' \ 'FROM pricelist_partnerinfo ' \ 'WHERE suppinfo_id IN %s' \ 'AND min_quantity <= %s ' \ 'ORDER BY min_quantity DESC LIMIT 1', (tuple(sinfo),qty_in_product_uom,)) res2 = cr.dictfetchone() if res2: price = res2['price'] else: price_type = price_type_obj.browse( cr, uid, int(res['base'])) uom_price_already_computed = True price = currency_obj.compute( cr, uid, price_type.currency_id.id, res['currency_id'], product_obj.price_get( cr, uid, [product_id], price_type.field, context=context)[product_id], round=False, context=context) if price is not False: price_limit = price price = price * (1.0 + (res['price_discount'] or 0.0)) price = rounding( price, res['price_round'] ) #TOFIX: rounding with tools.float_rouding price += (res['price_surcharge'] or 0.0) if res['price_min_margin']: price = max( price, price_limit + res['price_min_margin']) if res['price_max_margin']: price = min( price, price_limit + res['price_max_margin']) price_merchandise = self.pool.get( 'product.pricelist.item' ).get_total_price_merchandise( cr, uid, pricelist_version_ids[0], product_id, merchandise_id) if price_merchandise: price = price_merchandise if res['commission_ok'] == True: commission = 0 if res['fixed_commission_ok'] == True: commission_limit = commission object_product = product_obj.browse( cr, uid, product_id) if object_product: commission = object_product.rate_commission commission = commission * ( 1.0 + (res['price_discount_commission'] or 0.0)) commission = rounding( commission, res['price_round_commission'] ) #TOFIX: rounding with tools.float_rouding commission += ( res['price_surcharge_commission'] or 0.0) if res['price_min_margin_commission']: commission = max( commission, commission_limit + res['price_min_margin_commission'] ) if res['price_max_margin_commission']: commission = min( commission, commission_limit + res['price_max_margin_commission'] ) commission_value_type = commission break elif res['percent_commission_ok'] == True: fixed = False commission = ( price * res['percent_commission']) / 100 commission_value_type = res[ 'percent_commission'] else: object_product = product_obj.browse( cr, uid, product_id) data_commission = self.pool.get( 'product.product').get_base_commission( cr, uid, product_id) commission = data_commission['commission'] fixed = data_commission['fixed'] commission_value_type = data_commission[ 'commission_value_type'] else: price = False if price: results['item_id'] = res['id'] if 'uom' in context and not uom_price_already_computed: product = products_dict[product_id] uom = product.uos_id or product.uom_id price = product_uom_obj._compute_price( cr, uid, uom.id, price, context['uom']) commission = 0 object_product = product_obj.browse( cr, uid, product_id) price_merchandise = self.pool.get( 'product.pricelist.item' ).get_total_price_merchandise(cr, uid, pricelist_version_ids[0], product_id, merchandise_id) comission_merchandise = self.pool.get( 'product.pricelist.item' ).get_comission_merchandise(cr, uid, pricelist_version_ids[0], product_id, merchandise_id) if price_merchandise: price = price_merchandise if res['commission_ok'] == True: if res['fixed_commission_ok'] == True: commission_limit = commission fixed = True if object_product: commission = object_product.get_base_commission( cr, uid, object_product.id) commission = commission * ( 1.0 + (res['price_discount_commission'] or 0.0)) commission = rounding( commission, res['price_round_commission'] ) #TOFIX: rounding with tools.float_rouding commission += ( res['price_surcharge_commission'] or 0.0) if res['price_min_margin_commission']: commission = max( commission, commission_limit + res['price_min_margin_commission']) if res['price_max_margin_commission']: commission = min( commission, commission_limit + res['price_max_margin_commission']) break commission_value_type = commission elif res['percent_commission_ok'] == True: fixed = False commission = (price * res['percent_commission']) / 100 commission_value_type = res[ 'percent_commission'] else: data_commission = object_product.get_base_commission( cr, uid, object_product.id) commission = data_commission['commission'] fixed = data_commission['fixed'] commission_value_type = data_commission[ 'commission_value_type'] if results.get(product_id): results[product_id][pricelist_id] = { 'commission': commission, 'fixed': fixed, 'commission_value_type': commission_value_type, } else: results[product_id] = { pricelist_id: { 'commission': commission, 'fixed': fixed, 'commission_value_type': commission_value_type, } } return results
def price_get_multi_travel(self, cr, uid, pricelist_ids, products_by_qty_by_partner,merchandise_id=False, context=None): u"""Prix d'un trajet selon les listes de prix. @param pricelist_ids: @param merchandise_id: @param products_by_qty: @param partner: @param context: { 'date': Date of the pricelist (%Y-%m-%d),} @return: a dict of dict with product_id as key and a dict 'price by pricelist' as value """ list_product=[] def _create_parent_category_list(id, lst): if not id: return [] parent = product_category_tree.get(id) if parent: lst.append(parent) return _create_parent_category_list(parent, lst) else: return lst # _create_parent_category_list if context is None: context = {} date = context.get('date') or time.strftime('%Y-%m-%d') #if 'date' in context: # date = context['date'] currency_obj = self.pool.get('res.currency') product_obj = self.pool.get('product.product') #product_template_obj = self.pool.get('product.template') product_category_obj = self.pool.get('product.category') product_uom_obj = self.pool.get('product.uom') supplierinfo_obj = self.pool.get('product.supplierinfo') price_type_obj = self.pool.get('product.price.type') comission_merchandise=0 # product.pricelist.version: if not pricelist_ids: pricelist_ids = self.pool.get('product.pricelist').search(cr, uid, [], context=context) pricelist_version_ids = self.pool.get('product.pricelist.version').search(cr, uid, [ ('pricelist_id', 'in', pricelist_ids), '|', ('date_start', '=', False), ('date_start', '<=', date), '|', ('date_end', '=', False), ('date_end', '>=', date), ]) if len(pricelist_ids) != len(pricelist_version_ids): raise osv.except_osv(_('Attention !'), _(u"Il y'a au moins une liste de prix sans version active !\nVeuillez s'il vous plaît créer ou activer une.")) # product.product: product_ids = [i[0] for i in products_by_qty_by_partner] #products = dict([(item['id'], item) for item in product_obj.read(cr, uid, product_ids, ['categ_id', 'product_tmpl_id', 'uos_id', 'uom_id'])]) products = product_obj.browse(cr, uid, product_ids, context=context) products_dict = dict([(item.id, item) for item in products]) # product.category: product_category_ids = product_category_obj.search(cr, uid, []) product_categories = product_category_obj.read(cr, uid, product_category_ids, ['parent_id']) product_category_tree = dict([(item['id'], item['parent_id'][0]) for item in product_categories if item['parent_id']]) results = {} for product_id, qty, partner in products_by_qty_by_partner: for pricelist_id in pricelist_ids: price = False tmpl_id = products_dict[product_id].product_tmpl_id and products_dict[product_id].product_tmpl_id.id or False categ_id = products_dict[product_id].categ_id and products_dict[product_id].categ_id.id or False categ_ids = _create_parent_category_list(categ_id, [categ_id]) if categ_ids: categ_where = '(categ_id IN (' + ','.join(map(str, categ_ids)) + '))' else: categ_where = '(categ_id IS NULL)' if partner: partner_where = 'base <> -2 OR %s IN (SELECT name FROM product_supplierinfo WHERE product_id = %s) ' partner_args = (partner, tmpl_id) # product_id -> tmpl_id else: partner_where = 'base <> -2 ' partner_args = () if tmpl_id: cr.execute( 'SELECT i.*, pl.currency_id ' 'FROM product_pricelist_item AS i, ' 'product_pricelist_version AS v, product_pricelist AS pl ' 'WHERE (product_tmpl_id IS NULL OR product_tmpl_id = %s) ' 'AND (product_id IS NULL OR product_id = %s) ' 'AND (' + categ_where + ' OR (categ_id IS NULL)) ' 'AND (' + partner_where + ') ' 'AND price_version_id = %s ' 'AND (min_quantity IS NULL OR min_quantity <= %s) ' 'AND i.price_version_id = v.id AND v.pricelist_id = pl.id ' 'ORDER BY sequence', (tmpl_id, product_id) + partner_args + (pricelist_version_ids[0], qty)) res1 = cr.dictfetchall() uom_price_already_computed = False for res in res1: if res: if res['base'] == -1: if not res['base_pricelist_id']: price = 0.0 else: price_tmp = self.price_get(cr, uid, [res['base_pricelist_id']], product_id, qty, context=context)[res['base_pricelist_id']] ptype_src = self.browse(cr, uid, res['base_pricelist_id']).currency_id.id uom_price_already_computed = True price = currency_obj.compute(cr, uid, ptype_src, res['currency_id'], price_tmp, round=False, context=context) elif res['base'] == -2: # this section could be improved by moving the queries outside the loop: where = [] if partner: where = [('name', '=', partner) ] sinfo = supplierinfo_obj.search(cr, uid, [('product_id', '=', tmpl_id)] + where) price = 0.0 if sinfo: qty_in_product_uom = qty product_default_uom = product_obj.read(cr, uid, [product_id], ['uom_id'])[0]['uom_id'][0] supplier = supplierinfo_obj.browse(cr, uid, sinfo, context=context)[0] seller_uom = supplier.product_uom and supplier.product_uom.id or False if seller_uom and product_default_uom and product_default_uom != seller_uom: uom_price_already_computed = True qty_in_product_uom = product_uom_obj._compute_qty(cr, uid, product_default_uom, qty, to_uom_id=seller_uom) cr.execute('SELECT * ' \ 'FROM pricelist_partnerinfo ' \ 'WHERE suppinfo_id IN %s' \ 'AND min_quantity <= %s ' \ 'ORDER BY min_quantity DESC LIMIT 1', (tuple(sinfo),qty_in_product_uom,)) res2 = cr.dictfetchone() if res2: price = res2['price'] else: price_type = price_type_obj.browse(cr, uid, int(res['base'])) uom_price_already_computed = True price = currency_obj.compute(cr, uid, price_type.currency_id.id, res['currency_id'], product_obj.price_get(cr, uid, [product_id], price_type.field, context=context)[product_id], round=False, context=context) if price is not False: price_limit = price price = price * (1.0+(res['price_discount'] or 0.0)) price = rounding(price, res['price_round']) #TOFIX: rounding with tools.float_rouding price += (res['price_surcharge'] or 0.0) if res['price_min_margin']: price = max(price, price_limit+res['price_min_margin']) if res['price_max_margin']: price = min(price, price_limit+res['price_max_margin']) price_merchandise=self.pool.get('product.pricelist.item').get_total_price_merchandise(cr,uid,pricelist_version_ids[0],product_id,merchandise_id) comission_merchandise=self.pool.get('product.pricelist.item').get_comission_merchandise(cr,uid,pricelist_version_ids[0],product_id,merchandise_id) comission_is_fixes= self.pool.get('product.pricelist.item').get_comission_is_fixed(cr,uid,pricelist_version_ids[0],product_id,merchandise_id) comission_fixe= self.pool.get('product.pricelist.item').get_comission_fixe(cr,uid,pricelist_version_ids[0],product_id,merchandise_id) if price_merchandise: price = price_merchandise comission=comission_merchandise break else: # False means no valid line found ! But we may not raise an # exception here because it breaks the search price = False if price: results['item_id'] = res['id'] if 'uom' in context and not uom_price_already_computed: product = products_dict[product_id] uom = product.uos_id or product.uom_id price = product_uom_obj._compute_price(cr, uid, uom.id, price, context['uom']) price_merchandise=self.pool.get('product.pricelist.item').get_total_price_merchandise(cr,uid,pricelist_version_ids[0],product_id,merchandise_id) comission_merchandise=self.pool.get('product.pricelist.item').get_comission_merchandise(cr,uid,pricelist_version_ids[0],product_id,merchandise_id) comission_is_fixes= self.pool.get('product.pricelist.item').get_comission_is_fixed(cr,uid,pricelist_version_ids[0],product_id,merchandise_id) comission_fixe= self.pool.get('product.pricelist.item').get_comission_fixe(cr,uid,pricelist_version_ids[0],product_id,merchandise_id) if price_merchandise: price = price_merchandise if results.get(product_id): results[product_id][pricelist_id] = price else: results['comission_merchandise']=comission_merchandise try : results['comission_is_fixe']=comission_is_fixes results['comission_fixe']=comission_fixe except : pass results[product_id] = {pricelist_id: price} return results
def commission_get_multi(self, cr, uid, pricelist_ids, products_by_qty_by_partner,merchandise_id=False, context=None): u"""Calcul de la commission en fonction des listes de prix. @param pricelist_ids: @param products_by_qty: @param partner: @param context: { 'date': Date of the pricelist (%Y-%m-%d),} @return: a dict of dict with product_id as key and a dict 'price by pricelist' as value """ def _create_parent_category_list(id, lst): if not id: return [] parent = product_category_tree.get(id) if parent: lst.append(parent) return _create_parent_category_list(parent, lst) else: return lst # _create_parent_category_list if context is None: context = {} date = time.strftime('%Y-%m-%d') if 'date' in context: date = context['date'] currency_obj = self.pool.get('res.currency') product_obj = self.pool.get('product.product') #product_template_obj = self.pool.get('product.template') product_category_obj = self.pool.get('product.category') product_uom_obj = self.pool.get('product.uom') supplierinfo_obj = self.pool.get('product.supplierinfo') price_type_obj = self.pool.get('product.price.type') # product.pricelist.version: if not pricelist_ids: pricelist_ids = self.pool.get('product.pricelist').search(cr, uid, [], context=context) pricelist_version_ids = self.pool.get('product.pricelist.version').search(cr, uid, [ ('pricelist_id', 'in', pricelist_ids), '|', ('date_start', '=', False), ('date_start', '<=', date), '|', ('date_end', '=', False), ('date_end', '>=', date), ]) if len(pricelist_ids) != len(pricelist_version_ids): raise osv.except_osv(_('Warning !'), _("At least one pricelist has no active version !\nPlease create or activate one.")) # product.product: product_ids = [i[0] for i in products_by_qty_by_partner] products = product_obj.browse(cr, uid, product_ids, context=context) products_dict = dict([(item.id, item) for item in products]) # product.category: product_category_ids = product_category_obj.search(cr, uid, []) product_categories = product_category_obj.read(cr, uid, product_category_ids, ['parent_id']) product_category_tree = dict([(item['id'], item['parent_id'][0]) for item in product_categories if item['parent_id']]) fixed=True commission_value_type=0 results = {} for product_id, qty, partner in products_by_qty_by_partner: for pricelist_id in pricelist_ids: price = False commission=False #template _id tmpl_id = products_dict[product_id].product_tmpl_id and products_dict[product_id].product_tmpl_id.id or False categ_id = products_dict[product_id].categ_id and products_dict[product_id].categ_id.id or False categ_ids = _create_parent_category_list(categ_id, [categ_id]) if categ_ids: categ_where = '(categ_id IN (' + ','.join(map(str, categ_ids)) + '))' else: categ_where = '(categ_id IS NULL)' if partner: partner_where = 'base <> -2 OR %s IN (SELECT name FROM product_supplierinfo WHERE product_id = %s) ' partner_args = (partner, tmpl_id) # product_id -> tmpl_id else: partner_where = 'base <> -2 ' partner_args = () cr.execute( 'SELECT i.*, pl.currency_id ' 'FROM product_pricelist_item AS i, ' 'product_pricelist_version AS v, product_pricelist AS pl ' 'WHERE (product_tmpl_id IS NULL OR product_tmpl_id = %s) ' 'AND (product_id IS NULL OR product_id = %s) ' 'AND (' + categ_where + ' OR (categ_id IS NULL)) ' 'AND (' + partner_where + ') ' 'AND price_version_id = %s ' 'AND (min_quantity IS NULL OR min_quantity <= %s) ' 'AND i.price_version_id = v.id AND v.pricelist_id = pl.id ' 'ORDER BY sequence', (tmpl_id, product_id) + partner_args + (pricelist_version_ids[0], qty)) res1 = cr.dictfetchall() uom_price_already_computed = False for res in res1: if res:## calcul du prix if res['base'] == -1: if not res['base_pricelist_id']: price = 0.0 else: price_tmp = self.price_get(cr, uid, [res['base_pricelist_id']], product_id, qty, context=context)[res['base_pricelist_id']] ptype_src = self.browse(cr, uid, res['base_pricelist_id']).currency_id.id uom_price_already_computed = True price = currency_obj.compute(cr, uid, ptype_src, res['currency_id'], price_tmp, round=False, context=context) elif res['base'] == -2: # this section could be improved by moving the queries outside the loop: where = [] if partner: where = [('name', '=', partner) ] sinfo = supplierinfo_obj.search(cr, uid, [('product_id', '=', tmpl_id)] + where) price = 0.0 if sinfo: qty_in_product_uom = qty product_default_uom = product_obj.read(cr, uid, [product_id], ['uom_id'])[0]['uom_id'][0] supplier = supplierinfo_obj.browse(cr, uid, sinfo, context=context)[0] seller_uom = supplier.product_uom and supplier.product_uom.id or False if seller_uom and product_default_uom and product_default_uom != seller_uom: uom_price_already_computed = True qty_in_product_uom = product_uom_obj._compute_qty(cr, uid, product_default_uom, qty, to_uom_id=seller_uom) cr.execute('SELECT * ' \ 'FROM pricelist_partnerinfo ' \ 'WHERE suppinfo_id IN %s' \ 'AND min_quantity <= %s ' \ 'ORDER BY min_quantity DESC LIMIT 1', (tuple(sinfo),qty_in_product_uom,)) res2 = cr.dictfetchone() if res2: price = res2['price'] else: price_type = price_type_obj.browse(cr, uid, int(res['base'])) uom_price_already_computed = True price = currency_obj.compute(cr, uid, price_type.currency_id.id, res['currency_id'], product_obj.price_get(cr, uid, [product_id], price_type.field, context=context)[product_id], round=False, context=context) if price is not False: price_limit = price price = price * (1.0+(res['price_discount'] or 0.0)) price = rounding(price, res['price_round']) #TOFIX: rounding with tools.float_rouding price += (res['price_surcharge'] or 0.0) if res['price_min_margin']: price = max(price, price_limit+res['price_min_margin']) if res['price_max_margin']: price = min(price, price_limit+res['price_max_margin']) price_merchandise=self.pool.get('product.pricelist.item').get_total_price_merchandise(cr,uid,pricelist_version_ids[0],product_id,merchandise_id) if price_merchandise: price = price_merchandise if res['commission_ok'] == True: commission = 0 if res['fixed_commission_ok'] == True: commission_limit = commission object_product=product_obj.browse(cr,uid,product_id) if object_product: commission=object_product.rate_commission commission = commission * (1.0+(res['price_discount_commission'] or 0.0)) commission = rounding(commission, res['price_round_commission']) #TOFIX: rounding with tools.float_rouding commission += (res['price_surcharge_commission'] or 0.0) if res['price_min_margin_commission']: commission = max(commission, commission_limit+res['price_min_margin_commission']) if res['price_max_margin_commission']: commission = min(commission, commission_limit+res['price_max_margin_commission']) commission_value_type=commission break elif res['percent_commission_ok'] == True: fixed=False commission=(price*res['percent_commission']) / 100 commission_value_type = res['percent_commission'] else: object_product=product_obj.browse(cr,uid,product_id) data_commission=self.pool.get('product.product').get_base_commission(cr,uid,product_id) commission = data_commission['commission'] fixed = data_commission['fixed'] commission_value_type = data_commission['commission_value_type'] else: price = False if price: results['item_id'] = res['id'] if 'uom' in context and not uom_price_already_computed: product = products_dict[product_id] uom = product.uos_id or product.uom_id price = product_uom_obj._compute_price(cr, uid, uom.id, price, context['uom']) commission = 0 object_product=product_obj.browse(cr,uid,product_id) price_merchandise=self.pool.get('product.pricelist.item').get_total_price_merchandise(cr,uid,pricelist_version_ids[0],product_id,merchandise_id) comission_merchandise=self.pool.get('product.pricelist.item').get_comission_merchandise(cr,uid,pricelist_version_ids[0],product_id,merchandise_id) if price_merchandise: price = price_merchandise if res['commission_ok'] == True: if res['fixed_commission_ok'] == True: commission_limit = commission fixed=True if object_product: commission=object_product.get_base_commission(cr,uid,object_product.id) commission = commission * (1.0+(res['price_discount_commission'] or 0.0)) commission = rounding(commission, res['price_round_commission']) #TOFIX: rounding with tools.float_rouding commission += (res['price_surcharge_commission'] or 0.0) if res['price_min_margin_commission']: commission = max(commission, commission_limit+res['price_min_margin_commission']) if res['price_max_margin_commission']: commission = min(commission, commission_limit+res['price_max_margin_commission']) break commission_value_type=commission elif res['percent_commission_ok'] == True: fixed=False commission=(price*res['percent_commission']) / 100 commission_value_type = res['percent_commission'] else: data_commission=object_product.get_base_commission(cr,uid,object_product.id) commission = data_commission['commission'] fixed = data_commission['fixed'] commission_value_type = data_commission['commission_value_type'] if results.get(product_id): results[product_id][pricelist_id] = { 'commission' : commission, 'fixed' : fixed, 'commission_value_type' : commission_value_type, } else: results[product_id] = {pricelist_id: { 'commission' : commission, 'fixed' : fixed, 'commission_value_type' : commission_value_type, }} return results
def product_id_change( self, cr, uid, ids, pricelist, product, qty=0, uom=False, qty_uos=0, uos=False, name="", partner_id=False, lang=False, update_tax=True, date_order=False, packaging=False, fiscal_position=False, flag=False, context=None, ): if context is None: context = {} if not product: return { "value": {"th_weight": 0, "product_packaging": False, "product_uos_qty": qty, "tax_id": []}, "domain": {"product_uom": [], "product_uos": []}, } res = {} res = super(sale_order_line, self).product_id_change( cr, uid, ids, pricelist, product, qty, uom, qty_uos, uos, name, partner_id, lang, update_tax, date_order, packaging, fiscal_position, flag, ) product_obj = self.pool.get("product.product") pricelist_obj = self.pool.get("product.pricelist") prod = product_obj.browse(cr, uid, product, context=context) qty = qty or 0.0 if not uom or uom <> prod.uom_id.id: uom = prod.uom_id.id if not uos: uos = prod.uos_id.id price = pricelist_obj.price_get( cr, uid, [pricelist], product, qty or 1.0, partner_id, dict(context, uom=uom or res.get("product_uom"), date=date_order), )[pricelist] try: price = price * prod.coef_amount except ZeroDivisionError: pass if prod.coef_amount: uos_qty = qty / prod.coef_amount else: uos_qty = qty uos_qty = rounding(uos_qty, prod.uos_id.rounding) qty = rounding(qty, prod.uom_id.rounding) res["value"]["product_uom"] = uom res["value"]["product_uom_qty"] = qty res["value"]["product_uos"] = uos res["value"]["product_uos_qty"] = uos_qty res["value"]["secondary_price"] = price value = res["value"] if value.get("tax_id") == False: value.update({"tax_id": value.get("taxes_id")}) res.update({"value": value}) return res
def price_get_multi_lastinvoice(self, cr, uid, pricelist_ids, products_by_qty_by_partner, basefieldname="base", context=None): """multi products 'price_get'. @param pricelist_ids: @param products_by_qty: @param partner: @param basefieldname: @param context: { 'date': Date of the pricelist (%Y-%m-%d),} @return: a dict of dict with product_id as key and a dict 'price by pricelist' as value """ #basefieldname='base' def _create_parent_category_list(id, lst): if not id: return [] parent = product_category_tree.get(id) if parent: lst.append(parent) return _create_parent_category_list(parent, lst) else: return lst # _create_parent_category_list if context is None: context = {} date = time.strftime('%Y-%m-%d') if 'date' in context: date = context['date'] currency_obj = self.pool.get('res.currency') product_obj = self.pool.get('product.product') product_category_obj = self.pool.get('product.category') product_uom_obj = self.pool.get('product.uom') supplierinfo_obj = self.pool.get('product.supplierinfo') price_type_obj = self.pool.get('product.price.type') # product.pricelist.version: if not pricelist_ids: pricelist_ids = self.pool.get('product.pricelist').search( cr, uid, [], context=context) pricelist_version_ids = self.pool.get( 'product.pricelist.version').search(cr, uid, [ ('pricelist_id', 'in', pricelist_ids), '|', ('date_start', '=', False), ('date_start', '<=', date), '|', ('date_end', '=', False), ('date_end', '>=', date), ]) if len(pricelist_ids) != len(pricelist_version_ids): raise osv.except_osv( _('Warning!'), _("At least one pricelist has no active version !\nPlease create or activate one." )) # product.product: product_ids = [i[0] for i in products_by_qty_by_partner] #products = dict([(item['id'], item) for item in product_obj.read(cr, uid, product_ids, ['categ_id', 'product_tmpl_id', 'uos_id', 'uom_id'])]) products = product_obj.browse(cr, uid, product_ids, context=context) products_dict = dict([(item.id, item) for item in products]) # product.category: product_category_ids = product_category_obj.search(cr, uid, []) product_categories = product_category_obj.read(cr, uid, product_category_ids, ['parent_id']) product_category_tree = dict([(item['id'], item['parent_id'][0]) for item in product_categories if item['parent_id']]) results = {} for product_id, qty, partner in products_by_qty_by_partner: for pricelist_id in pricelist_ids: price = False tmpl_id = product_id and products_dict[ product_id].product_tmpl_id and products_dict[ product_id].product_tmpl_id.id or False categ_id = product_id and products_dict[ product_id].categ_id and products_dict[ product_id].categ_id.id or False categ_ids = _create_parent_category_list(categ_id, [categ_id]) if categ_ids: categ_where = '(categ_id IN (' + ','.join( map(str, categ_ids)) + '))' else: categ_where = '(categ_id IS NULL)' if partner: partner_where = basefieldname + ' <> -2 OR %s IN (SELECT name FROM product_supplierinfo WHERE product_id = %s) ' partner_args = (partner, tmpl_id) else: partner_where = basefieldname + ' <> -2 ' partner_args = () cr.execute( 'SELECT i.*, pl.currency_id ' 'FROM product_pricelist_item AS i, ' 'product_pricelist_version AS v, product_pricelist AS pl ' 'WHERE (product_tmpl_id IS NULL OR product_tmpl_id = %s) ' 'AND (product_id IS NULL OR product_id = %s) ' 'AND (' + categ_where + ' OR (categ_id IS NULL)) ' 'AND (' + partner_where + ') ' 'AND price_version_id = %s ' 'AND (min_quantity IS NULL OR min_quantity <= %s) ' 'AND i.price_version_id = v.id AND v.pricelist_id = pl.id ' 'ORDER BY sequence', (tmpl_id, product_id) + partner_args + (pricelist_version_ids[0], qty)) res1 = cr.dictfetchall() uom_price_already_computed = False for res in res1: if res: if res[basefieldname] == -10: # Partner's last invoice price price = 0.0 product_default_uom = product_obj.read( cr, uid, [product_id], ['uom_id'])[0]['uom_id'][0] cr.execute( "select i.partner_id, il.product_id, il.price_unit, il.uos_id \ from account_invoice i \ inner join account_invoice_line il on il.invoice_id = i.id \ inner join product_uom uom on uom.id = il.uos_id \ where state not in ('draft','cancel') \ and il.product_id = %s \ and i.partner_id = %s \ order by i.write_date desc limit 1", ( product_id, partner or -1, )) res2 = cr.dictfetchone() if res2: line_uom = res2['uos_id'] if line_uom and product_default_uom and product_default_uom != line_uom: uom_price_already_computed = True price = product_uom_obj._compute_price( cr, uid, line_uom, res2['price_unit'], product_default_uom) else: price = res2['price_unit'] else: return False if price is not False: price_limit = price price = price * (1.0 + (res['price_discount'] or 0.0)) price = rounding( price, res['price_round'] ) #TOFIX: rounding with tools.float_rouding price += (res['price_surcharge'] or 0.0) if res['price_min_margin']: price = max( price, price_limit + res['price_min_margin']) if res['price_max_margin']: price = min( price, price_limit + res['price_max_margin']) break else: # False means no valid line found ! But we may not raise an # exception here because it breaks the search price = False if price: results['item_id'] = res['id'] if 'uom' in context and not uom_price_already_computed: product = products_dict[product_id] uom = product.uos_id or product.uom_id price = product_uom_obj._compute_price( cr, uid, uom.id, price, context['uom']) if results.get(product_id): results[product_id][pricelist_id] = price else: results[product_id] = {pricelist_id: price} return results
def price_get_old(self, cr, uid, ids, prod_id, qty, partner=None, context=None): ''' context = { 'uom': Unit of Measure (int), 'partner': Partner ID (int), 'date': Date of the pricelist (%Y-%m-%d), } ''' price = False item_id = 0 if context is None: context = {} currency_obj = self.pool.get('res.currency') product_obj = self.pool.get('product.product') supplierinfo_obj = self.pool.get('product.supplierinfo') price_type_obj = self.pool.get('product.price.type') if context and ('partner_id' in context): partner = context['partner_id'] context['partner_id'] = partner date = time.strftime('%Y-%m-%d') if context and ('date' in context): date = context['date'] result = {} result['item_id'] = {} for id in ids: cr.execute('SELECT * ' \ 'FROM product_pricelist_version ' \ 'WHERE pricelist_id = %s AND active=True ' \ 'AND (date_start IS NULL OR date_start <= %s) ' \ 'AND (date_end IS NULL OR date_end >= %s) ' \ 'ORDER BY id LIMIT 1', (id, date, date)) plversion = cr.dictfetchone() if not plversion: raise osv.except_osv(_('Warning !'), _('No active version for the selected pricelist !\n' \ 'Please create or activate one.')) cr.execute('SELECT id, categ_id ' \ 'FROM product_template ' \ 'WHERE id = (SELECT product_tmpl_id ' \ 'FROM product_product ' \ 'WHERE id = %s)', (prod_id,)) tmpl_id, categ = cr.fetchone() categ_ids = [] while categ: categ_ids.append(str(categ)) cr.execute('SELECT parent_id ' \ 'FROM product_category ' \ 'WHERE id = %s', (categ,)) categ = cr.fetchone()[0] if str(categ) in categ_ids: raise osv.except_osv(_('Warning !'), _('Could not resolve product category, ' \ 'you have defined cyclic categories ' \ 'of products!')) if categ_ids: categ_where = '(categ_id IN (' + ','.join(categ_ids) + '))' else: categ_where = '(categ_id IS NULL)' cr.execute( 'SELECT i.*, pl.currency_id ' 'FROM product_pricelist_item AS i, ' 'product_pricelist_version AS v, product_pricelist AS pl ' 'WHERE (product_tmpl_id IS NULL OR product_tmpl_id = %s) ' 'AND (product_id IS NULL OR product_id = %s) ' 'AND (' + categ_where + ' OR (categ_id IS NULL)) ' 'AND price_version_id = %s ' 'AND (min_quantity IS NULL OR min_quantity <= %s) ' 'AND i.price_version_id = v.id AND v.pricelist_id = pl.id ' 'ORDER BY sequence', (tmpl_id, prod_id, plversion['id'], qty)) res1 = cr.dictfetchall() for res in res1: item_id = 0 if res: if res['base'] == -1: if not res['base_pricelist_id']: price = 0.0 else: price_tmp = self.price_get(cr, uid, [res['base_pricelist_id']], prod_id, qty,context=context)[res['base_pricelist_id']] ptype_src = self.browse(cr, uid, res['base_pricelist_id']).currency_id.id price = currency_obj.compute(cr, uid, ptype_src, res['currency_id'], price_tmp, round=False) break elif res['base'] == -2: where = [] if partner: where = [('name', '=', partner) ] sinfo = supplierinfo_obj.search(cr, uid, [('product_id', '=', tmpl_id)] + where) price = 0.0 if sinfo: cr.execute('SELECT * ' \ 'FROM pricelist_partnerinfo ' \ 'WHERE suppinfo_id IN %s' \ 'AND min_quantity <= %s ' \ 'ORDER BY min_quantity DESC LIMIT 1', (tuple(sinfo),qty,)) res2 = cr.dictfetchone() if res2: price = res2['price'] break else: price_type = price_type_obj.browse(cr, uid, int(res['base'])) price = currency_obj.compute(cr, uid, price_type.currency_id.id, res['currency_id'], product_obj.price_get(cr, uid, [prod_id], price_type.field,context=context)[prod_id], round=False, context=context) if price: price_limit = price price = price * (1.0+(res['price_discount'] or 0.0)) price = rounding(price, res['price_round']) price += (res['price_surcharge'] or 0.0) if res['price_min_margin']: price = max(price, price_limit+res['price_min_margin']) if res['price_max_margin']: price = min(price, price_limit+res['price_max_margin']) item_id = res['id'] break else: # False means no valid line found ! But we may not raise an # exception here because it breaks the search price = False result[id] = price result['item_id'] = {id: item_id} if context and ('uom' in context): product = product_obj.browse(cr, uid, prod_id) uom = product.uos_id or product.uom_id result[id] = self.pool.get('product.uom')._compute_price(cr, uid, uom.id, result[id], context['uom']) return result
def price_get_multi(self, cr, uid, pricelist_ids, products_by_qty_by_partner, context=None): """multi products 'price_get'. @param pricelist_ids: @param products_by_qty: @param partner: @param context: { 'date': Date of the pricelist (%Y-%m-%d),} @return: a dict of dict with product_id as key and a dict 'price by pricelist' as value """ def _create_parent_category_list(id, lst): if not id: return [] parent = product_category_tree.get(id) if parent: lst.append(parent) return _create_parent_category_list(parent, lst) else: return lst def _create_parent_pricecategory_list(id, lst): if not id: return [] parent = product_pricecategory_tree.get(id) if parent: lst.append(parent) return _create_parent_pricecategory_list(parent, lst) else: return lst if context is None: context = {} date = time.strftime('%Y-%m-%d') if 'date' in context: date = context['date'] currency_obj = self.pool.get('res.currency') product_obj = self.pool.get('product.product') product_template_obj = self.pool.get('product.template') product_category_obj = self.pool.get('product.category') product_uom_obj = self.pool.get('product.uom') supplierinfo_obj = self.pool.get('product.supplierinfo') price_type_obj = self.pool.get('product.price.type') product_pricecategory_obj = self.pool.get('product.pricecategory') product_pricelist_version_obj = self.pool.get('product.pricelist.version') # product.pricelist.version: if pricelist_ids: pricelist_version_ids = pricelist_ids else: # all pricelists: pricelist_version_ids = self.pool.get('product.pricelist').search(cr, uid, [], context=context) pricelist_version_ids = list(set(pricelist_version_ids)) plversions_search_args = [ ('pricelist_id', 'in', pricelist_version_ids), '|', ('date_start', '=', False), ('date_start', '<=', date), '|', ('date_end', '=', False), ('date_end', '>=', date), ] plversion_ids = product_pricelist_version_obj.search(cr, uid, plversions_search_args) if len(pricelist_version_ids) != len(plversion_ids): raise osv.except_osv(_('Warning !'), _("At least one pricelist has no active version !\nPlease create or activate one.")) # product.product: product_ids = [i[0] for i in products_by_qty_by_partner] #products = dict([(item['id'], item) for item in product_obj.read(cr, uid, product_ids, ['categ_id', 'product_tmpl_id', 'uos_id', 'uom_id'])]) products = product_obj.browse(cr, uid, product_ids, context=context) products_dict = dict([(item.id, item) for item in products]) # product.category: product_category_ids = product_category_obj.search(cr, uid, []) product_categories = product_category_obj.read(cr, uid, product_category_ids, ['parent_id']) product_category_tree = dict([(item['id'], item['parent_id'][0]) for item in product_categories if item['parent_id']]) product_pricecategory_ids = product_pricecategory_obj.search(cr, uid, []) product_pricecategories = product_category_obj.read(cr, uid, product_pricecategory_ids, ['parent_id']) product_pricecategory_tree = dict([(item['id'], item['parent_id'][0]) for item in product_pricecategories if item['parent_id']]) results = {} for product_id, qty, partner in products_by_qty_by_partner: for pricelist_id in pricelist_version_ids: price = False tmpl_id = products_dict[product_id].product_tmpl_id and products_dict[product_id].product_tmpl_id.id or False categ_id = products_dict[product_id].categ_id and products_dict[product_id].categ_id.id or False categ_ids = _create_parent_category_list(categ_id, [categ_id]) if categ_ids: categ_where = '(categ_id IN (' + ','.join(map(str, categ_ids)) + '))' else: categ_where = '(categ_id IS NULL)' #jon pricecategory_ids comes from product.price_category_id # why need function _create_parent_pricecategory_list? pricecategory_ids = None p = products_dict[product_id] if p.pricecategory_id: pricecategory_ids = [p.pricecategory_id.id] if pricecategory_ids: # jon search pricelist_item , pricecategory_id == product.pricecategory_id or pricecategory_id == False pricecateg_where = '(pricecategory_id IN (' + ','.join(map(str, pricecategory_ids)) + ') OR pricecategory_id IS NULL)' else: pricecateg_where = '(pricecategory_id IS NULL)' cr.execute( 'SELECT i.*, pl.currency_id ' 'FROM product_pricelist_item AS i, ' 'product_pricelist_version AS v, product_pricelist AS pl ' 'WHERE (product_tmpl_id IS NULL OR product_tmpl_id = %s) ' 'AND (product_id IS NULL OR product_id = %s) ' 'AND (' + categ_where + ' OR (categ_id IS NULL)) ' # 'AND (' + pricecateg_where + ' OR (pricecategory_id IS NULL)) ' 'AND (' + pricecateg_where + ')' 'AND price_version_id = %s ' 'AND (min_quantity IS NULL OR min_quantity <= %s) ' 'AND i.price_version_id = v.id AND v.pricelist_id = pl.id ' 'ORDER BY i.pricecategory_id ,sequence', (tmpl_id, product_id, plversion_ids[0], qty)) res1 = cr.dictfetchall() uom_price_already_computed = False for res in res1: if res: if res['base'] == -1: if not res['base_pricelist_id']: price = 0.0 else: price_tmp = self.price_get(cr, uid, [res['base_pricelist_id']], product_id, qty, context=context)[res['base_pricelist_id']] ptype_src = self.browse(cr, uid, res['base_pricelist_id']).currency_id.id price = currency_obj.compute(cr, uid, ptype_src, res['currency_id'], price_tmp, round=False) elif res['base'] == -2: # this section could be improved by moving the queries outside the loop: where = [] if partner: where = [('name', '=', partner) ] sinfo = supplierinfo_obj.search(cr, uid, [('product_id', '=', tmpl_id)] + where) price = 0.0 if sinfo: qty_in_product_uom = qty product_default_uom = product_template_obj.read(cr, uid, [tmpl_id], ['uom_id'])[0]['uom_id'][0] supplier = supplierinfo_obj.browse(cr, uid, sinfo, context=context)[0] seller_uom = supplier.product_uom and supplier.product_uom.id or False supplier_currency = supplier.company_id and supplier.company_id.currency_id.id or False if seller_uom and product_default_uom and product_default_uom != seller_uom: uom_price_already_computed = True qty_in_product_uom = product_uom_obj._compute_qty(cr, uid, product_default_uom, qty, to_uom_id=seller_uom) cr.execute(""" SELECT * FROM pricelist_partnerinfo WHERE suppinfo_id IN %s AND min_quantity <= %s ORDER BY min_quantity DESC LIMIT 1 """, (tuple(sinfo),qty_in_product_uom,)) res2 = cr.dictfetchone() if res2: price = currency_obj.compute(cr, uid, supplier_currency, res['currency_id'], res2['price'], round=False, context=context) else: price_type = price_type_obj.browse(cr, uid, int(res['base'])) price = currency_obj.compute(cr, uid, price_type.currency_id.id, res['currency_id'], product_obj.price_get(cr, uid, [product_id], price_type.field,context=context)[product_id], round=False, context=context) uom_price_already_computed = True if price is not False: price_limit = price price = price * (1.0 + (res['price_discount'] or 0.0)) price = rounding(price, res['price_round']) price += (res['price_surcharge'] or 0.0) if res['price_min_margin']: price = max(price, price_limit + res['price_min_margin']) if res['price_max_margin']: price = min(price, price_limit + res['price_max_margin']) break else: # False means no valid line found ! But we may not raise an # exception here because it breaks the search price = False if price: if 'uom' in context and not uom_price_already_computed: product = products_dict[product_id] uom = product.uos_id or product.uom_id price = self.pool.get('product.uom')._compute_price(cr, uid, uom.id, price, context['uom']) if results.get(product_id): results[product_id][pricelist_id] = price else: results[product_id] = {pricelist_id: price} return results
def price_get_multi(self, cr, uid, pricelist_ids, products_by_qty_by_partner, context=None): """multi products 'price_get'. @param pricelist_ids: @param products_by_qty: @param partner: @param context: { 'date': Date of the pricelist (%Y-%m-%d),} @return: a dict of dict with product_id as key and a dict 'price by pricelist' as value """ def _create_parent_category_list(id, lst): if not id: return [] parent = product_category_tree.get(id) if parent: lst.append(parent) return _create_parent_category_list(parent, lst) else: return lst # _create_parent_category_list if context is None: context = {} date = time.strftime("%Y-%m-%d") if "date" in context: date = context["date"] currency_obj = self.pool.get("res.currency") product_obj = self.pool.get("product.product") product_category_obj = self.pool.get("product.category") product_uom_obj = self.pool.get("product.uom") supplierinfo_obj = self.pool.get("product.supplierinfo") price_type_obj = self.pool.get("product.price.type") # product.pricelist.version: if not pricelist_ids: pricelist_ids = self.pool.get("product.pricelist").search(cr, uid, [], context=context) pricelist_version_ids = self.pool.get("product.pricelist.version").search( cr, uid, [ ("pricelist_id", "in", pricelist_ids), "|", ("date_start", "=", False), ("date_start", "<=", date), "|", ("date_end", "=", False), ("date_end", ">=", date), ], ) if len(pricelist_ids) != len(pricelist_version_ids): raise osv.except_osv( _("Warning!"), _("At least one pricelist has no active version !\nPlease create or activate one.") ) # product.product: product_ids = [i[0] for i in products_by_qty_by_partner] # products = dict([(item['id'], item) for item in product_obj.read(cr, uid, product_ids, ['categ_id', 'product_tmpl_id', 'uos_id', 'uom_id'])]) products = product_obj.browse(cr, uid, product_ids, context=context) products_dict = dict([(item.id, item) for item in products]) # product.category: product_category_ids = product_category_obj.search(cr, uid, []) product_categories = product_category_obj.read(cr, uid, product_category_ids, ["parent_id"]) product_category_tree = dict( [(item["id"], item["parent_id"][0]) for item in product_categories if item["parent_id"]] ) results = {} for product_id, qty, partner in products_by_qty_by_partner: for pricelist_id in pricelist_ids: price = False tmpl_id = ( products_dict[product_id].product_tmpl_id and products_dict[product_id].product_tmpl_id.id or False ) categ_id = products_dict[product_id].categ_id and products_dict[product_id].categ_id.id or False categ_ids = _create_parent_category_list(categ_id, [categ_id]) if categ_ids: categ_where = "(categ_id IN (" + ",".join(map(str, categ_ids)) + "))" else: categ_where = "(categ_id IS NULL)" if partner: partner_where = "base <> -2 OR %s IN (SELECT name FROM product_supplierinfo WHERE product_id = %s) " partner_args = (partner, tmpl_id) else: partner_where = "base <> -2 " partner_args = () cr.execute( "SELECT i.*, pl.currency_id " "FROM product_pricelist_item AS i, " "product_pricelist_version AS v, product_pricelist AS pl " "WHERE (product_tmpl_id IS NULL OR product_tmpl_id = %s) " "AND (product_id IS NULL OR product_id = %s) " "AND (" + categ_where + " OR (categ_id IS NULL)) " "AND (" + partner_where + ") " "AND price_version_id = %s " "AND (min_quantity IS NULL OR min_quantity <= %s) " "AND i.price_version_id = v.id AND v.pricelist_id = pl.id " "ORDER BY sequence", (tmpl_id, product_id) + partner_args + (pricelist_version_ids[0], qty), ) res1 = cr.dictfetchall() uom_price_already_computed = False for res in res1: if res: if res["base"] == -1: if not res["base_pricelist_id"]: price = 0.0 else: price_tmp = self.price_get( cr, uid, [res["base_pricelist_id"]], product_id, qty, context=context )[res["base_pricelist_id"]] ptype_src = self.browse(cr, uid, res["base_pricelist_id"]).currency_id.id uom_price_already_computed = True price = currency_obj.compute( cr, uid, ptype_src, res["currency_id"], price_tmp, round=False, context=context ) elif res["base"] == -2: # this section could be improved by moving the queries outside the loop: where = [] if partner: where = [("name", "=", partner)] sinfo = supplierinfo_obj.search(cr, uid, [("product_id", "=", tmpl_id)] + where) price = 0.0 if sinfo: qty_in_product_uom = qty product_default_uom = product_obj.read(cr, uid, [product_id], ["uom_id"])[0]["uom_id"][ 0 ] supplier = supplierinfo_obj.browse(cr, uid, sinfo, context=context)[0] seller_uom = supplier.product_uom and supplier.product_uom.id or False if seller_uom and product_default_uom and product_default_uom != seller_uom: uom_price_already_computed = True qty_in_product_uom = product_uom_obj._compute_qty( cr, uid, product_default_uom, qty, to_uom_id=seller_uom ) cr.execute( "SELECT * " "FROM pricelist_partnerinfo " "WHERE suppinfo_id IN %s" "AND min_quantity <= %s " "ORDER BY min_quantity DESC LIMIT 1", (tuple(sinfo), qty_in_product_uom), ) res2 = cr.dictfetchone() if res2: price = res2["price"] else: price_type = price_type_obj.browse(cr, uid, int(res["base"])) uom_price_already_computed = True price = currency_obj.compute( cr, uid, price_type.currency_id.id, res["currency_id"], product_obj.price_get(cr, uid, [product_id], price_type.field, context=context)[ product_id ], round=False, context=context, ) if price is not False: price_limit = price price = price * (1.0 + (res["price_discount"] or 0.0)) price = rounding(price, res["price_round"]) # TOFIX: rounding with tools.float_rouding price += res["price_surcharge"] or 0.0 if res["price_min_margin"]: price = max(price, price_limit + res["price_min_margin"]) if res["price_max_margin"]: price = min(price, price_limit + res["price_max_margin"]) break else: # False means no valid line found ! But we may not raise an # exception here because it breaks the search price = False if price: results["item_id"] = res["id"] if "uom" in context and not uom_price_already_computed: product = products_dict[product_id] uom = product.uos_id or product.uom_id price = product_uom_obj._compute_price(cr, uid, uom.id, price, context["uom"]) if results.get(product_id): results[product_id][pricelist_id] = price else: results[product_id] = {pricelist_id: price} return results
def price_get_multi_lastinvoice(self, cr, uid, pricelist_ids, products_by_qty_by_partner, basefieldname="base",context=None): """multi products 'price_get'. @param pricelist_ids: @param products_by_qty: @param partner: @param basefieldname: @param context: { 'date': Date of the pricelist (%Y-%m-%d),} @return: a dict of dict with product_id as key and a dict 'price by pricelist' as value """ #basefieldname='base' def _create_parent_category_list(id, lst): if not id: return [] parent = product_category_tree.get(id) if parent: lst.append(parent) return _create_parent_category_list(parent, lst) else: return lst # _create_parent_category_list if context is None: context = {} date = time.strftime('%Y-%m-%d') if 'date' in context: date = context['date'] currency_obj = self.pool.get('res.currency') product_obj = self.pool.get('product.product') product_category_obj = self.pool.get('product.category') product_uom_obj = self.pool.get('product.uom') supplierinfo_obj = self.pool.get('product.supplierinfo') price_type_obj = self.pool.get('product.price.type') # product.pricelist.version: if not pricelist_ids: pricelist_ids = self.pool.get('product.pricelist').search(cr, uid, [], context=context) pricelist_version_ids = self.pool.get('product.pricelist.version').search(cr, uid, [ ('pricelist_id', 'in', pricelist_ids), '|', ('date_start', '=', False), ('date_start', '<=', date), '|', ('date_end', '=', False), ('date_end', '>=', date), ]) if len(pricelist_ids) != len(pricelist_version_ids): raise osv.except_osv(_('Warning!'), _("At least one pricelist has no active version !\nPlease create or activate one.")) # product.product: product_ids = [i[0] for i in products_by_qty_by_partner] #products = dict([(item['id'], item) for item in product_obj.read(cr, uid, product_ids, ['categ_id', 'product_tmpl_id', 'uos_id', 'uom_id'])]) products = product_obj.browse(cr, uid, product_ids, context=context) products_dict = dict([(item.id, item) for item in products]) # product.category: product_category_ids = product_category_obj.search(cr, uid, []) product_categories = product_category_obj.read(cr, uid, product_category_ids, ['parent_id']) product_category_tree = dict([(item['id'], item['parent_id'][0]) for item in product_categories if item['parent_id']]) results = {} for product_id, qty, partner in products_by_qty_by_partner: for pricelist_id in pricelist_ids: price = False tmpl_id = product_id and products_dict[product_id].product_tmpl_id and products_dict[product_id].product_tmpl_id.id or False categ_id = product_id and products_dict[product_id].categ_id and products_dict[product_id].categ_id.id or False categ_ids = _create_parent_category_list(categ_id, [categ_id]) if categ_ids: categ_where = '(categ_id IN (' + ','.join(map(str, categ_ids)) + '))' else: categ_where = '(categ_id IS NULL)' if partner: partner_where = basefieldname+' <> -2 OR %s IN (SELECT name FROM product_supplierinfo WHERE product_id = %s) ' partner_args = (partner, tmpl_id) else: partner_where = basefieldname+' <> -2 ' partner_args = () cr.execute( 'SELECT i.*, pl.currency_id ' 'FROM product_pricelist_item AS i, ' 'product_pricelist_version AS v, product_pricelist AS pl ' 'WHERE (product_tmpl_id IS NULL OR product_tmpl_id = %s) ' 'AND (product_id IS NULL OR product_id = %s) ' 'AND (' + categ_where + ' OR (categ_id IS NULL)) ' 'AND (' + partner_where + ') ' 'AND price_version_id = %s ' 'AND (min_quantity IS NULL OR min_quantity <= %s) ' 'AND i.price_version_id = v.id AND v.pricelist_id = pl.id ' 'ORDER BY sequence', (tmpl_id, product_id) + partner_args + (pricelist_version_ids[0], qty)) res1 = cr.dictfetchall() uom_price_already_computed = False for res in res1: if res: if res[basefieldname] == -10: # Partner's last invoice price price = 0.0 product_default_uom = product_obj.read(cr, uid, [product_id], ['uom_id'])[0]['uom_id'][0] cr.execute("select i.partner_id, il.product_id, il.price_unit, il.uos_id \ from account_invoice i \ inner join account_invoice_line il on il.invoice_id = i.id \ inner join product_uom uom on uom.id = il.uos_id \ where state not in ('draft','cancel') \ and il.product_id = %s \ and i.partner_id = %s \ order by i.write_date desc limit 1", (product_id,partner or -1,)) res2 = cr.dictfetchone() if res2: line_uom = res2['uos_id'] if line_uom and product_default_uom and product_default_uom != line_uom: uom_price_already_computed = True price = product_uom_obj._compute_price(cr, uid, line_uom, res2['price_unit'], product_default_uom) else: price = res2['price_unit'] else: return False if price is not False: price_limit = price price = price * (1.0+(res['price_discount'] or 0.0)) price = rounding(price, res['price_round']) #TOFIX: rounding with tools.float_rouding price += (res['price_surcharge'] or 0.0) if res['price_min_margin']: price = max(price, price_limit+res['price_min_margin']) if res['price_max_margin']: price = min(price, price_limit+res['price_max_margin']) break else: # False means no valid line found ! But we may not raise an # exception here because it breaks the search price = False if price: results['item_id'] = res['id'] if 'uom' in context and not uom_price_already_computed: product = products_dict[product_id] uom = product.uos_id or product.uom_id price = product_uom_obj._compute_price(cr, uid, uom.id, price, context['uom']) if results.get(product_id): results[product_id][pricelist_id] = price else: results[product_id] = {pricelist_id: price} return results
def price_get_old(self, cr, uid, ids, prod_id, qty, partner=None, context=None): ''' context = { 'uom': Unit of Measure (int), 'partner': Partner ID (int), 'date': Date of the pricelist (%Y-%m-%d), } ''' price = False item_id = 0 if context is None: context = {} currency_obj = self.pool.get('res.currency') product_obj = self.pool.get('product.product') supplierinfo_obj = self.pool.get('product.supplierinfo') price_type_obj = self.pool.get('product.price.type') if context and ('partner_id' in context): partner = context['partner_id'] context['partner_id'] = partner date = time.strftime('%Y-%m-%d') if context and ('date' in context): date = context['date'] result = {} result['item_id'] = {} for id in ids: cr.execute('SELECT * ' \ 'FROM product_pricelist_version ' \ 'WHERE pricelist_id = %s AND active=True ' \ 'AND (date_start IS NULL OR date_start <= %s) ' \ 'AND (date_end IS NULL OR date_end >= %s) ' \ 'ORDER BY id LIMIT 1', (id, date, date)) plversion = cr.dictfetchone() if not plversion: raise osv.except_osv(_('Warning !'), _('No active version for the selected pricelist !\n' \ 'Please create or activate one.')) cr.execute('SELECT id, categ_id ' \ 'FROM product_template ' \ 'WHERE id = (SELECT product_tmpl_id ' \ 'FROM product_product ' \ 'WHERE id = %s)', (prod_id,)) tmpl_id, categ = cr.fetchone() categ_ids = [] while categ: categ_ids.append(str(categ)) cr.execute('SELECT parent_id ' \ 'FROM product_category ' \ 'WHERE id = %s', (categ,)) categ = cr.fetchone()[0] if str(categ) in categ_ids: raise osv.except_osv(_('Warning !'), _('Could not resolve product category, ' \ 'you have defined cyclic categories ' \ 'of products!')) if categ_ids: categ_where = '(categ_id IN (' + ','.join(categ_ids) + '))' else: categ_where = '(categ_id IS NULL)' cr.execute( 'SELECT i.*, pl.currency_id ' 'FROM product_pricelist_item AS i, ' 'product_pricelist_version AS v, product_pricelist AS pl ' 'WHERE (product_tmpl_id IS NULL OR product_tmpl_id = %s) ' 'AND (product_id IS NULL OR product_id = %s) ' 'AND (' + categ_where + ' OR (categ_id IS NULL)) ' 'AND price_version_id = %s ' 'AND (min_quantity IS NULL OR min_quantity <= %s) ' 'AND i.price_version_id = v.id AND v.pricelist_id = pl.id ' 'ORDER BY sequence', (tmpl_id, prod_id, plversion['id'], qty)) res1 = cr.dictfetchall() for res in res1: item_id = 0 if res: if res['base'] == -1: if not res['base_pricelist_id']: price = 0.0 else: price_tmp = self.price_get(cr, uid, [res['base_pricelist_id']], prod_id, qty, context=context)[res['base_pricelist_id']] ptype_src = self.browse(cr, uid, res['base_pricelist_id']).currency_id.id price = currency_obj.compute(cr, uid, ptype_src, res['currency_id'], price_tmp, round=False) break elif res['base'] == -2: where = [] if partner: where = [('name', '=', partner) ] sinfo = supplierinfo_obj.search(cr, uid, [('product_id', '=', tmpl_id)] + where) price = 0.0 if sinfo: cr.execute('SELECT * ' \ 'FROM pricelist_partnerinfo ' \ 'WHERE suppinfo_id IN %s' \ 'AND min_quantity <= %s ' \ 'ORDER BY min_quantity DESC LIMIT 1', (tuple(sinfo),qty,)) res2 = cr.dictfetchone() if res2: price = res2['price'] break else: price_type = price_type_obj.browse(cr, uid, int(res['base'])) price = currency_obj.compute(cr, uid, price_type.currency_id.id, res['currency_id'], product_obj.price_get(cr, uid, [prod_id], price_type.field, context=context)[prod_id], round=False, context=context) if price: price_limit = price price = price * (1.0+(res['price_discount'] or 0.0)) price = rounding(price, res['price_round']) price += (res['price_surcharge'] or 0.0) if res['price_min_margin']: price = max(price, price_limit+res['price_min_margin']) if res['price_max_margin']: price = min(price, price_limit+res['price_max_margin']) item_id = res['id'] break else: # False means no valid line found ! But we may not raise an # exception here because it breaks the search price = False result[id] = price result['item_id'] = {id: item_id} if context and ('uom' in context): product = product_obj.browse(cr, uid, prod_id) uom = product.uos_id or product.uom_id result[id] = self.pool.get('product.uom')._compute_price(cr, uid, uom.id, result[id], context['uom']) return result
def product_id_change(self, cr, uid, ids, pricelist, product, qty=0, uom=False, qty_uos=0, uos=False, name='', partner_id=False, lang=False, update_tax=True, date_order=False, packaging=False, fiscal_position=False, flag=False, context=None): if context is None: context = {} if not product: return { 'value': { 'th_weight': 0, 'product_packaging': False, 'product_uos_qty': qty, 'tax_id': [] }, 'domain': { 'product_uom': [], 'product_uos': [] } } res = {} res = super(sale_order_line, self).product_id_change(cr, uid, ids, pricelist, product, qty, uom, qty_uos, uos, name, partner_id, lang, update_tax, date_order, packaging, fiscal_position, flag) product_obj = self.pool.get('product.product') pricelist_obj = self.pool.get('product.pricelist') prod = product_obj.browse(cr, uid, product, context=context) qty = qty or 0.0 if not uom or uom <> prod.uom_id.id: uom = prod.uom_id.id if not uos: uos = prod.uos_id.id price = pricelist_obj.price_get( cr, uid, [pricelist], product, qty or 1.0, partner_id, dict( context, uom=uom or res.get('product_uom'), date=date_order, ))[pricelist] try: price = price * prod.coef_amount except ZeroDivisionError: pass if prod.coef_amount: uos_qty = qty / prod.coef_amount else: uos_qty = qty uos_qty = rounding(uos_qty, prod.uos_id.rounding) qty = rounding(qty, prod.uom_id.rounding) res['value']['product_uom'] = uom res['value']['product_uom_qty'] = qty res['value']['product_uos'] = uos res['value']['product_uos_qty'] = uos_qty res['value']['secondary_price'] = price value = res['value'] if value.get('tax_id') == False: value.update({'tax_id': value.get('taxes_id')}) res.update({'value': value}) return res