Brilliant, exactly what I was missing. Thank you very much.
For anyone needing this the code that works looks like this:
types = {'customer', 'supplier'} admin_user, = self.User.find([('login', '=', 'admin')]) def no_origin(move): return ((move.from_location.type in types) ^ (move.to_location.type in types) and not move.origin) moves = [] move=Move() move.from_location = supplier_loc move.quantity = 10 ... complete the rest of the move moves.append(move) movesw = sorted(filter(no_origin, moves)) key = '|'.join(map(str, movesw)).encode('utf-8') warning_name = "%s.done" % (hashlib.md5(key).hexdigest()) self.Warning(user=admin_user, name=warning_name, always=True).save() self.Move.click(moves, 'do')