2

我正在尝试根据下拉列表中的选择实现与发票行表单类似的效果,其中某些列出现或消失(编辑视图?)。

我正在尝试研究 account_invoice_layout 中实现此效果的代码,但它有点难以理解。

这是完整的代码:

class account_invoice_line(osv.osv):

def move_line_get_item(self, cr, uid, line, context=None):
    if line.state != 'article':
        return None
    return super(account_invoice_line, self).move_line_get_item(cr, uid, line, context)

def fields_get(self, cr, uid, fields=None, context=None):
    article = {
        'article': [('readonly', False), ('invisible', False)],
        'text': [('readonly', True), ('invisible', True), ('required', False)],
        'subtotal': [('readonly', True), ('invisible', True), ('required', False)],
        'title': [('readonly', True), ('invisible', True), ('required', False)],
        'break': [('readonly', True), ('invisible', True), ('required', False)],
        'line': [('readonly', True), ('invisible', True), ('required', False)],
    }
    states = {
        'name': {
            'break': [('readonly', True),('required', False),('invisible', True)],
            'line': [('readonly', True),('required', False),('invisible', True)],
            },
        'product_id': article,
        'account_id': article,
        'quantity': article,
        'uos_id': article,
        'price_unit': article,
        'discount': article,
        'invoice_line_tax_id': article,
        'account_analytic_id': article,
    }
    res = super(account_invoice_line, self).fields_get(cr, uid, fields, context)
    for field in res:
        if states.has_key(field):
            for key,value in states[field].items():
                res[field].setdefault('states',{})
                res[field]['states'][key] = value
    return res

def onchange_invoice_line_view(self, cr, uid, id, type, context=None, *args):

    if (not type):
        return {}
    if type != 'article':
        temp = {'value': {
                'product_id': False,
                'uos_id': False,
                'account_id': False,
                'price_unit': False,
                'price_subtotal': False,
                'quantity': 0,
                'discount': False,
                'invoice_line_tax_id': False,
                'account_analytic_id': False,
                },
            }
        if type == 'line':
            temp['value']['name'] = ' '
        if type == 'break':
            temp['value']['name'] = ' '
        if type == 'subtotal':
            temp['value']['name'] = 'Sub Total'
        return temp
    return {}

def create(self, cr, user, vals, context=None):
    if vals.has_key('state'):
        if vals['state'] == 'line':
            vals['name'] = ' '
        if vals['state'] == 'break':
            vals['name'] = ' '
        if vals['state'] != 'article':
            vals['quantity']= 0
            vals['account_id']= self._default_account(cr, user, None)
    return super(account_invoice_line, self).create(cr, user, vals, context)

def write(self, cr, user, ids, vals, context=None):
    if vals.has_key('state'):
        if vals['state'] != 'article':
            vals['product_id']= False
            vals['uos_id']= False
            vals['account_id']= self._default_account(cr, user, None)
            vals['price_unit']= False
            vals['price_subtotal']= False
            vals['quantity']= 0
            vals['discount']= False
            vals['invoice_line_tax_id']= False
            vals['account_analytic_id']= False
        if vals['state'] == 'line':
            vals['name'] = ' '
        if vals['state'] == 'break':
            vals['name'] = ' '
    return super(account_invoice_line, self).write(cr, user, ids, vals, context)

def copy_data(self, cr, uid, id, default=None, context=None):
    if default is None:
        default = {}
    default['state'] = self.browse(cr, uid, id, context=context).state
    return super(account_invoice_line, self).copy_data(cr, uid, id, default, context)

def _fnct(self, cr, uid, ids, name, args, context=None):
    res = {}
    lines = self.browse(cr, uid, ids, context=context)
    account_ids = [line.account_id.id for line in lines]
    account_names = dict(self.pool.get('account.account').name_get(cr, uid, account_ids, context=context))
    for line in lines:
        if line.state != 'article':
            if line.state == 'line':
                res[line.id] = '-----------------------------------------'
            elif line.state == 'break':
                res[line.id] = 'PAGE BREAK'
            else:
                res[line.id] = ' '
        else:
            res[line.id] = account_names.get(line.account_id.id, '')
    return res

_name = "account.invoice.line"
_order = "invoice_id, sequence asc"
_description = "Invoice Line"
_inherit = "account.invoice.line"
_columns = {
    'state': fields.selection([
            ('article','Product'),
            ('title','Title'),
            ('text','Note'),
            ('subtotal','Sub Total'),
            ('line','Separator Line'),
            ('break','Page Break'),]
        ,'Type', select=True, required=True),
    'sequence': fields.integer('Sequence Number', select=True, help="Gives the sequence order when displaying a list of invoice lines."),
    'functional_field': fields.function(_fnct, arg=None, fnct_inv=None, fnct_inv_arg=None, type='char', fnct_search=None, obj=None, store=False, string="Source Account"),
}

def _default_account(self, cr, uid, context=None):
    cr.execute("select id from account_account where parent_id IS NULL LIMIT 1")
    res = cr.fetchone()
    return res[0]

_defaults = {
    'state': 'article',
    'sequence': 0,
}

account_invoice_line()

fields_get 方法究竟做了什么?什么时候执行?上面的代码是如何编辑视图的?

谢谢你。

4

1 回答 1

4

实际上 fields_get() 返回模块的字段定义。在字段定义中,您可以提供 states 参数。

默认情况下,它在字段定义上的工作方式如下:

states = {'draft':[('readonly','=',True)]}

当状态表单处于“草稿”时,它会将字段设置为只读。

变量状态文章存储相同的值。

现在在您向我们展示的模块中,状态字段值与通常的值不同:

[('article','Product'),
            ('title','Title'),
            ('text','Note'),
            ('subtotal','Sub Total'),
            ('line','Separator Line'),
            ('break','Page Break'),]

在 fields_get() 函数的最后一部分,我们有:

res = super(account_invoice_line, self).fields_get(cr, uid, fields, context)
for field in res:
    if states.has_key(field):
        for key,value in states[field].items():
            res[field].setdefault('states',{})
            res[field]['states'][key] = value
return res

它使用超类的方法,它的工作方式如下:

fields_get() 使用 fields 参数返回模块上存在的字段。您的模块只是强制每个字段的状态参数。

最后,它允许根据虚拟状态字段显示字段。在您的示例中:

  • 如果一行处于“文章”状态,则默认显示,
  • 如果一行处于“标题”状态,则显示为不可见且只读。

我认为这些状态值是用来判断一行是标题、文章还是其他内容。

所以,如果你想在你自己的模块中做同样的事情,复制/粘贴这个 fields_get() 函数定义,自定义你的文章和状态变量,如果需要,不要忘记调整_columns 类属性上的状态字段定义.

希望对你有帮助

不是现在

于 2013-01-10T13:13:31.167 回答