2015-08-12 1 views
7

У меня есть переходная модель, которая служит диалогом. С моей точки зрения формы У меня есть кнопка, как это:Odoo - кнопка предотвращения от закрытия мастера

<footer states="partnerId"> 
    <button name="check_tax_id" string="Tovább" type="object"/> 
</footer> 

Кнопка вызывающую эту функцию (я могу подтвердить, что на самом деле вызывает):

@api.one 
    def check_tax_id(self, context=None): 
     self.state = "partnerDetails" 

     return None; 

Моя проблема заключается в том, что диалоговое окно закрывается сразу же после Я нажимаю эту кнопку! Что я делаю неправильно?

ответ

16

Раствор 0

@api.multi 
def check_tax_id(self): 
    self.ensure_one() 
    self.name = "New name" 
    return { 
     "type": "ir.actions.do_nothing", 
    } 

Это решение было представлено here Тадеуша Карпинского.

Решение 1

Вы можете вернуть новую форму с тем же идентификатором записи.

@api.multi 
def check_tax_id(self): 
    self.ensure_one() 
    self.name = "New name" 
    return { 
     'context': self.env.context, 
     'view_type': 'form', 
     'view_mode': 'form', 
     'res_model': 'model_name', 
     'res_id': self.id, 
     'view_id': False, 
     'type': 'ir.actions.act_window', 
     'target': 'new', 
    } 

Решение 2

Вы можете создать виджет в JQuery. Это откроет мастер, и вы можете назначить поведение, которое вы хотите для кнопок вручную. Вы можете использовать функцию call для вызова функции питона, а также:

[...] 

new instance.web.Dialog(this, { 
    title: _t("Title"), 
    width: '95%', 
    buttons: [ 
      { text: _t("First button"), click: function() { self.first_button(); }}, 
      { text: _t("Second button"), click: function() { self.second_button(); }}, 
      { text: _t("Close"), click: function() { dialog.close(); }},      
     ], 
}); 

[...] 

Решение 3

Конечно вы можете переопределить метод создания, а также, чтобы избежать создания записи в некоторых случаях

Решение 4

Последний выбор. Создайте рабочий процесс с полем состояния. Создайте кнопки рабочего процесса, чтобы отправлять сигналы для изменения состояния. Вы можете показать или скрыть остальные поля, используя атрибут attrs и поле состояния. Но я не знаю, будет ли это соответствовать вашим потребностям.

+0

Я нашел важную информацию здесь: https://github.com/odoo/odoo/issues/2270 –

+0

В настоящее время ваше решение кажется единственным, что работает. –

+0

Запись уже создана при запуске мастера, она не будет создаваться снова, если вы пройдете идентификатор текущего мастера, но будете созданы, если вы передадите False в res_id. – StackUP

0

Да, вы правы ... но у нас нет никакого решения. Потому что, когда вы нажимаете на любую кнопку мастера, мастер автоматически уничтожается.

Но вы можете выполнить этот метод, используя метод write onchange любого поля.

0

на odoo 7

def traszero(self ,cr ,uid ,ids ,context=None): 
     data_obj = self.pool.get('stock.return.picking.line') 
     ret_wizard = self.browse(cr, uid, ids, context=context) 
     if ret_wizard.product_return_moves: 
      line_ids = ret_wizard.product_return_moves.mapped('id') 
      data_obj.write(cr, uid, line_ids, {'quantity': 0}, context=context) 
     return {'name':"Return Shipment", 
      'res_model':"stock.return.picking", 
      'src_model':"stock.picking", 
      'view_mode':"form", 
      'target':"new", 
      'key2':"client_action_multi", 
      'multi':"True", 
      'res_id':ids[0], 
      'type': 'ir.actions.act_window', 
      } 
0

Что вы можете сделать, это есть кнопка открыть еще один мастер проходящего контекст со всеми значениями, введенным в первый мастер. Это позволяет выполнить некоторую функцию, т.е. ваша кнопка. И сохраните состояние своего волшебника. Поэтому значение по умолчанию для полей в вашем мастере должно сначала проверять контекст и отбрасывать на что-то другое.

Вот пример:

class MyWizard(models.TransientModel): 
    _name = 'myaddon.mywizard' 

    def _get_default_char(self): 
     return self._context.get('mychar',"") 

    mychar = fields.Char(string="My Char", default=_get_default_char) 

    @api.multi 
    def my_button(self): 
     # Execute Function Here 
     # reload wizard with context 

     return { 
      'view_type': 'form', 
      'view_mode': 'form', 
      'res_model': 'myaddon.mywizard', 
      'type': 'ir.actions.act_window', 
      'target': 'new', 
      'context': '{"mychar":'HELLO WORLD'}', 
     } 
+0

Спасибо, но я думаю, что принятый ответ намного проще и эффективнее, достигая той же цели. –

5

В моем случае этот код работает.

@api.multi 
def test(self): 
    l = logging.getLogger() 
    l.warn("xD") 
    return { 
     "type": "ir.actions.do_nothing", 
    } 
2

Самый простой это сделать, это:

@api.multi 
def null_action(self): 
    return { 
     "type": "set_scrollTop", 
    } 

Как тип используется для вызова любого метода на классе ActionManager (JavaScript)

Это лучше, чем «типа»: «ИК .actions_doothing ", которые генерируют исключение (этот атрибут не существует)

2

вчера я столкнулся с этой же проблемой. Мне нужно было показать кнопку, чтобы сделать что-то, не отправив всю визард. Я работал вокруг этого, не используя кнопку вообще. Это довольно просто и эффективно. Что вам нужно:

  1. логический флаг в модели мастера
  2. OnChange прикреплен к флагу (который заменяет вы sumbmit функцию)
  3. заменить кнопку на панели ж/флаг ж/invisible="1" и этикетка будет стилизован под кнопкой

Вот код:

source_it = fields.Boolean(string='Source') 
[...] 
def action_source(self): 
    # do stuff 

@api.onchange('source_it') 
def onchange_source_it(self): 
    if self.env.context.get('sourcing_now') or not self.source_it: 
     return 
    self.action_source() 
[...] 
<label for="source_it" class="pull-left btn btn-success" /> 
<field name="source_it" invisible="1" /> 

хитрость ж orks, потому что когда метка имеет атрибут for, он будет действовать как флажок, поэтому, если вы нажмете на метку, вы фактически переключаете этот флажок.