2017-07-05 5 views
0

Ich arbeite an einer Tabelle, die in einem Formular ist. Diese Tabelle wird automatisch mit der Eingabe des ersten Feldes gefüllt, das der Benutzer zu tun hat. In der Tabelle gibt es nur eine Spalte, in die der Benutzer Daten eingeben muss, und ich habe es ihnen ermöglicht, Daten direkt in die Tabelle einzugeben, anstatt ein neues Formular zu öffnen. Diese Daten müssen mit Werten überprüft werden, die in der Tabelle versteckt sind. Ich muss nur prüfen, ob der vom Benutzer eingegebene Wert einige Toleranzen berücksichtigt.Odoo 10 - Holen Sie sich tatsächliche Zeile oder rufen Sie die Funktion nach dem Speichern

Jetzt ist mein Problem, für die Überprüfung der Werte muss ich wissen, dass die IDs der Werte mit den Rechte Toleranzen überprüfen können, aber ich kann sie nicht erhalten, wenn der Benutzer das Formular nicht speichert.

Also habe ich zwei Fragen: Ist es möglich, eine Funktion direkt nach dem Speichern aufzurufen? Ich weiß, dass ich die "create" Funktion überschreiben kann, aber das ist nicht was ich will, ich möchte eine Funktion direkt nach dem Speichern aufgerufen werden, dank der ich die ids kennen könnte und es wäre möglich, die Werte zu überprüfen. Wenn das nicht möglich ist, ist meine zweite Frage: Ist es möglich, die Zeilennummer zu erhalten, wenn der Benutzer seinen Wert eingibt? Es wäre nützlich, die Zeilennummer mit api.onchange zu bekommen, so dass ich einfach in die Zeilen loopen könnte, bis ich die richtige finde und dann die Daten verwende, die da sind.

Vielen Dank für Ihre Zeit

EDIT1: Hier ist der Code, den ich eine Schleife durch die Daten aus:

class ControlMeasure(models.Model): 
    """ 
     Modèle pour la mesure d'une pièce 
    """ 

# Nom de la table 
_name = 'spc.control.measure' 

# Champs de la table 
name    = fields.Many2one(string='Name', related='control_point_id.measure_type_id', readonly=True) 
value    = fields.Float(string='Measured value') 
validity   = fields.Boolean(string='Validity', readonly=True) 
nominal_value  = fields.Float(string='Nominal value', related='control_point_id.nominal_value', readonly=True) 

unit_id    = fields.Many2one('product.uom', string='Unit', related='control_point_id.product_uom_id', readonly=True)    
control_part_id  = fields.Many2one('spc.control.part', string='Controled piece') 
control_point_id = fields.Many2one('spc.control.point', string='Control point') 

# Champs visuels 
control_device_id = fields.Many2one('spc.control.device', string='Used device', related='control_point_id.control_device_id') 

# Vérifie si la valeur mesurée est dans la tolérance 
@api.multi 
@api.onchange('value') 
def is_valid(self): 

    # raise Exception('Appel réussi') 

    sql= """ 
      SELECT p.nominal_value, p.inferior_tolerance, p.superior_tolerance FROM spc_control_point p 
      WHERE p.control_plan_id = %(ctrlid)s 
     """ 

    if self.control_part_id.control_plan_id == False: 
     raise Exception('False ' + str(self.control_part_id.control_plan_id)) 
    else: 
     self.env.cr.execute(sql, {'ctrlid' : self.control_part_id.control_plan_id.id}) 
     row = self.env.cr.fetchall() 

     for i in range(0, len(row)): 
      #raise Exception(str(self.value) + ' < ' + str(row[i][0]) + ' - ' + str(abs(row[i][1])) + ' or ' + str(self.value) + ' > ' + str(row[i][0]) + ' + ' + str(abs(row[i][2]))) 
      if self.value < row[i][0] - abs(row[i][1]) or self.value > row[i][0] + abs(row[i][2]): 
       self.validity = False 
      else: 
       self.validity = True 

Hier ist der ganze Code funktioniert, wie ich mit Ausnahme der Schleife wollen, dass ich weiß nicht, wie um es richtig zu machen, habe ich überprüft, ob die Daten, die getestet werden, die richtigen sind und sie sind, der Test selbst funktioniert wie ich will, aber wie Sie sehen, jedes Mal überprüfe ich alle Zeilen und das Ende, nur die letzte Zählung. Deshalb kam ich mit der Idee, die Zeilennummer zu bekommen, wo der Benutzer geklickt hat, aber ich weiß nicht, ob es möglich ist oder sogar eine Funktion nach dem Speichern aufrufen, was einfach wäre, weil ich die IDs kennen würde und ich überprüfen könnte die Daten nach dem Speichern.

Antwort

0

Zwei mögliche Lösungen kommen in meinem Kopf:

  1. Wie Sie erwähnt haben, eine Methode mit @api.onchange Dekorateur schaffen kann, ist es in der eingegebenen Daten jedes Mal Benutzer weitergegeben zu überprüfen, ohne es wirklich zu speichern oder irgendwelche anderen Manipulationen.

    @api.multi 
    @api.onchange('your_field', 'your_field2') 
    def _onchange_your_fields(self): 
        for record in self: 
         if record.your_field != record.validation_field: 
          raise exceptions.ValidationError(_('Sorry, pal, try again')) 
    

Das gute daran ist, dass es den Wert des Felds schnell zu validieren: nachdem der Benutzer einen Cursor auf das nächste Feld setzen. Obwohl es aus der Sicht eines Benutzers irritieren kann.

  1. Sie können versuchen @api.constrains Dekorateur. Es verhält sich etwas anders als der Dekorateur @api.onchange, aber es ist üblich, es für eine Validierung zu verwenden.

    @api.multi 
    @api.constrains('your_field', 'your_field2') 
    def _check_your_fields(self): 
        for record in self: 
         if record.your_field != record.validation_field: 
          raise exceptions.ValidationError(_('Sorry, pal, try again')) 
    

Der Unterschied ist, dass es aufgerufen wird, nachdem Sie „Speichern“ werden getroffen, aber vor create oder write Funktionen tatsächlich auszuführen.

Hoffe, das wird helfen.

UPDATE 1:

# Vérifie si la valeur mesurée est dans la tolérance 
@api.multi 
@api.onchange('value') 
def validate(self): 
    # Because we are using @api.multi decorator, our 'self' is actually a recordset. 
    # That means, that we cannot treat it as a regular record, so "self.control_part_id...." would be an odd code 
    for record in self: 
     # So now we took a one record from recordset, and now we can continue on validating it. 
     if not record.control_part_id.control_plan_id: 
      raise exceptions.UserError(_('False %s' % str(record.control_part_id.control_plan_id))) 

     # You executed here a SQL query, which is actually takes our records from database, not from cache. 
     # But we haven't write(or create) our changes yet, and that makes no sense. 

     # What we wanna do, is to take values from cache and validate them. You can simply do it just via model's field 
     validation_record = record.control_point_id 

     if record.value < validation_row.nominal_value - validation_row.inferior_tolerance \ 
      or record.value > validation_row.nominal_value + validation_row.superior_tolerance: 
       record.validity = True 

     else: 
      # You can get rid of this line by simply defining the default value of record.validity as "False" 
      record.validity = False 


# I recommend you to check the final validation this way 
@api.multi 
@api.constrains('validity') 
def check_valid(self): 
    for record in self: 
     if not record.validity: 
      raise exceptions.ValidationError(_("Cannot pass a validation rest")) 
+0

Ich habe immer noch ein Problem damit eigentlich, vielleicht verstehe ich nicht genau, wie es funktioniert, aber wenn ich die erste Lösung nehmen, muß ich durch mehrere Datensätze in einer Schleife und wenn Ich tue meinen Test Ich erstelle keinen Fehler, aber ich setze ein anderes Feld auf falsch oder wahr und wenn es falsch ist, wird die ganze Reihe rot und das ist, wo mein Problem ist. Wenn ich das tue, werden nur die letzten Werte berücksichtigt, ich bearbeite meinen Beitrag, um den Code, den ich für dich gemacht habe, zu verstehen, was ich gerade tue – Isariamkia

+0

Ich habe meine Antwort aktualisiert, bitte, schau sie dir an. – tidylobster

+0

Danke für die Hilfe! Ich wusste nicht, dass ich den Cache dafür verwenden könnte! So, jetzt macht es die Tests richtig, aber wenn ich speichere, wird der Wert des Gültigkeitsfeldes nicht korrekt gespeichert, wenn ich den Wert des Feldes nach dem Test zeige True, aber wenn ich es speichere geht es Falsch vorbei Standard – Isariamkia

Verwandte Themen