How to resolve “TypeError: float() argument must b

2019-08-15 19:42发布

I was trying to install module product_print_zpl_barcode in odoo 9. This module is used to add a wizard on product variant to generate and print a product barcode on a ZPL printer. I got the error:

TypeError: float() argument must be a string or a number

when I pressed the button "Print barcode".

Here is the source code and error:

product_print_zpl_barcode.py

 # -*- coding: utf-8 -*-

 from openerp import models, fields, api, _
 from openerp.exceptions import UserError
 from openerp.tools import float_compare, float_is_zero
 import openerp.addons.decimal_precision as dp
 import base64
 import re


 class ProductPrintZplBarcode(models.Model):
_name = 'product.print.zpl.barcode'
_description = 'Generate and print product barcodes in ZPL'

@api.depends('pricelist_id', 'quantity', 'product_id')
def _compute_price(self):
    # for regular barcodes
    for wiz in self:
        if wiz.pricelist_id and wiz.product_id:
            price_uom = wiz.pricelist_id.price_get(wiz.product_id.id, 1)
            wiz.price_uom = price_uom
            wiz.price = price_uom * wiz.quantity
    return wiz.price

Traceback

   Traceback (most recent call last):
 File "D:\Projet_Odoo\Odoo 9.0-20180426\server\.\openerp\http.py", line 650, in _handle_exception
File "D:\Projet_Odoo\Odoo 9.0-20180426\server\.\openerp\http.py", line 687, in dispatch
File "D:\Projet_Odoo\Odoo 9.0-20180426\server\.\openerp\http.py", line 323, in _call_function
File "D:\Projet_Odoo\Odoo 9.0-20180426\server\.\openerp\service\model.py", line 118, in wrapper
File "D:\Projet_Odoo\Odoo 9.0-20180426\server\.\openerp\http.py", line 316, in checked_call
File "D:\Projet_Odoo\Odoo 9.0-20180426\server\.\openerp\http.py", line 966, in __call__
File "D:\Projet_Odoo\Odoo 9.0-20180426\server\.\openerp\http.py", line 516, in response_wrap
File "D:\Projet_Odoo\Odoo 9.20180426\server\openerp\addons\web\controllers\main.py", line 896, in call_kw
File "D:\Projet_Odoo\Odoo 9.20180426\server\openerp\addons\web\controllers\main.py", line 888, in _call_kw
File "D:\Projet_Odoo\Odoo 9.0-20180426\server\.\openerp\api.py", line 250, in wrapper
File "D:\Projet_Odoo\Odoo 9.0-20180426\server\.\openerp\api.py", line 381, in old_api
File "D:\Projet_Odoo\Odoo 9.0-20180426\server\.\openerp\models.py", line 6067, in onchange
File "D:\Projet_Odoo\Odoo 9.0-20180426\server\.\openerp\models.py", line 5770, in __getitem__
File "D:\Projet_Odoo\Odoo 9.0-20180426\server\.\openerp\fields.py", line 834, in __get__
File "D:\Projet_Odoo\Odoo 9.0-20180426\server\.\openerp\fields.py", line 949, in determine_draft_value
File "D:\Projet_Odoo\Odoo 9.0-20180426\server\.\openerp\fields.py", line 895, in compute_value
File "D:\Projet_Odoo\Odoo 9.0-20180426\server\.\openerp\fields.py", line 885, in _compute_value
File "D:\Projet_Odoo\Odoo 9.020180426\server\openerp\addons\product_print_zpl_barcode\models\product_print_zpl_barcode.py", line 100, in _compute_price
File "D:\Projet_Odoo\Odoo 9.0-20180426\server\.\openerp\fields.py", line 847, in __set__
File "D:\Projet_Odoo\Odoo 9.0-20180426\server\.\openerp\fields.py", line 1177, in convert_to_cache
TypeError: float() argument must be a string or a number

1条回答
够拽才男人
2楼-- · 2019-08-15 20:42

Do not return any value.

As described on Odoo web site You should assign the computed value to the field:

Computed fields

Fields can be computed (instead of read straight from the database) using the compute parameter. It must assign the computed value to the field. If it uses the values of other fields, it should specify those fields using depends()

After evaluating price_uom = wiz.pricelist_id.price_get(wiz.product_id.id, 1):

price_uom will be a dict ({pricelist_id: price}) so you need to get price_uom before trying to perform any arithmetic operation.

@api.depends('pricelist_id', 'quantity', 'product_id')
def _compute_price(self):
    # for regular barcodes
    for wiz in self:
        if wiz.pricelist_id and wiz.product_id:
            # You need to get price from the dict using pricelist_id
            price_uom = wiz.pricelist_id.price_get(wiz.product_id.id, 1)[wiz.pricelist_id.id]
            wiz.price_uom = price_uom
            wiz.price = price_uom * wiz.quantity
    return wiz.price

You can see how the price_get return value is computed if you take a look at the following code (I just copied the minimum necessary code):

def price_get(self, cr, uid, ids, prod_id, qty, partner=None, context=None):
    return dict((key, price[0]) for key, price in self.price_rule_get(cr, uid, ids, prod_id, qty, partner=partner, context=context).items())

def price_rule_get(self, cr, uid, ids, prod_id, qty, partner=None, context=None):
    product = self.pool.get('product.product').browse(cr, uid, prod_id, context=context)
    res_multi = self.price_rule_get_multi(cr, uid, ids, products_by_qty_by_partner=[(product, qty, partner)], context=context)
    res = res_multi[prod_id]
    return res

def price_rule_get_multi(self, cr, uid, ids, products_by_qty_by_partner, context=None):
    """multi products 'price_get'.
        @param 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
    """
    if not ids:
        ids = self.pool.get('product.pricelist').search(cr, uid, [], context=context)
    results = {}
    for pricelist in self.browse(cr, uid, ids, context=context):
        subres = self._price_rule_get_multi(cr, uid, pricelist, products_by_qty_by_partner, context=context)
        for product_id, price in subres.items():
            results.setdefault(product_id, {})
            results[product_id][pricelist.id] = price
    return results
查看更多
登录 后发表回答