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}
Example #2
0
    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
Example #3
0
    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}
Example #4
0
 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
Example #5
0
 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
Example #6
0
 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
Example #7
0
 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}
Example #8
0
    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}
Example #9
0
    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
Example #10
0
    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
Example #11
0
    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
Example #12
0
    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
Example #13
0
    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
Example #14
0
    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
Example #15
0
    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
Example #16
0
    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
Example #17
0
    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
Example #18
0
    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
Example #19
0
    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
Example #20
0
 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
Example #21
0
    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
Example #22
0
    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
Example #23
0
    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
Example #24
0
    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