如何自动填写Odoo表单中的内容?

时间:2018-01-15 09:26:13

标签: python python-2.7 odoo-8 odoo

如何使上次填充详细信息字段呈现选中的相应储罐的最新litersdate 储罐。例如如果我选择 Tank A ,我会看到表单上最后一次填充dateliters中的数量的自动填充。 enter image description here

我有两个课程fleet_fuel_tankfleet_tank_log_fuel

fleet_fuel_tank类

的代码段
class fleet_fuel_tank(osv.Model):


    def _tank_name_get_fnc(self, cr, uid, ids, prop, unknow_none, context=None):
        res = {}
        for record in self.browse(cr, uid, ids, context=context):
            res[record.id] = record.name
        return res




    def _count_all(self, cr, uid, ids, field_name, arg, context=None):
        Stock = self.pool['fleet.tank.log.fuel']
        LogFuel = self.pool['fleet.tank.log.fuel']
        # LogService = self.pool['fleet.tank.log.services']
        # LogContract = self.pool['fleet.tank.log.contract']
        Cost = self.pool['fleet.tank.cost']
        return {
            tank_id: {
                'stock_count': Stock.search_count(cr, uid, [('stock_id', '=', tank_id)], context=context),
                'fuel_tank_logs_count': LogFuel.search_count(cr, uid, [('tank_id', '=', tank_id)], context=context),
                # 'service_count': LogService.search_count(cr, uid, [('tank_id', '=', tank_id)], context=context),
                # 'contract_count': LogContract.search_count(cr, uid, [('tank_id', '=', tank_id)], context=context),
                'cost_count': Cost.search_count(cr, uid, [('tank_id', '=', tank_id), ('parent_id', '=', False)], context=context)
            }
            for tank_id in ids
        }

    def return_action_to_open(self, cr, uid, ids, context=None):
        """ This opens the xml view specified in xml_id for the current tank """
        if context is None:
            context = {}
        if context.get('xml_id'):
            res = self.pool.get('ir.actions.act_window').for_xml_id(cr, uid ,'fleet', context['xml_id'], context=context)
            res['context'] = context
            res['context'].update({'default_tank_id': ids[0]})
            res['domain'] = [('tank_id','=', ids[0])]
            return res
        return False

    def act_show_log_cost(self, cr, uid, ids, context=None):
        """ This opens log view to view and add new log for this vehicle, groupby default to only show effective costs
            @return: the costs log view
        """
        if context is None:
            context = {}
        res = self.pool.get('ir.actions.act_window').for_xml_id(cr, uid ,'fleet','fleet_tank_costs_act', context=context)
        res['context'] = context
        res['context'].update({
            'default_tank_id': ids[0],
            'search_default_parent_false': True
        })
        res['domain'] = [('tank_id','=', ids[0])]
        return res

        # Driver can be changed to the purchaser Id



    def _get_stock(self, cr, uid, ids, stock_id, arg, context):
        res = dict.fromkeys(ids, 0)
        for record in self.browse(cr,uid,ids,context=context):
            ids = self.pool.get('fleet.tank.log.fuel').search(cr, uid, [('tank_id', '=', record.id)], limit=1, order='value desc')
            if len(ids) > 0:
                res[record.id] = self.pool.get('fleet.tank.log.fuel').browse(cr, uid, ids[0], context=context).value
        return res

    def _set_stock(self, cr, uid, id, name, value, args=None, context=None):
        if value:
            date = fields.date.context_today(self, cr, uid, context=context)
            data = {'value': value, 'date': date, 'tank_id': id}
            return self.pool.get('fleet.tank.log.fuel').create(cr, uid, data, context=context)


    _name = 'fleet.fuel.tank'
    _description = 'Contains Fuel Tank Details '

    _columns = {
        # 'name': fields.char('Name of Tank'),

        'name': fields.char( type="char", string='Name'),
        'location': fields.char('Location'),
        'fuel_type': fields.selection([('petroleum', 'Petroleum'), ('diesel', 'Diesel'), ('kerosene', 'Kerosene')], 'Fuel Type', help='Fuel Used by the vehicle'),
        'driver_id': fields.many2one('res.partner', 'Driver', help='Driver of the vehicle'),
        'capacity': fields.integer('Capacity',  help='Total capacity the tank can hold'),
        'refilling_date': fields.date(string='Re- Filling Date'),
        'liter': fields.float('Liters'),
        'value': fields.float('Current Stock Value', group_operator="max"),
        'stock': fields.function(_get_stock, fnct_inv=_set_stock, type='float', string='Last Stock Level', help='stock measure of the Tank at the moment of this log'),
        # 'stock_unit': fields.selection([('liters', 'liters')], 'Stock Unit', help='Unit of the stock '),
        'company_id': fields.many2one('res.company', 'Company'),
        'log_tank_fuel': fields.one2many('fleet.tank.log.fuel', 'tank_id', 'Fuel Logs'),
        'cost_count': fields.function(_count_all, type='integer', string="Costs" , multi=True),
        'stock_count': fields.function(_count_all, type='integer', string='Stock', multi=True),
        'fuel_tank_logs_count': fields.function(_count_all, type='integer', string='Fuel Logs', multi=True),
        'reception_date': fields.date('Acquisition Date', required=False, help='Date when the Tank has acquired fuel'),
        'location': fields.char('Location', help='Physical Location of the Tank  (KAKUMA, ...)'),



    }

fleet_tank_log_fuel类的代码

class fleet_tank_log_fuel(osv.Model):

    def on_change_tank(self, cr, uid, ids, tank_id, context=None):
        if not tank_id:
            return {}
        tank = self.pool.get('fleet.fuel.tank').browse(cr, uid, tank_id, context=context)
        # stock_unit = tank.stock_unit
        driver = tank.driver_id.id
        return {
            'value': {
                # 'stock_unit': stock_unit,
                'purchaser_id': driver,
            }
        }

    def on_change_liter(self, cr, uid, ids, liter, price_per_liter, amount, context=None):
        #need to cast in float because the value receveid from web client maybe an integer (Javascript and JSON do not
        #make any difference between 3.0 and 3). This cause a problem if you encode, for example, 2 liters at 1.5 per
        #liter => total is computed as 3.0, then trigger an onchange that recomputes price_per_liter as 3/2=1 (instead
        #of 3.0/2=1.5)
        #If there is no change in the result, we return an empty dict to prevent an infinite loop due to the 3 intertwine
        #onchange. And in order to verify that there is no change in the result, we have to limit the precision of the
        #computation to 2 decimal
        liter = float(liter)
        price_per_liter = float(price_per_liter)
        amount = float(amount)
        if liter > 0 and price_per_liter > 0 and round(liter*price_per_liter,2) != amount:
            return {'value' : {'amount' : round(liter * price_per_liter,2),}}
        elif amount > 0 and liter > 0 and round(amount/liter,2) != price_per_liter:
            return {'value' : {'price_per_liter' : round(amount / liter,2),}}
        elif amount > 0 and price_per_liter > 0 and round(amount/price_per_liter,2) != liter:
            return {'value' : {'liter' : round(amount / price_per_liter,2),}}
        else :
            return {}

    def on_change_price_per_liter(self, cr, uid, ids, liter, price_per_liter, amount, context=None):
        #need to cast in float because the value receveid from web client maybe an integer (Javascript and JSON do not
        #make any difference between 3.0 and 3). This cause a problem if you encode, for example, 2 liters at 1.5 per
        #liter => total is computed as 3.0, then trigger an onchange that recomputes price_per_liter as 3/2=1 (instead
        #of 3.0/2=1.5)
        #If there is no change in the result, we return an empty dict to prevent an infinite loop due to the 3 intertwine
        #onchange. And in order to verify that there is no change in the result, we have to limit the precision of the
        #computation to 2 decimal
        liter = float(liter)
        price_per_liter = float(price_per_liter)
        amount = float(amount)
        if liter > 0 and price_per_liter > 0 and round(liter*price_per_liter,2) != amount:
            return {'value' : {'amount' : round(liter * price_per_liter,2),}}
        elif amount > 0 and price_per_liter > 0 and round(amount/price_per_liter,2) != liter:
            return {'value' : {'liter' : round(amount / price_per_liter,2),}}
        elif amount > 0 and liter > 0 and round(amount/liter,2) != price_per_liter:
            return {'value' : {'price_per_liter' : round(amount / liter,2),}}
        else :
            return {}

    def on_change_amount(self, cr, uid, ids, liter, price_per_liter, amount, context=None):
        #need to cast in float because the value receveid from web client maybe an integer (Javascript and JSON do not
        #make any difference between 3.0 and 3). This cause a problem if you encode, for example, 2 liters at 1.5 per
        #liter => total is computed as 3.0, then trigger an onchange that recomputes price_per_liter as 3/2=1 (instead
        #of 3.0/2=1.5)
        #If there is no change in the result, we return an empty dict to prevent an infinite loop due to the 3 intertwine
        #onchange. And in order to verify that there is no change in the result, we have to limit the precision of the
        #computation to 2 decimal
        liter = float(liter)
        price_per_liter = float(price_per_liter)
        amount = float(amount)
        if amount > 0 and liter > 0 and round(amount/liter,2) != price_per_liter:
            return {'value': {'price_per_liter': round(amount / liter,2),}}
        elif amount > 0 and price_per_liter > 0 and round(amount/price_per_liter,2) != liter:
            return {'value': {'liter': round(amount / price_per_liter,2),}}
        elif liter > 0 and price_per_liter > 0 and round(liter*price_per_liter,2) != amount:
            return {'value': {'amount': round(liter * price_per_liter,2),}}
        else :
            return {}

    def _get_default_service_type(self, cr, uid, context):
        try:
            model, model_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'fleet', 'type_service_refueling')
        except ValueError:
            model_id = False
        return model_id

    _name = 'fleet.tank.log.fuel'
    _description = 'Fuel log for Tank'
    _inherits = {'fleet.tank.cost': 'cost_id'}

    _columns = {
        'tank_id': fields.many2one('fleet.fuel.tank', 'Tank'),   
        'liter': fields.float('Liters'),
        'price_per_liter': fields.float('Price Per Liter'),
        'value': fields.float('Current Stock Value', group_operator="max"),
        'purchaser_id': fields.many2one('res.partner', 'Purchaser', domain="['|',('customer','=',True),('employee','=',True)]"),
        'inv_ref': fields.char('Invoice Reference', size=64),
        'date': fields.date('Date'),
        'vendor_id': fields.many2one('res.partner', 'Supplier', domain="[('supplier','=',True)]"),
        'notes': fields.text('Notes'),
        'cost_id': fields.many2one('fleet.tank.cost', 'Cost', ondelete='cascade'),
        'cost_amount': fields.related('cost_id', 'amount', string='Amount', type='float', store=True), #we need to keep this field as a related with store=True because the graph view doesn't support (1) to address fields from inherited table and (2) fields that aren't stored in database
    }
    _defaults = {
        'date': fields.date.context_today,
        # 'cost_subtype_id': _get_default_service_type,
        'cost_type': 'fuel',
    }

1 个答案:

答案 0 :(得分:1)

如何设置默认值

如果您使用的是旧api ,则可以使用_defaults词典设置默认值:

def _get_default_notes(self, cr, uid, context=None):
    return 'Test note'

# [...]

_defaults = {
    'location': 'Far away',
    'notes': _get_default_notes,
}

尝试使用新api ,因为它会更容易。然后你应该填写这样的默认值:

class FleetFuelTank(models.Model):    
    liter = fields.Char(
        string='Liters',
        default=lambda self: self._get_default_liter(),
    )

    @api.model
    def _get_default_liter(self):
        return 4.5

如何触发onchange方法

如果要动态修改数据,可以使用onchange方法。我在这里向你展示一些例子:

旧API

<field name="product_uom_qty" on_change="onchange_quantity(product_id)"/>
def onchange_quantity(self, cr, uid, ids, product_id):

    result = {
        'product_uos_qty': 0.00
    }

    # [...]

    return {'value': result }

新API(xml视图中没有任何内容)

@api.one
@api.onchange('tank_id')
def onchange_tank(self):
    self.name = 'changes what you want to do'