import uuid import logging import datetime from .dsslogger import OdooCustomLogger from odoo import api, fields, models, _ from odoo import tools from datetime import datetime from datetime import date from odoo.exceptions import ValidationError from dateutil.relativedelta import relativedelta from tuya_iot import TuyaOpenAPI, TUYA_LOGGER from tuya_connector import TuyaOpenAPI, TUYA_LOGGER import sys TUYA_LOGGER.setLevel(logging.DEBUG) logging.setLoggerClass(OdooCustomLogger) _logger = logging.getLogger(__name__) ##_logger = logging.getLogger(__name__) class trigger(models.Model): dataset = None @api.model def GetValue(self,Table,FieldName): sampletable = self.env['ir.config_parameter'].sudo().get_param('dss.global.trigger_sample_table') sampleid = self.env['ir.config_parameter'].sudo().get_param('dss.global.trigger_sample_id') Dataset = self.env[sampletable].search([('id','=',sampleid)]) _logger.info("GetValue called for "+str(Table)+" Fieldname "+str(FieldName)+' -> '+str(self)+' / '+str(Dataset)) Field=self.env['ir.model.fields'].search([('id','=',FieldName)]) _logger.info("GetValue called for "+str(Table)+" Fieldname "+str(Field)) _logger.info("GetValue called for "+str(Table)+" Fieldname "+str(Field)+' -> '+str(Dataset[Field.name])) return Dataset[Field.name] class dsstriggerconditions(models.Model): _name = "dss.triggerconditions" _description = "DigitalSignage Trigger Bedingungen" _inherit = ['mail.thread','mail.activity.mixin'] _rec_name = "triggerconditionname" # _inherit = ['mail.thread', 'mail.activity.mixin'] uuid = fields.Char(default=lambda self: self._default_uuid(), required=True, readonly=True, copy=False, string='UUID') date_create = fields.Date('Erstellungsdatum',default=lambda self: self._default_create_date()) date_lastedit = fields.Date('Änderungsdatum') user_create = fields.Char('Erstellungsuser',default=lambda self: self._default_create_user()) user_lastedit = fields.Char('Änderungsuser') triggerconditionname = fields.Char('Trigger Bedingungsname',tracking=True) trigger_table = fields.Many2one('ir.model','Nutzbar in',help='Für welche Daten ist dieser Bedingung gültig ?',tracking=True) trigger_condition_type = fields.Selection([('WERT','Feld gleich einem Wert'),('MARKER','Marker vorhanden')],'Prüfungsart',tracking=True) trigger_field = fields.Many2one('ir.model.fields',string="Bedingungsfeld", help='Prüfungsfeldname in der Tabelle - für dieses Feld wird der Wert geprüft',tracking=True) trigger_operator = fields.Selection([('NGLEICH','Feld gleich dem Wert'),('GGLEICH','Feld größer/gleich dem Wert'),('KGLEICH','Feld kleiner/gleich dem Wert'),('UGLEICH','Feld ungleich dem Wert'),('ENTHAELT','Feld enthällt dem Wert')],'Feldwertoperator',tracking=True) trigger_value_opperator = fields.Selection([('TAG','Aktueller Tag'),('TIME','Aktuelle Zeit'),('JAHR','Aktuelles Jahr'),('BTRUE','Boolean Wahr'),('BFALSE','Boolean Falsch'),('FIX','Wert')],'Vergleichswert',tracking=True) trigger_negate = fields.Boolean('Ergebnis Negieren',tracking=True) trigger_marker_check = fields.Many2one('dss.marker','Marker',help='Welcher Marker soll eingefügt werden ?',tracking=True) trigger_value = fields.Char('Fix Wert',tracking=True) @api.model def _default_uuid(self): return str(uuid.uuid4()) def _default_create_date(self): return str(date.today()) def _default_create_user(self): return str(self.env.user.name) def trigger_CheckCond(self,Dataset,Condition): if (Condition.trigger_condition_type == "MARKER"): Wert = "" else: fieldname = Condition.trigger_field.name field = Dataset._fields[fieldname] field_type = field.type Compare = False if (field_type == "date"): Wert = str(Dataset[fieldname]) elif (field_type == "many2one"): Wert = str(Dataset[fieldname].id) else: Wert = Dataset[fieldname] if (Condition.trigger_condition_type == "WERT"): _logger.info("Trigger in CheckConditions - checking conditions : "+str(Dataset)+" field : "+str(fieldname)+' ('+str(Condition.trigger_value_opperator)+') -> '+str(Condition)) OPP = Condition.trigger_operator if (Condition.trigger_value_opperator== "TAG"): TargetValue= str(date.today()) if (Wert == False): Wert = "1900-01-01" elif (Condition.trigger_value_opperator== "TIME"): TargetValue= str(datetime.now()) if (Wert == False): Wert = "00:00" elif (Condition.trigger_value_opperator== "JAHR"): TargetValue= str(date.today()) if (Wert == False): Wert = "1900-01-01" elif (Condition.trigger_value_opperator== "BTRUE"): TargetValue= str(True) elif (Condition.trigger_value_opperator== "BFALSE"): TargetValue= str(False) elif (Condition.trigger_value_opperator== "FIX"): TargetValue= str(Condition.trigger_value) _logger.info("Trigger in CheckConditions - Vergleich : ("+str(Wert)+') ('+str(field_type)+' -> '+str(OPP)+' -> '+str(TargetValue)) Compare = False if OPP=="NGLEICH": Compare = str(Wert) == str(TargetValue) _logger.info("Trigger in CheckConditions - Vergleich GLEICH : "+str(Wert)+' = '+str(TargetValue)+" = "+str(Compare)) if OPP=="UGLEICH": Compare = str(Wert) != str(TargetValue) _logger.info("Trigger in CheckConditions - Vergleich NGLEICH : "+str(Wert)+' <> '+str(TargetValue)+" = "+str(Compare)) if OPP=="GGLEICH": Compare = str(Wert) >= str(TargetValue) _logger.info("Trigger in CheckConditions - Vergleich GGLEICH : "+str(Wert)+' >= '+str(TargetValue)+" = "+str(Compare)) if OPP=="KGLEICH": Compare = str(Wert) <= str(TargetValue) _logger.info("Trigger in CheckConditions - Vergleich KGLEICH : "+str(Wert)+' <= '+str(TargetValue)+" = "+str(Compare)) elif (Condition.trigger_condition_type == "MARKER"): _logger.info("Trigger in CheckConditions - checking conditions : "+str(Dataset.marker_list)+" Marker : "+str(Condition.trigger_marker_check)) Compare = Condition.trigger_marker_check.id in Dataset.marker_list.mapped('id') if Condition.trigger_negate: Compare = not Compare _logger.info("Trigger in CheckConditions - NOT Invert : = "+str(Compare)) dotrigger = Compare return dotrigger @api.model def getconditionbyid(self,conditionid): _logger.info("Trigger get condition by conditionid !"+str(conditionid)) element = self.env['dss.triggerconditions'].search([('id','=',conditionid)]) _logger.info("Trigger get condition by conditionid !"+str(conditionid)+' - '+str(element)) blocksyntax = {} if element: blocksyntax = element.read()[0] if element else {} else: blocksyntax = {} return blocksyntax return element class dsstriggergroups(models.Model): _name = "dss.triggergroups" _description = "DigitalSignage Trigger Gruppen" _inherit = ['mail.thread','mail.activity.mixin'] _rec_name = "triggergroupname" # _inherit = ['mail.thread', 'mail.activity.mixin'] uuid = fields.Char(default=lambda self: self._default_uuid(), required=True, readonly=True, copy=False, string='UUID') date_create = fields.Date('Erstellungsdatum',default=lambda self: self._default_create_date()) date_lastedit = fields.Date('Änderungsdatum') user_create = fields.Char('Erstellungsuser',default=lambda self: self._default_create_user()) user_lastedit = fields.Char('Änderungsuser') triggergroupname = fields.Char('Trigger Gruppenname',tracking=True) trigger_table = fields.Many2one('ir.model','Nutzbar in',help='Für welche Daten ist dieser Tigger gültig ?',tracking=True) triggers = fields.Many2many('dss.triggertypes',string='Enthaltene Trigger',tracking=True) trigger_allgemein = fields.Boolean('Trigger allgemein gültig ?',tracking=True) trigger_cron = fields.Boolean('Triggergruppe für Zeitsteuerung ?',tracking=True) @api.model def _default_uuid(self): return str(uuid.uuid4()) def _default_create_date(self): return str(date.today()) def _default_create_user(self): return str(self.env.user.name) @api.model def run_triggers(self, changes, Dataset, triggers): _logger.info("Trigger in run_triggers ! - start count :"+str(len(triggers)) ) for trig in triggers: if trig.trigger_active: _logger.info("Trigger in run_triggers - Working on : "+str(trig.triggername)+'('+str(trig.id)+')') dochecktrigger = False if (changes == False): dochecktrigger = True elif (trig.triggertyp == "COND"): dochecktrigger = True else: if (trig.trigger_field.name in changes): dochecktrigger = True if (dochecktrigger): isinintitable = self.env['dss.triggermodel.execute'].search(['&',('trigger','=',trig.id),('data_uuid','=',Dataset.uuid)]) dotrigger = False if (not isinintitable) and trig.trigger_init_trigger: _logger.info("Trigger in run_triggers - first run and allowed : "+str(isinintitable)+' -> '+str(trig.trigger_init_trigger)+' -> '+str(trig)) dotrigger = True elif (not isinintitable) and ((not trig.trigger_init_trigger) and (not trig.trigger_onlyinit_trigger)): _logger.info("Trigger in run_triggers - first run but not allowed : "+str(isinintitable)+' -> '+str(trig.trigger_init_trigger)+' -> '+str(trig)) dotrigger = False elif (isinintitable) and trig.trigger_onlyinit_trigger: _logger.info("Trigger in run_triggers - not first run but only first: "+str(isinintitable)+' -> '+str(trig.trigger_onlyinit_trigger)+' -> '+str(trig)) dotrigger = False else: _logger.info("Trigger in run_triggers - not first run but only first: "+str(isinintitable)+' -> '+str(trig)) dotrigger = True if dotrigger: fieldname = trig.trigger_value_field.name _logger.info("Trigger in run_triggers - checking conditions : "+str(trig.triggertyp)+" field : "+str(fieldname)+' -> '+str(trig.trigger_value_field)) if (trig.triggertyp == "FIELD_B"): Wert = Dataset[fieldname] _logger.info("Trigger in run_triggers - Boolean check : "+str(Dataset[fieldname])+" vs "+str(Wert)+' -> '+str(trig.trigger_value_Bool)) if trig.trigger_value_Bool: if Wert: _logger.info("Trigger in run_triggers - value true - specific value found : "+str(changes)+" ("+str(Wert)+') -> '+str(trig.trigger_value_Bool)) dotrigger = True else: _logger.info("Trigger in run_triggers - value true - specific value not found : "+str(changes)+" ("+str(Wert)+') -> '+str(trig.trigger_value_Bool)) dotrigger = False else: if Wert: _logger.info("Trigger in run_triggers - value False - specific value found : "+str(changes)+" ("+str(Wert)+') -> '+str(trig.trigger_value_Bool)) dotrigger = False else: _logger.info("Trigger in run_triggers - value False - specific value not found : "+str(changes)+" ("+str(Wert)+') -> '+str(trig.trigger_value_Bool)) dotrigger = True elif (trig.triggertyp == "FIELD_S"): #Wert= self.env[trig.trigger_table.model].get(fieldname) WertDB = self.env[trig.trigger_table.model].search([('id', '=', Dataset.id)]) field = WertDB._fields[fieldname] field_type = field.type Wert = "" if field_type=="many2one": Wert = str(Dataset[fieldname].id) # Dataset[fieldname].model # SubWertDB = self.env[].search([('id', '=', field.id)]) # Wert = SubWertDB.id if field_type=="char": Wert = str(Dataset[fieldname]) _logger.info("Trigger in run_triggers - specific value : "+str(changes)+" ("+str(Wert)+') -> '+str(trig.trigger_value)+' - '+str(field)+' / '+str(field_type)) if (str(Wert) == str(trig.trigger_value)): _logger.info("Trigger in run_triggers - specific value found : "+str(changes)+" ("+str(Wert)+') -> '+str(trig.trigger_value)) dotrigger = True else: _logger.info("Trigger in run_triggers - specific value not found : "+str(changes)+" ("+str(Wert)+') -> '+str(trig.trigger_value)) dotrigger = False elif (trig.triggertyp == "FIELD_K"): dotrigger = False elif (trig.triggertyp == "MANUAL"): dotrigger = False elif (trig.triggertyp == "COND"): dotrigger = True if trig.trigger_plus_conditions and dotrigger: runtrigger = True for SingleC in trig.trigger_conditions: _logger.info("Trigger in run_triggers - Multible Conditions found "+str(trig.trigger_conditions)+' -> '+str(SingleC)+' -> '+str(runtrigger)) runtrigger = SingleC.trigger_CheckCond(Dataset,SingleC) and runtrigger else: runtrigger = dotrigger if runtrigger: execds = '' self.trigger_run(trig,Dataset,isinintitable,execds) def trigger_run(self,trig,Dataset,isinintitable,execds): for akt in trig.trigger_aktionen: if akt: _logger.info("Trigger in Trigger_run - Aktion "+str(akt)) akt.Doexecute(Dataset) execds = execds + ";" +str(Dataset.id)+'/'+str(akt.id) if not isinintitable: # self.env['dss.triggermodel.execute'].create({'trigger':trig.id,'data_uuid':Dataset.uuid,'execdatetime':date.today(),"trigger_action":akt.id}) self.env['dss.triggermodel.execute'].create({'trigger':trig.id,'data_uuid':Dataset.uuid,'execdatetime':date.today(),"trigger_table":self.env['ir.model'].search([('model','=',str(akt.trigger_table.model))]).id,"trigger_action":akt.id}) # akt._run_action_code_multi(akt._get_eval_context(akt)) else: _logger.info("Trigger in Trigger_run - no Aktion in Trigger !") for aktgroup in trig.trigger_aktionen_groups: if aktgroup: for akt in aktgroup: _logger.info("Trigger in Trigger_run - Aktion "+str(akt)) akt.Doexecute(Dataset,trig,isinintitable) execds = execds + ";" +str(Dataset.id)+'/'+str(akt.id) return execds def run_cron_triggers(self,triggergroup,triggers): _logger.info("Trigger in run_Cron_Triggers ! - Start für : "+str(self.trigger_table.model)) resultstr = "Anz. Trigger : "+str(len(triggers)) resultsimplestr = "Anz. Trigger : "+str(len(triggers)) triggercnt = 0 cntExecDS_init = 0 cntExecDS = 0 cntExecCont = 0 cntExecContTrue = 0 cntExecAS = 0 dscnt = 0 execds = "" for trig in triggers: triggercnt += 1 resultstr = resultstr+" Trigger "+str(triggercnt)+' : ' if (trig.triggertyp == "FILTER"): lea=trig.trigger_raw_condition.split(',') _logger.info("Trigger in run_Cron_triggers - : Filtered Datasets "+str(lea)) AllDataset = self.env[str(triggergroup.trigger_table.model)].search([lea]) else: AllDataset = self.env[str(triggergroup.trigger_table.model)].search([]) _logger.info("Trigger in run_Cron_triggers - : All Datasets "+str(len(AllDataset))) resultstr = " Count Data : "+str(len(AllDataset)) for Dataset in AllDataset: dscnt += 1 resultstr = resultstr+" Data "+str(dscnt)+' : ' _logger.info("Trigger in run_Cron_triggers - : "+str(Dataset)+" check allready execute : "+str(Dataset.uuid)+" "+str(date.today())) isinintitable = self.env['dss.triggermodel.execute'].search(['&',('trigger','=',trig.id),('data_uuid','=',Dataset.uuid),('execdatetime','=',date.today())]) dotrigger = False if (not isinintitable) and trig.trigger_init_trigger: _logger.info("Trigger in run_Cron_triggers - first run and allowed : "+str(isinintitable)+' -> '+str(trig.trigger_init_trigger)+' -> '+str(trig)) dotrigger = True elif (not isinintitable) and ((not trig.trigger_init_trigger) and (not trig.trigger_onlyinit_trigger)): _logger.info("Trigger in run_Cron_triggers - first run but not allowed : "+str(isinintitable)+' -> '+str(trig.trigger_init_trigger)+' -> '+str(trig)) dotrigger = False elif (isinintitable) and trig.trigger_onlyinit_trigger: _logger.info("Trigger in run_Cron_triggers - not first run but only first (or day): "+str(isinintitable)+' -> '+str(trig.trigger_onlyinit_trigger)+' -> '+str(trig)) dotrigger = False else: _logger.info("Trigger in run_Cron_triggers - running no given restrictions : "+str(isinintitable)+' -> '+str(trig)) dotrigger = True if dotrigger: cntExecDS_init += 1 if (trig.triggertyp == "FILTER"): runtrigger = True elif (trig.triggertyp == "COND"): runtrigger = True for SingleC in trig.trigger_conditions: cntExecCont += 1 _logger.info("Trigger in run_Cron_triggers - Multible Conditions found "+str(trig.trigger_conditions)+' -> '+str(SingleC)+' -> '+str(runtrigger)) conres = SingleC.trigger_CheckCond(Dataset,SingleC) runtrigger = conres and runtrigger if conres: cntExecContTrue += 1 else: _logger.info("Trigger Abgebrochen ! in ZeitGruppen sind nur BedingungsTrigger Erlaubt "+str(trig.trigger_aktionen)) runtrigger = False _logger.info("Trigger in run_Cron_triggers - Conditions result "+str(runtrigger)) if runtrigger: cntExecDS += 1 _logger.info("Trigger wird Ausgeführt - Aktionen "+str(trig.trigger_aktionen)) resultstr = resultstr + " Anz Aktionen : "+str(len(trig.trigger_aktionen)) execds = self.trigger_run(trig,Dataset,isinintitable,execds) _logger.info("Result :"+resultstr) _logger.info("-------------------------------------- CRON Trigger Result --------------------------------------------------------------------") _logger.info("Result :"+resultsimplestr) _logger.info("Result : Anz. CondChecks : "+str(cntExecDS_init)) _logger.info("Result : Anz. Conditions : "+str(cntExecCont)) _logger.info("Result : Anz. ConditionsTrue : "+str(cntExecContTrue)) _logger.info("Result : Anz. ConditionsFalse : "+str(cntExecCont - cntExecContTrue)) _logger.info("Result : Anz. Conditionok : "+str(cntExecDS)) _logger.info("Result : Anz. ExecAction : "+str(cntExecAS)) _logger.info("Result : Exec Datasets : "+execds) _logger.info("-------------------------------------------------------------------------------------------------------------------------------") def exectrigger(self): _logger.info("Trigger Sofort Execute !"+str(self)) if self.trigger_cron: self.run_cron_triggers(self,self.triggers) else: self.run_triggers(False,False,self.triggers) class dsstriggertypes(models.Model): _name = "dss.triggertypes" _description = "DigitalSignage Trigger Typen" _inherit = ['mail.thread','mail.activity.mixin'] _rec_name = "triggername" uuid = fields.Char(default=lambda self: self._default_uuid(), required=True, readonly=True, copy=False, string='UUID') date_create = fields.Date('Erstellungsdatum',default=lambda self: self._default_create_date()) date_lastedit = fields.Date('Änderungsdatum') user_create = fields.Char('Erstellungsuser',default=lambda self: self._default_create_user()) user_lastedit = fields.Char('Änderungsuser') triggername = fields.Char('Triggername',tracking=True) triggergruppe = fields.Char('Triggergruppe',tracking=True) trigger_active = fields.Boolean('Trigger Aktiv ?',tracking=True) triggertyp = fields.Selection([('FIELD_A','Feldänderung allgemein'),('FIELD_S','Feldänderung spezifisch'),('FIELD_B','Feldänderung BOOL'),('FIELD_K','Feldwert berechnet'),('COND','Bedingungen prüfen'),('MANUAL','Manuell ausgelösst'),('FILTER','Manuell gefiltert')],'Triggertyp',tracking=True) trigger_table = fields.Many2one('ir.model','Nutzbar in',help='Für welche Daten ist dieser Tigger gültig ?',tracking=True) trigger_field = fields.Many2one('ir.model.fields', string="Auslöser Feld",help='Triggerfeldname in der Tabelle - Änderungen an dem Feld lösen den Trigger aus',tracking=True) trigger_operator = fields.Selection([('NGLEICH','Feld gleich dem Wert'),('GGLEICH','Feld größer/gleich dem Wert'),('KGLEICH','Feld kleiner/gleich dem Wert'),('GROESSER','Feld grösser dem Wert'),('KLEINER','Feld kleiner dem Wert'),('UGLEICH','Feld ungleich dem Wert'),('ENTHAELT','Feld enthällt dem Wert')],'Feldwertoperator',tracking=True) trigger_time_opperator = fields.Selection([('TAG','Aktueller Tag'),('TIME','Aktuelle Zeit'),('JAHR','Aktuelles Jahr'),('FIX','Feste Zeit')],'Vergleichswert',tracking=True) trigger_init_trigger = fields.Boolean('Ausl. bei 1. Änderung ?',help='Soll der Trigger bereits beim setzen des 1. Wertes auslösen?',tracking=True) trigger_onlyinit_trigger = fields.Boolean('Ausl. nur bei 1. Änderung ?',help='Soll der Trigger nur beim setzen des 1. Wertes auslösen?',tracking=True) trigger_plus_conditions = fields.Boolean('Zusätz. Bedingungen prüfen',help='Soll der Trigger zusätzlich zur Auslösung Bedingungen prüfen?',tracking=True) trigger_value_field = fields.Many2one('ir.model.fields',string="Vergleichsfeld Feld", help='Prüfungsfeldname in der Tabelle - für dieses Feld wird der Wert geprüft',tracking=True) trigger_value = fields.Char('Feldwert für Trigger',tracking=True) trigger_value_Bool = fields.Boolean('Feldwert für Trigger (Ja/Nein)',tracking=True) trigger_conditions = fields.Many2many('dss.triggerconditions',string='Bedingungen zum auslösen des Triggers',tracking=True) trigger_aktionen = fields.Many2many('dss.triggeractions',string='Aktionen bei auslösen des Triggers',tracking=True) trigger_aktionen_groups = fields.Many2many('dss.triggeractions.groups',string='Aktionsgruppen bei auslösen des Triggers',tracking=True) trigger_raw_condition = fields.Char('Datensatz Auswahl',tracking=True) trigger_is_block_config = fields.Boolean('Blockly Trigger Design',tracking=True) trigger_block_config = fields.Char('Blockly Design',tracking=True) trigger_block_raw_config = fields.Char('Blockly command Design',tracking=True) trigger_block_command_uptodate = fields.Boolean('Blockly command aktuell',tracking=True) trigger_block_command = fields.Char('Blockly command',tracking=True) @api.model def _default_uuid(self): return str(uuid.uuid4()) def _default_create_date(self): return str(date.today()) def _default_create_user(self): return str(self.env.user.name) def getfield(self,model,field_name): value = model for part in field_name.split('.'): value = getattr(value,part) return value def _check_trigger(self,DataRecord): return "" @api.model def gettriggerbyname(self,triggername): _logger.info("Trigger get Triggerbyname !"+str(triggername)) return self.env['dss.triggertypes'].search([('triggername','=',triggername)]) @api.model def gettriggerblocksyntaxbyname(self,triggername): _logger.info("Trigger get Trigger Block Syntax by Name !"+str(triggername)) foundtrigger = self.env['dss.triggertypes'].search([('triggername','=',triggername)]) blocksyntax = {} if foundtrigger: blocksyntax = foundtrigger.read()[0] if foundtrigger else {} else: blocksyntax = {} return blocksyntax @api.model def gettablebyid(self,tableid): _logger.info("Trigger get tablename by Tableid !"+str(tableid)) return str(self.env['ir.model'].search([('id','=',tableid)]).model) @api.model def getfieldbyid(self,fieldid): _logger.info("Trigger get fieldname-mix by fieldid !"+str(fieldid)) feld = self.env['ir.model.fields'].search([('id','=',fieldid)]) return str(str(feld.field_description+' ('+feld.name+')')) @api.model def getbyid(self,modelid,searchfield,searchid): _logger.info("Trigger get modelid by searchid !"+str(searchid)) foundtrigger = self.env[modelid].search([(searchfield,'=',searchid)]) blocksyntax = {} if foundtrigger: blocksyntax = foundtrigger.read()[0] if foundtrigger else {} else: blocksyntax = {} return blocksyntax @api.model def getall(self,modelid): _logger.info("Trigger get all !"+str(modelid)) foundtrigger = self.env[modelid].search([]) _logger.info("Trigger get all !"+str(foundtrigger)) blocksyntax = [] if foundtrigger: blocksyntax = [record.read()[0] for record in foundtrigger] if foundtrigger else [] else: blocksyntax = [] _logger.info("Trigger get all !"+str(blocksyntax)) return blocksyntax def execute_trigger(self): if self.trigger_block_raw_config: a=1 else: a=2 def handleNewClick(self): return True def handleSaveClick(self): return True def handleGenerateClick(self): return True def handleRedrawClick(self): return True @api.model def NewBlockTrigger(self,triggername,triggeraktiv): _logger.info("Trigger New Block Trigger !"+str(triggername)) newtrigger = self.env['dss.triggertypes'].create({'triggername':triggername,'trigger_is_block_config':True,'trigger_active':triggeraktiv}) return newtrigger @api.model def UpdateBlockTrigger(self,triggername,blockcode,triggeraktiv ): _logger.info("Trigger Update Block Trigger !"+str(triggername)) foundtrigger = self.env['dss.triggertypes'].search([('triggername','=',triggername)]) if foundtrigger: foundtrigger.write({'trigger_block_raw_config':blockcode,'trigger_active':triggeraktiv,'trigger_block_command_uptodate':False}) return foundtrigger @api.model def execTriggerTest(self,sourcecode,sampletable,sampleid): _logger.info("Trigger Exec Trigger Test !"+str(sourcecode)+' / '+str(sampletable)+' / '+str(sampleid)) try: Dataset = self.env[sampletable].search([('id','=',sampleid)]) _logger.info("Trigger Exec Trigger Test Dataset !"+str(Dataset)) self.env['ir.config_parameter'].sudo().set_param('dss.global.trigger_sample_table', sampletable) self.env['ir.config_parameter'].sudo().set_param('dss.global.trigger_sample_id', sampleid) exec(sourcecode) return "OK" except Exception as e: _logger.error("Trigger Exec Trigger Test Error !"+str(e)) return "Error :"+str(e) class dsstriggeractions(models.Model): _name = "dss.triggeractions" _description = "DigitalSignage Trigger Aktionen" _inherit = ['mail.thread','mail.activity.mixin'] _rec_name = "triggeractionname" _order = "triggeractionprio" uuid = fields.Char(default=lambda self: self._default_uuid(), required=True, readonly=True, copy=False, string='UUID') date_create = fields.Date('Erstellungsdatum',default=lambda self: self._default_create_date()) date_lastedit = fields.Date('Änderungsdatum') user_create = fields.Char('Erstellungsuser',default=lambda self: self._default_create_user()) user_lastedit = fields.Char('Änderungsuser') BotText = fields.Html('Ausgabetext') triggeractionprio = fields.Integer('Priorität',tracking=True) Info_Subject = fields.Char('InfoÜberschrift') followaction = fields.Boolean('Folgeaktion vorhanden',tracking=True) has_trigger_action_conditions = fields.Boolean('Bedingungen vorhanden',help="Sind Bedingungen vor Ausführung vorhanden?",tracking=True) trigger_conditions = fields.Many2many('dss.triggerconditions',string='Bedingungen zum Ausführen der Aktion',tracking=True) trigger_aktionen_active = fields.Boolean('Trigger Aktion aktiv',tracking=True) trigger_table = fields.Many2one('ir.model','Nutzbar in',help='Für welche Daten ist dieser Tigger gültig ?',tracking=True) triggeractionname = fields.Char('Triggeraktionname',tracking=True) triggeractiontyp = fields.Selection([('EMAIL','EMail an senden'),('NOTIZ','Notitz erstellen'),('MESSA','Message an Follower senden'),('CHANNEL','Message an Channel senden'),('ACTIV','Aufgabe erzeugen'),('MARKER','Marker eintragen'),('DSEDIT','Akt. Datensatz ändern'),('TUYA','Tuya Aktion auslössen'),('PRUEF','Wert prüfen')],'Aktionstyp',tracking=True) email_getfrom = fields.Selection([('FIX','Email fest hinterlegt'),('DATA','Email in Feld hinterlegt')],'Emailadresse von',tracking=True) email_send_confirm = fields.Boolean('Email Bestätigen vor senden',tracking=True) email_fix_email_sender = fields.Many2one('res.partner','Absender',help='Email Sender Adresse der Aktion',tracking=True) email_fix_email = fields.Many2one('res.partner','Empfänger fix',help='Email Emüfänger Adresse für Benachrichtigung/Triggeraktion',tracking=True) email_data_table = fields.Many2one('ir.model','EmailDaten in',help='Für welche Daten ist diese Aktion gültig ?',tracking=True) email_data_field = fields.Many2one('ir.model.fields','Empfänger Feld', help='Feldname in der Tabelle',tracking=True) email_template = fields.Many2one('mail.template','Emailvorlage',tracking=True) email_has_attachments = fields.Boolean('Email mit Anhang',tracking=True,help='Soll die Email mit Anhang versendet werden ?') email_contract_attachment_types = fields.Many2many('dss.mediatypes',tracking=True,help='Welche Dateitypen aus dem Vertrag sollen als Anhang versendet werden ?') activity_user = fields.Many2one('res.users','Empfänger der Aufgabe',tracking=True) activity_type = fields.Many2one('mail.activity.type','Art der Aufgabe',tracking=True) activity_date_type = fields.Selection([('TOPLU','Von heute in x Tagen'),('TOFIX','An einem festen Datum'),('TOFIXDB','An einem festen Datum der Datenbank'),('TOPLUDB','An einem festen Datum der Datenbank + x Tage')],tracking=True) activity_date_type_add_days = fields.Integer('x Tage Aufschlag',tracking=True) activity_date_type_fix = fields.Date('Planungsdatum ',tracking=True) activity_text = fields.Text('Inhalt der Aufgabe',tracking=True) field = fields.Char('Feldname',help='Feldname in o.g. Tebelle.',tracking=True) type_s = fields.Char('Feldwertoperator',tracking=True) value_s = fields.Char('Feldwert für Trigger',tracking=True) action_table = fields.Many2one('ir.model','Nutzbar in',help='Für welche Daten ist dieser Tigger gültig ?',tracking=True) action_field = fields.Many2one('ir.model.fields', string="Auslöser Feld",help='Triggerfeldname in der Tabelle - Änderungen an dem Feld lösen den Trigger aus',tracking=True) action_test_id = fields.Char('TestID für Triggeraktion',tracking=True) action_value_type = fields.Selection([('FIXT','Fester Wert'),('BOOL','Boolischen Wert'),('DATE','Aktuelles Datum'),('DATX','Aktuelles Datum + X'),('CALC','Berechneter Wert'),('GROS','Aus anderer Quelle')],'Wertart des Eintrags',tracking=True) action_value_fix = fields.Char('Wert zum setzen',tracking=True) action_value_bool = fields.Boolean('Boolwert zum setzen',tracking=True) action_value_fix_plus = fields.Integer('Zuschlag für Berechnung',tracking=True) action_value_from_same_table_bool = fields.Boolean('Wert aus akt. Datensatz ?',tracking=True) action_value_from_table = fields.Many2one('ir.model','Daten aus ',help='Aus welcher Datenmenge soll der Wert geholt werden ?',tracking=True) action_value_from_field = fields.Many2one('ir.model.fields','Feld aus ',help='Aus welchem Feld soll der Wert geholt werden ?',tracking=True,domain='[("model_id","=",action_value_from_table)]') postChannel = fields.Char('Kanalnummer für Post :',tracking=True) follow_action_id = fields.Many2one('dss.triggeractions', string="Nachfolgende Aktion",help='Aktion welche direkt im Anschluss unabhänig des Ablaufs ausgeführt wird',tracking=True) insert_marker = fields.Many2one('dss.marker','Marker',help='Welcher Marker soll eingefügt werden ?',tracking=True) @api.model def _default_uuid(self): return str(uuid.uuid4()) def _default_create_date(self): return str(date.today()) def _default_create_user(self): return str(self.env.user.name) def Doexecute(self,Dataset): runaction = False if self.has_trigger_action_conditions: runaction = True for SingleC in self.trigger_conditions: _logger.info("Trigger in run_triggers - Multible Conditions found "+str(self.trigger_conditions)+' -> '+str(SingleC)+' -> '+str(runaction)) runaction = SingleC.trigger_CheckCond(Dataset,SingleC) and runaction else : runaction=True if runaction: if (self.triggeractiontyp == 'EMAIL'): # mail_pool = self.env['mail.mail'] # values={} # values.update({'subject': 'Your subject'}) # values.update({'email_to': 'To email'}) # values.update({'body_html': 'body' }) # values.update({'body': 'body' }) # values.update({'res_id': 'obj.id' }) #[optional] here is the record id, where you want to post that email after sending # values.update({'model': ''Object Name }) #[optional] here is the object(like 'project.project') to whose record id you want to post that email after sending # msg_id = mail_pool.create(values) # # And then call send function of the mail.mail, # if msg_id: # mail_pool.send([msg_id]) ccmailto = self.email_template.email_cc ccmailto_org = self.email_template.email_cc if not ccmailto: ccmailto='' mailto = "" if self.email_getfrom == "FIX": mailto = "" for partner in self.email_fix_email: mailto = mailto+';'+partner.email _logger.info('Trigger Aktion TRA_' + str(self)+' Sending Email - FIX Empfänger : '+str(self.email_getfrom)+' -> '+str(mailto)) elif self.email_getfrom == "DATA": mailto = str(Dataset[self.email_data_field.name]) _logger.info('Trigger Aktion TRA_' + str(self)+' Sending Email - DATA Empfänger : '+str(self.email_getfrom)+' -> '+str(mailto)) else: mailto = "technik@logumedia.de" _logger.info('Trigger Aktion TRA_' + str(self)+' Sending Email - NONE Empfänger : '+str(self.email_getfrom)+' -> '+str(mailto)) if 'contract_writer_mailcc' in self.env[str(self.trigger_table.model)]._fields: mailcc = Dataset["contract_writer_mailcc"] if mailcc: VsPartner = self.env['res.partner'].search([('id','=',Dataset.contract_writer.id)]) ccmailto = ccmailto+';'+VsPartner.email _logger.info('Trigger Aktion TRA_' + str(self)+' Sending Email CC Writer - FIX Empfänger : '+str(VsPartner)+' -> '+str(ccmailto)+' + '+str(VsPartner.email)) _logger.info('Trigger Aktion TRA_' + str(self)+' Sending Email - Template : '+str(self.email_template)+" Empfänger :"+str(mailto)+'/'+str(ccmailto)+' -> '+str(Dataset)) self.email_template.email_to = mailto self.email_template.email_cc = ccmailto if self.email_has_attachments: _logger.info('Trigger Aktion TRA_' + str(self)+' Sending Email - Anhang : '+str(self.email_contract_attachment_types)) attachments = [] for mediatype in self.email_contract_attachment_types: _logger.info('Trigger Aktion TRA_' + str(self)+' Sending Email - Anhang : '+str(mediatype)) single_attachment = Dataset.get_attachments_by_mediatype(mediatype) if single_attachment: _logger.info('Trigger Aktion TRA_' + str(self)+' Sending Email - Anhang erzeugen : '+str(single_attachment)) if single_attachment.binary_filename: fname = single_attachment.binary_filename else: fname = single_attachment.binary_name att_id = self.env['ir.attachment'].create({'name': fname, 'datas': single_attachment.binary_binary}) _logger.info('Trigger Aktion TRA_' + str(self)+' Sending Email - Anhang wurde erzeugen : '+str(att_id)) self.email_template.attachment_ids = [(4, att_id.id)] _logger.info('Trigger Aktion TRA_' + str(self)+' Sending Email - Anhang neu : '+str(self.email_template.attachment_ids)) if not self.email_send_confirm: self.email_template.send_mail(Dataset.id,force_send=True) else: action = (self.env["confirmation.wizard"].confirm_message( _("Möchten Sie die EMail versenden ?"),self.email_template, # One or more records title="Bestätigen",method="Email senden ",callback_params={"Email": mailto})) if action: self.email_template.send_mail(Dataset.id,force_send=True) self.email_template.attachment_ids = [(5,0,0)] # Clear attachments after sending self.email_template.email_cc = ccmailto_org elif (self.triggeractiontyp == 'DSEDIT'): _logger.info('Trigger Aktion TRA_' + str(self)+' Setze Wert für DS_'+str(Dataset)+' FLD_'+str(self.action_field.name)+' - Typ : '+str(self.action_value_type)+' -> '+str(self.action_value_bool)) EditFeld = Dataset[self.action_field.name] field = Dataset._fields[self.action_field.name] field_type = field.type if (self.action_value_type == 'BOOL'): _logger.info('Trigger Aktion TRA_' + str(self)+' Setze Wert - Typ : '+str(self.action_value_type)+' / '+str(EditFeld)+' -> '+str(self.action_value_bool)) EditFeld = Dataset.write({self.action_field.name : self.action_value_bool}) if (self.action_value_type == 'DATE'): _logger.info('Trigger Aktion TRA_' + str(self)+' Setze Wert - Typ : '+str(self.action_value_type)+' / '+str(EditFeld)+' -> '+str(date.today())) EditFeld = Dataset.write({self.action_field.name : date.today()}) if (self.action_value_type == 'DATX'): _logger.info('Trigger Aktion TRA_' + str(self)+' Setze Wert - Typ : '+str(self.action_value_type)+' / '+str(EditFeld)+' -> '+str(date.today())+' + '+str(self.action_value_fix_plus)+' = '+str(date.today()+ relativedelta(days=self.action_value_fix_plus))) EditFeld = Dataset.write({self.action_field.name : date.today() + relativedelta(days=self.action_value_fix_plus)}) if (self.action_value_type == 'FIXT'): _logger.info('Trigger Aktion TRA_' + str(self)+' Setze Wert - Typ : '+str(self.action_value_type)+' / '+str(EditFeld)+' (Type : '+str(field_type)+') -> '+str(self.action_value_fix)) if (field_type == "many2one"): Dataset[self.action_field.name] = int(self.action_value_fix) elif (field_type == "date"): Dataset.write({self.action_field.name : self.action_value_fix}) else: Dataset.write({self.action_field.name : self.action_value_fix}) if (self.action_value_type == 'GROS'): if (self.action_value_from_same_table_bool): Dataset[self.action_field.name] = Dataset[self.action_value_from_field.name] elif (self.triggeractiontyp == 'ACTIV'): deadline = datetime.now() if self.activity_date_type == 'TOPLU': deadline = datetime.now() deadline = deadline + relativedelta(days=self.activity_date_type_add_days) elif self.activity_date_type == 'TOFIX': deadline = self.activity_date_type_fix elif self.activity_date_type == 'TOFIXDB': deadline = Dataset[self.action_field.name] elif self.activity_date_type == 'TOPLUDB': deadline = Dataset[self.action_field.name] deadline = deadline + relativedelta(days=self.activity_date_type_add_days) if not Dataset: _logger.info('Trigger Aktion TRA_' + str(self)+' Create Task - No Dataset - use Test '+str(self.trigger_table)+' '+str(self.action_test_id)) ds = self.env[self.trigger_table.model].search([('id','=',self.action_test_id)]) else: ds = Dataset if not self.trigger_table: _logger.info('Trigger Aktion TRA_' + str(self)+' Create Task - No Model '+str(ds)+' '+str(self.trigger_table)) else: _logger.info('Trigger Aktion TRA_' + str(self)+' Create Task '+str(self.Info_Subject)+' ('+str(self.activity_user)+') - Model : '+str(self.trigger_table.id)+'/'+str(ds.id)+' '+str(deadline)) self.env['mail.activity'].create({ 'display_name': self.Info_Subject, 'summary': self.activity_text, 'date_deadline': deadline, 'user_id': self.activity_user.id, 'res_id': ds.id, 'res_model_id': self.trigger_table.id, 'activity_type_id': self.activity_type.id }) _logger.info('Trigger Aktion TRA_' + str(self)+' Create Task '+str(self.Info_Subject)+' ('+str(self.activity_user)+') - Model : '+str(self.trigger_table.id)+'/'+str(Dataset.id)+' '+str(deadline)) elif (self.triggeractiontyp == 'MARKER'): _logger.info('Trigger Aktion TRA_' + str(self)+' Insert Marker '+str(Dataset.marker_list)+' ('+str(self.insert_marker)+') - Model : '+str(self.trigger_table.id)+'/'+str(Dataset.id)) Dataset.marker_list = [(4,self.insert_marker.id)] elif (self.triggeractiontyp == 'CHANNEL'): if (not self.BotText): self.BotText='' body = self.BotText + '('+str(self.id)+')' Channel = self.env["mail.channel"].browse(int(self.postChannel)) Channel.message_post(body=body,author_id=self.env.ref('base.partner_root').id,subject=self.Info_Subject,message_type="comment",subtype_xmlid="mail.mt_comment") _logger.info('Trigger Aktion TRA_' + str(self)+' Post channel '+str(self.postChannel)+' ('+str(Channel.name)+') - Text : '+str(body)) elif (self.triggeractiontyp == 'NOTIZ'): if (not self.BotText): self.BotText='' body = self.BotText + '('+str(self.id)+')' # body = 'Für die Werbekampagne '+str(record.adname)+' im Vertrag '+str(record.contract.contract_auto_name)+' des Projektes '+str(record.project.projektname)+' wurde der Korekturabzug automatisch durch Zeitablauf bestätigt !' Dataset.message_post(body=body,author_id=self.env.ref('base.partner_root').id,subject=self.Info_Subject) # self.env['mail.message'].create({'message_type': 'comment','subtype_id': self.env.ref('mail.mt_comment').id, # 'model': 'mail.channel','res_id': self.env.ref('mail.channel_all_employees').id,'body': body,'subject': akt.Info_Subject,}) _logger.info('Trigger Aktion TRA_' + str(self)+' Create notice '+str(self.Info_Subject)+' + Text : '+str(body)) elif (self.triggeractiontyp == 'MESSA'): partner_ids = Dataset.message_follower_ids.partner_id.ids if (not self.BotText): self.BotText='' body = self.BotText + '('+str(self.id)+')' #while '{#' in str(body): _logger.info('Trigger Aktion TRA_' + str(self)+' Sende Message '+str(partner_ids)+' + Text : '+str(body)) # Dataset.message_post(body=body,author_id=self.env.ref('base.partner_root').id,subject=self.Info_Subject,partner_ids=partner_ids) # self.env['mail.message'].create({'message_type': 'comment','subtype_id': self.env.ref('mail.mt_comment').id, # 'model': 'mail.channel','res_id': self.env.ref('mail.channel_all_employees').id,'body': body,'subject': akt.Info_Subject,}) return True def exectriggeraction(self): _logger.info('Trigger Aktion Sofortauslösung TRA_' + str(self)+' '+str(self.trigger_table.model)+' Testid :'+str(self.action_test_id)) Dataset = self.env[str(self.trigger_table.model)].search([('id','=',self.action_test_id)], limit=1) self.Doexecute(Dataset) class dsstriggermodel(models.Model): _name = "dss.triggermodel" _description = "DigitalSignage Trigger Model für Inherit" _rec_name = "trigger_uuid" trigger_uuid = fields.Char(default=lambda self: self._default_uuid(), required=True, readonly=True, copy=False, string='UUID') run_trigger = fields.Boolean('Trigger aktiv') run_uni_trigger = fields.Boolean('Allgemeine Trigger aktiv',default=True) run_uni_sub_trigger = fields.Boolean('Allgemeine Trigger (Sub) aktiv',default=True) triggergroup = fields.Many2one('dss.triggergroups',string='Triggergruppe') @api.model def _default_uuid(self): return str(uuid.uuid4()) @api.model def trigger_track_template(self, changes, Dataset): _logger.info("Trigger in track_template - "+str(Dataset)+" - Changes : "+str(changes)) if Dataset.run_trigger: _logger.info("Trigger in track_template - "+str(Dataset.triggergroup)+" - Changes : "+str(changes)) Dataset.triggergroup.run_triggers(changes, Dataset, Dataset.triggergroup.triggers) if Dataset.run_uni_trigger: _logger.info("Trigger in track_template - UNIVERSAL - Suche Triggergruppen : id :"+str(Dataset._name)) triggergroups = self.env['dss.triggergroups'].search([('trigger_table','=',Dataset._name),('trigger_allgemein','=',True)]) _logger.info("Trigger in track_template - UNIVERSAL - Triggergruppen gefunden : "+str(triggergroups)) for trig in triggergroups: trig.run_triggers(changes, Dataset, trig.triggers) class dsstriggeractiongroupss(models.Model): _name = "dss.triggeractions.groups" _description = "DigitalSignage Trigger Aktionen Gruppen" _inherit = ['mail.thread','mail.activity.mixin'] _rec_name = "triggeractiongroupname" uuid = fields.Char(default=lambda self: self._default_uuid(), required=True, readonly=True, copy=False, string='UUID') date_create = fields.Date('Erstellungsdatum',default=lambda self: self._default_create_date()) date_lastedit = fields.Date('Änderungsdatum') user_create = fields.Char('Erstellungsuser',default=lambda self: self._default_create_user()) user_lastedit = fields.Char('Änderungsuser') triggeractiongroupname = fields.Char('Triggeraktion Gruppenname',tracking=True) trigger_list = fields.Many2many('dss.triggeractions',string='Enthaltene Trigger',help='Welche Trigger sollen ausgeführt werden ?',tracking=True) action_test_id = fields.Char('TestID für Triggeraktion',tracking=True) trigger_table = fields.Many2one('ir.model','Nutzbar in',help='Für welche Daten ist dieser Tigger gültig ?',tracking=True) @api.model def _default_uuid(self): return str(uuid.uuid4()) def _default_create_date(self): return str(date.today()) def _default_create_user(self): return str(self.env.user.name) def Doexecute(self,Dataset,trig,isinintitable): for akt in self.trigger_list: _logger.info("Trigger in ExecTrigger_Group - Aktion "+str(akt)) akt.Doexecute(Dataset) if not isinintitable: self.env['dss.triggermodel.execute'].create({'trigger':trig.id,'data_uuid':Dataset.uuid,'execdatetime':date.today(),"trigger_table":self.env['ir.model'].search([('model','=',str(akt.trigger_table.model))]).id,"trigger_action":akt.id}) else: _logger.info("Trigger in Trigger_group_run - no Aktion in Trigger !") def DoexecuteGroup(self,Dataset): for akt in self.trigger_list: _logger.info("Trigger in ExecTrigger_Group - Aktion "+str(akt)) akt.Doexecute(Dataset) def exectriggeraction_group(self): _logger.info('Trigger Aktion Sofortauslösung TRA_G' + str(self)+' '+str(self.trigger_table.model)+' Testid :'+str(self.action_test_id)) Dataset = self.env[str(self.trigger_table.model)].search([('id','=',self.action_test_id)], limit=1) self.DoexecuteGroup(Dataset)