diff --git a/__init__.py b/__init__.py index 0650744..f7209b1 100755 --- a/__init__.py +++ b/__init__.py @@ -1 +1,2 @@ from . import models +from . import controllers diff --git a/__manifest__.py b/__manifest__.py index 57d0f48..4064d10 100755 --- a/__manifest__.py +++ b/__manifest__.py @@ -25,24 +25,31 @@ 'views/dss_geraetetypen.xml', 'views/dss_texts.xml', 'views/dss_systems.xml', + 'views/dss_screendesign.xml', + 'views/dss_trigger_actions.xml', + 'views/dss_eventdays.xml', + 'views/dss_triggertypes.xml', 'views/mainsystem_view.xml', 'views/menu.xml', 'views/company_view.xml', + 'views/google_map_templates.xml' ], 'demo': [], 'installable': True, 'application': True, 'images': ['static/description/banner.gif'], 'auto_install': False, - 'css': ['static/src/css/dss.css'], 'assets': { + 'web.assets_backend': [ + 'DigitalSignage/static/src/**/*', + 'DigitalSignage/static/src/xml/screenDesignerView.xml', + ], 'web.assets_common': [ - 'DigitalSignage/static/images/**/*', + 'DigitalSignage/static/images/**/*', 'DigitalSignage/static/src/css/dss.css', ], - 'web.assets_backend': [ - ], 'web.assets_qweb': [ + 'DigitalSignage/static/src/xml/*', ], }, 'license': 'LGPL-3', diff --git a/getimg.sh b/getimg.sh new file mode 100755 index 0000000..3b6cb2e --- /dev/null +++ b/getimg.sh @@ -0,0 +1 @@ +curl https://upload.diebesorger.com/f.php?h=1DWnJR2Q&d=1 \ No newline at end of file diff --git a/models/dss.py b/models/dss.py index 0173955..27551de 100755 --- a/models/dss.py +++ b/models/dss.py @@ -18,7 +18,11 @@ from odoo import tools from odoo.exceptions import ValidationError from datetime import date from pyffmpeg import FFmpeg +from tuya_iot import TuyaOpenAPI, TUYA_LOGGER +from tuya_connector import TuyaOpenAPI, TUYA_LOGGER +import sys +TUYA_LOGGER.setLevel(logging.DEBUG) _logger = logging.getLogger(__name__) def _generate_preview_from_binary(self, videofile_file): @@ -54,6 +58,7 @@ class dssimport(models.Model): return action class dssSettings(models.Model): + _name = "dss.settings" _description = "DigitalSignage Einstellungen" uuid = fields.Char(default=lambda self: self._default_uuid(), required=True, readonly=True, copy=False, string='UUID') @@ -63,6 +68,13 @@ class dssSettings(models.Model): def_contract_cloudpath_sample = fields.Char('Projekt Beispiel :') def_ad_cloudpath = fields.Char('Standard Kampagnen Pfad') def_ad_cloudpath_sample = fields.Char('Kampagnen Beispiel :') + tuya_access_id = fields.Char('Tuya Access ID') + tuya_access_key = fields.Char('Tuya Access KEY') + tuya_endpoint = fields.Char('Tuya Access Endpoint') + def _get_settingvalue(self,valuename): + settings = (self.env['dss.settings'].search([],limit=1)) + wert = settings._origin.read([valuename])[0][valuename] + return wert def _get_path_converted(self,path,record): alls = '' @@ -161,8 +173,8 @@ class dsscontracts(models.Model): contract_name = fields.Char('Kurzbezeichnung', required=True,tracking=True) contract_state = fields.Many2one('dss.contractstate',group_expand='_read_group_stage_ids',tracking=True) contract_state_order = fields.Integer(related='contract_state.order',store=True) - contract_auto_id = fields.Char("Kundennummer",tracking=True) - contract_auto_name = fields.Char('Vertragskennug',tracking=True) + contract_auto_id = fields.Char("Kundennummer",tracking=True,help="Wird berechnet aus Projektnummer + Kunden ID") + contract_auto_name = fields.Char('Vertragskennug',tracking=True,help="Wird berechnet aus Kundennummer + Vertragskennung") contract_remark = fields.Html('Vertragshinweise',tracking=True) @@ -171,8 +183,8 @@ class dsscontracts(models.Model): projectIid = fields.Integer('Project IID',tracking=True) project_ad_structure = fields.Many2one(related='project.grundsystem_default_adstructure', string='Aufbau') - client = fields.Many2one('res.partner',domain="['&',('dsspartner','=',True),('dsspartner_werbung','=',True)]",tracking=True) - client_id = fields.Char("Kundenid",tracking=True) + client = fields.Many2one('res.partner',domain="['&',('dsspartner','=',True),('dsspartner_werbung','=',True)]",tracking=True,help="Nur zu Benutzen wenn Kunden als Kontakt angelegt wurde") + client_id = fields.Char("Kundenid",tracking=True,help="Nur der 2 stellige letzte Teil der Kundennummer") client_uuid = fields.Char(related="client.dss_uuid") parent_id = fields.Many2one('dss.contracts', string='Parent Task', index=True,tracking=True) @@ -211,7 +223,8 @@ class dsscontracts(models.Model): runtime_t = fields.Integer('Laufzeit',tracking=True) runtime_events = fields.Many2many('dss.eventdays',tracking=True) runtime_divers = fields.Char('Laufzeit',tracking=True) - + runtime_finish = fields.Date('LaufzeitEnde',tracking=True) + paymentsystems = fields.Many2one('dss.paysystems',tracking=True) intern_info_payment_off = fields.Boolean('Keine Zahl-Benachrichtigungen',tracking=True) @@ -283,11 +296,15 @@ class dsscontracts(models.Model): cname = record.contract_name resstr = "%s%s %s" % (record.project_id,record.client_id,cname) cidstr = "%s%s" % (record.project_id,record.client_id) - if resstr is None : - resstr = 'nicht ermittelbar' - _logger.debug(resstr) - self.contract_auto_name = resstr - self.contract_auto_id = cidstr + if resstr is None : + resstr = 'nicht ermittelbar' + _logger.info('Contract_client_id_change : C_' + str(self.id) + ' - '+str(cidstr)+' vs. '+str(self.contract_auto_id)+'/'+str(resstr)+' vs '+str(self.contract_auto_name)); + if not self.contract_auto_name: + self.contract_auto_name = resstr + if not self.contract_auto_id: + self.contract_auto_id = cidstr + if self.contract_auto_id == "": + self.contract_auto_id = cidstr @api.onchange('project_id') def _onchange_project_id(self): @@ -298,11 +315,15 @@ class dsscontracts(models.Model): cname = record.contract_name resstr = "%s%s %s" % (record.project_id,record.client_id,cname) cidstr = "%s%s" % (record.project_id,record.client_id) - if resstr is None : - resstr = 'nicht ermittelbar' - _logger.debug(resstr) - self.contract_auto_name = resstr - self.contract_auto_id = cidstr + if resstr is None : + resstr = 'nicht ermittelbar' + _logger.info('project_id_change : C_' + str(self.id) + ' - '+str(cidstr)+' vs. '+str(self.contract_auto_id)+'/'+str(resstr)+' vs '+str(self.contract_auto_name)); + if not self.contract_auto_name: + self.contract_auto_name = resstr + if not self.contract_auto_id: + self.contract_auto_id = cidstr + if self.contract_auto_id == "": + self.contract_auto_id = cidstr @api.onchange('contract_name') def _onchange_contract_name(self): @@ -312,10 +333,34 @@ class dsscontracts(models.Model): else: cname = record.contract_name resstr = "%s%s %s" % (record.project_id,record.client_id,cname) - if resstr is None : - resstr = 'nicht ermittelbar' - _logger.debug(resstr) - self.contract_auto_name = resstr + cidstr = "%s%s" % (record.project_id, record.client_id) + if resstr is None : + resstr = 'nicht ermittelbar' + _logger.info('Contract_Name_Change : C_' + str(self.id) + ' - '+str(cidstr)+' vs. '+str(self.contract_auto_id)+'/'+str(resstr)+' vs '+str(self.contract_auto_name)); + if not self.contract_auto_name: + self.contract_auto_name = resstr + if not self.contract_auto_id: + self.contract_auto_id = cidstr + if self.contract_auto_id == "": + self.contract_auto_id = cidstr + @api.onchange('contract_auto_id') + def _onchange_contract_auto_id(self): + for record in self : + if record.contract_name == '' : + cname = 'unbekannter Kunden' + else: + cname = record.contract_name + resstr = "%s%s %s" % (record.project_id,record.client_id,cname) + cidstr = "%s%s" % (record.project_id, record.client_id) + if resstr is None: + resstr = 'nicht ermittelbar' + _logger.info('Contract_auto_id_change : C_' + str(self.id) + ' - '+str(cidstr)+' vs. '+str(self.contract_auto_id)+'/'+str(resstr)+' vs '+str(self.contract_auto_name)); + if not self.contract_auto_name: + self.contract_auto_name = resstr + if not self.contract_auto_id: + self.contract_auto_id = cidstr + if self.contract_auto_id == "": + self.contract_auto_id = cidstr # @api.model # def create(self,vals): @@ -368,6 +413,20 @@ class dsscontracts(models.Model): else: _logger.info('Click auf Werbekampagne : C_'+str(self.id)+'A_'+str(ds.id)+' - Kampagne gefunden ') self.ads_last_ad = ds +# prüfen ob Contract_autoname + resstr = '' + if not self.contract_auto_name: + _logger.info('Click auf Werbekampagne : C_'+str(self.id)+'A_'+str(ds.id)+' - Kein Contract_autoname ') + if self.contract_name == '': + cname = 'unbekannter Kunden' + else: + cname = self.contract_name + resstr = "%s%s %s" % (self.project_id, self.client_id, cname) + if not resstr: + resstr = 'nicht ermittelbar' + _logger.debug(resstr) + self.contract_auto_name = resstr + _logger.info('Click auf Werbekampagne : C_' + str(self.id) + 'A_' + str(ds.id) + ' - Contract_autoname gesetzt '+ str(resstr)+'/'+str(cidstr)) # prüfen ob LetzteKampagne medien hat _logger.info('Click auf Werbekampagne : C_'+str(self.id)+'A_'+str(ds.id)+' - Suche evtl Medien der Kampagne ') medias = self.env['dss.mediarelations'].search(['&',('contract','=',self.id),('ad','=',ds.id)]) @@ -445,12 +504,12 @@ class dsscontracts(models.Model): { 'field': feld.id, 'contract': self.id, 'project': self.project.id, 'field_uuid': feld.uuid, 'ad': kamp.id, 'relname':media.medianame,'mediatype':media.id}) _logger.info('Prüfe Medien : C_'+str(self.id)+'A_'+str(kamp.id)+' Erstelle Medium : M_'+str(media.id)+' -> '+str(newmedi.id)) - _logger.info('Prüfe Medien : C_'+str(self.id)+'A_'+str(kamp.id)+' Medien evtl erstellt ! NM_'+str(newmedi.id)) + _logger.info('Prüfe Medien : C_'+str(self.id)+'A_'+str(kamp.id)+' Medien evtl erstellt ! ') medias = self.env['dss.mediarelations'].search([('ad','=',kamp.id)]) _logger.info('Click auf Werbekampagne : C_'+str(self.id)+'A_'+str(kamp.id)+' neue Media '+str(mediaids)) kamp.write({'need_media': [(6,0,medias.ids)]}) -# self.write({'need_media': [(5,0,0)]}) -# _logger.info('Click auf Werbekampagne : C_'+str(self.id)+'K_'+str(kamp.id)+' setze Media '+str(kamp.need_media)) +# self.write({'need_media': [(5,0,0)]}) +# _logger.info('Click auf Werbekampagne : C_'+str(self.id)+'K_'+str(kamp.id)+' setze Media '+str(kamp.need_media)) else: _logger.info('Prüfe Medien : C_'+str(self.id)+'A_'+str(kamp.id)+' Medien gefunden !') if not self.werbe_feld_selected: @@ -505,10 +564,51 @@ class dsscontracts(models.Model): 'res_id':kampagne.id, 'display_name' : 'Änderung zur Werbekampagne '+kampagne.parent_ad.adname, 'domain':'[("id","=","context[kampagne_id]")]' - } + } + def setFirstKampagne(self): + for record in self: + if record.contract_auto_id: + record.tokampagne() + def setTreeStandardValues(self): + for record in self: + if record.contract_name == '': + cname = 'unbekannter Kunden' + else: + cname = record.contract_name + resstr = "%s%s %s" % (record.project_id, record.client_id, cname) + cidstr = "%s%s" % (record.project_id, record.client_id) + if resstr is None: + resstr = 'nicht ermittelbar' + _logger.info('Set Standard Values : C_' + str(record.id) + ' - ' + str(cidstr) + ' vs. ' + str( + record.contract_auto_id) + '/' + str(resstr) + ' vs ' + str(record.contract_auto_name)); + if not record.contract_auto_name: + record.contract_auto_name = resstr + if not record.contract_auto_id: + record.contract_auto_id = cidstr + if record.contract_auto_id == "": + record.contract_auto_id = cidstr - def pyaction_view_contract(self): + def setStandardValues(self): + for record in self: + if record.contract_name == '': + cname = 'unbekannter Kunden' + else: + cname = record.contract_name + resstr = "%s%s %s" % (record.project_id, record.client_id, cname) + cidstr = "%s%s" % (record.project_id, record.client_id) + if resstr is None: + resstr = 'nicht ermittelbar' + _logger.info('Set Standard Values : C_' + str(self.id) + ' - ' + str(cidstr) + ' vs. ' + str( + self.contract_auto_id) + '/' + str(resstr) + ' vs ' + str(self.contract_auto_name)); + if not self.contract_auto_name: + self.contract_auto_name = resstr + if not self.contract_auto_id: + self.contract_auto_id = cidstr + if self.contract_auto_id == "": + self.contract_auto_id = cidstr + + def pyaction_view_contract(self): view = self.env.ref('DigitalSignage.dss_main_contracts_form') _logger.debug('Click auf Vertrag : '+str(self.id)) return { @@ -542,7 +642,7 @@ class dsscontracts(models.Model): -class dssmain(models.Model): +class dssprojects(models.Model): _name = "dss.projects" _description = "DigitalSignage Projekte" _rec_name = "projektname" @@ -552,6 +652,7 @@ class dssmain(models.Model): projectid = fields.Integer('Projekt ID',tracking=True) color = fields.Char('Color Index',tracking=True) active = fields.Boolean('Active', default=True,tracking=True) + invisible = fields.Boolean('Ausgeblendet', default=False,tracking=True) name = fields.Char('Interner Name', required=True,tracking=True) aktstatus = fields.Many2one('dss.projectstate',string='Aktueller Status:',tracking=True) aktstatus_typ = fields.Selection(related='aktstatus.typ') @@ -564,12 +665,22 @@ class dssmain(models.Model): grundsystem_default_adstructure = fields.Many2one(related='grundsystemname.default_adstructure',tracking=True) grundsystemicon5050 = fields.Image(related='grundsystemname.icon_5050') grundsystem_ordner = fields.Char(related='grundsystemname.default_cloud_path') - standort = fields.Char('Hauptstandort des Projektes',tracking=True) + standort = fields.Char('Beschreibung des Standortes') + standort_strasse = fields.Char('Strasse des Projektes',tracking=True) + standort_plz = fields.Char('PLZ des Projektes',tracking=True) + standort_ort = fields.Char('Ort des Projektes',tracking=True) + standort_bundesland = fields.Many2one('res.country.state',string='Bundesland des Projektes',tracking=True) + standort_land = fields.Many2one('res.country',string='Land des Projektes',tracking=True) + standort_long = fields.Char('Standort Long des Projektes',tracking=True) + standort_lati = fields.Char('Standort Lat des Projektes',tracking=True) + standort_visible = fields.Boolean('Auf Projekt-Karte sichtbar',tracking=True) vertragsschreiber = fields.Many2one('res.partner',domain="['&',('dsspartner','=',True),('dsspartner_vertrieb','=',True)]",tracking=True) standortpartner = fields.Many2one('res.partner',domain="['&',('dsspartner','=',True),('dsspartner_standort','=',True)]",tracking=True) vertriebspartner = fields.Many2many('res.partner',domain="['&',('dsspartner','=',True),('dsspartner_vertrieb','=',True)]",tracking=True) - zeiten_on = fields.Datetime('Einschaltzeit',tracking=True) - zeiten_off = fields.Datetime('Ausschaltzeit',tracking=True) + zeiten_on = fields.Datetime('veraltet',tracking=True) + zeiten_off = fields.Datetime('veraltet',tracking=True) + zeitenf_on = fields.Float('Einschaltzeit',tracking=True) + zeitenf_off = fields.Float('Ausschaltzeit',tracking=True) errichtet_am = fields.Datetime('Errichtungstag',tracking=True) standort_inout = fields.Selection([('indoor','im Gebäude'), ('outdoor','Aussenbereich'), ('semiindoor','Überdachter Aussenbereich'),('Divers','Andere Art')],tracking=True); @@ -612,6 +723,45 @@ class dssmain(models.Model): _logger.info("Project " + str(self.id) + " deleted - using standard path") self.cloudlink = dssSettings._get_path_converted(self,self.env['dss.settings'].search([],limit=1).def_project_cloudpath,self) + def switch_invislbe(self): + return { + 'type': 'ir.actions.act_window', + 'view_type':'kanban', + 'view_mode':'kanban,tree', + 'res_model':'dss.contracts', + 'target':'current', + 'context':'{"default_project":'+str(self.id)+',"show_project_update":True}', + 'res_id':self.id, + 'display_name' : self.projektname, + 'domain':'[("project","=",'+str(self.id)+')]' + } + + @api.model + def _geo_localize(self, street='', zip='', city='', state='', country=''): + geo_obj = self.env['base.geocoder'] + search = geo_obj.geo_query_address(street=street, zip=zip, city=city, state=state, country=country) + result = geo_obj.geo_find(search, force_country=country) + if result is None: + search = geo_obj.geo_query_address(city=city, state=state, country=country) + result = geo_obj.geo_find(search, force_country=country) + return result + + def dss_geo_localize(self): + # We need country names in English below + result = self._geo_localize(self.standort_strasse, + self.standort_plz, + self.standort_ort, + self.standort_bundesland.name, + self.standort_land.name) + + if result: + self.write({ + 'standort_lati': result[0], + 'standort_long': result[1] + }) + else: + partners_not_geo_localized |= partner + return True class dssgeraetetypen(models.Model): _name = "dss.geraetetypen" @@ -632,6 +782,7 @@ class dssgeraetetypen(models.Model): has_heizung = fields.Boolean('Mit Heizsystem',tracking=True) has_klima = fields.Boolean('Mit Klimasystem',tracking=True) has_fan = fields.Boolean('Mit Ventiltorensystem',tracking=True) + has_tuya = fields.Boolean('Mit Tuyasteuerung',tracking=True) stromzaehler = fields.Many2one('dss.geraetetypen',tracking=True) stromverbrauch_avg = fields.Integer('Stromverbrauch AVG in W',tracking=True) @@ -681,6 +832,15 @@ class dssgeraetetypen(models.Model): zusatz_integrationen = fields.Many2one('dss.geraetetypen',tracking=True) zusatz_zubehoer = fields.Char('Sonstiges Zubehör',tracking=True) + tuya_Geraete_uid = fields.Char('Tuya Geräte UID',tracking=True) + tuya_Geraete_id = fields.Char('Tuya Geräte ID', tracking=True) + + tuya_can_switch = fields.Boolean('Tuya mit Schalter',tracking=True) + tuya_has_powervalue = fields.Boolean('Tuya mit Stromzähler',tracking=True) + + tuya_last_totalpower = fields.Char('Stromzähler Gesamt',tracking=True,readonly=True) + tuya_last_lastpower = fields.Char('Stromzähler Aktuell',tracking=True,readonly=True) + tuya_last_switchstate = fields.Char('Schalter Aktuell ',tracking=True,readonly=True) @api.model def _default_uuid(self): @@ -692,6 +852,57 @@ class dssgeraetetypen(models.Model): if syst.grundsystem: syst.grundsystem_kennung = syst.grundsystem.kennung + def get_value_from_tuyaresult(self,dataset,valuename): + result='' + _logger.info('Resultanfrage:' + str(dataset)+' Feld : '+str(valuename)) + for singlepart in dataset: + if singlepart: + if (singlepart['code'] == valuename): + result = singlepart['value'] + break + return result + + def pyaction_tuya_readout(self): + _logger.info('Tuya Schaltanfrage : Endpoint - ' + str(dssSettings._get_settingvalue(self,'tuya_endpoint')) + ' AccessID ' + str(dssSettings._get_settingvalue(self,'tuya_access_id')) + ' AccessKEY ' + str(dssSettings._get_settingvalue(self,'tuya_access_key'))) + openapi = TuyaOpenAPI(dssSettings._get_settingvalue(self,'tuya_endpoint'),dssSettings._get_settingvalue(self,'tuya_access_id'),dssSettings._get_settingvalue(self,'tuya_access_key')) + openapi.connect() + switchcode = eval('True') + commands = {'commands':[{'code':'switch','value': switchcode}]} +# result = openapi.post('/v1.0/iot-03/devices/{}/commands'.format(self.tuya_Geraete_id),commands) + result = openapi.get('/v1.0/iot-03/devices/{}/status'.format(self.tuya_Geraete_id)) + _logger.info('Erfolg ? :' + str(result['success'])) + success = result['success'] + if success: + _logger.info('Erfolgreiche Anfrage :' + str(result['result'])) + if self.tuya_has_powervalue: + self.tuya_last_totalpower = self.get_value_from_tuyaresult(result['result'],'forward_energy_total') + self.tuya_last_lastpower = self.get_value_from_tuyaresult(result['result'],'phase_a') + if self.tuya_can_switch: + self.tuya_last_switchstate = self.get_value_from_tuyaresult(result['result'],'switch') + else: + _logger.info('Fehlerhafte Anfrage :' + str(result['msg'])) + + def pyaction_tuya_switch(self): + _logger.info('Tuya Schaltanfrage : Endpoint - ' + str( + dssSettings._get_settingvalue(self, 'tuya_endpoint')) + ' AccessID ' + str( + dssSettings._get_settingvalue(self, 'tuya_access_id')) + ' AccessKEY ' + str( + dssSettings._get_settingvalue(self, 'tuya_access_key'))) + openapi = TuyaOpenAPI(dssSettings._get_settingvalue(self, 'tuya_endpoint'), + dssSettings._get_settingvalue(self, 'tuya_access_id'), + dssSettings._get_settingvalue(self, 'tuya_access_key')) + openapi.connect() + commands = {'commands': [{'code': 'switch', 'value': not self.tuya_last_switchstate}]} + # result = openapi.post('/v1.0/iot-03/devices/{}/commands'.format(self.tuya_Geraete_id),commands) + result = openapi.post('/v1.0/iot-03/devices/{}/commands'.format(self.tuya_Geraete_id),commands) + _logger.info('Erfolg ? :' + str(result['success'])) + success = result['success'] + if success: + _logger.info('Erfolgreiche Anfrage :' + str(result['result'])) + self.pyaction_tuya_readout() + else: + _logger.info('Fehlerhafte Anfrage :' + str(result['msg'])) + + class dsssystemtypen(models.Model): @@ -756,6 +967,7 @@ class dsssystems(models.Model): grundsystem = fields.Many2one('dss.systemtypen', string="Gerät ist nutzbar für") grundsystem_kennung = fields.Char(string='Kennung', related='grundsystem.kennung') + standort = fields.Char('Hauptstandort des Systems',tracking=True) farbe = fields.Integer('Grundfarbe') @@ -879,13 +1091,35 @@ class dsseventdays(models.Model): # uuid = fields.Char('UUID', required=True, translate=True) eventname = fields.Char('Eventname', required=True) description = fields.Text('EventBeschreibung') - eventdate = fields.Date('EventDatum', required=True) + eventstartdate = fields.Datetime('EventDatum', required=True) + eventenddate = fields.Datetime('EventDatum', required=True) color = fields.Char(string='Color Index') + username = fields.Many2one('res.users',string="Kalendercontact") + calendarevent = fields.Many2one('calendar.event') @api.model def _default_uuid(self): return str(uuid.uuid4()) + @api.model + def create(self,vals): + result = super().create(vals) + return result + + def pydocalendarEntry(self): + event = { + 'start': self.eventstartdate.strftime('%Y-%m-%d %H:%M:%S'), + 'stop': self.eventenddate.strftime('%Y-%m-%d %H:%M:%S'), + 'duration': 24, + 'allday': False, + 'partner_ids': (4,self.username.partner_id.id), + 'name': self.eventname, + 'description': self.description, + 'user_id': self.username.id, + } + _logger.debug('linking new event ' + str(event) + ' ' + str(self.uuid)) + self.calendarevent=self.env['calendar.event'].create(event) + class dsstodostatus(models.Model): @@ -920,7 +1154,7 @@ class dssadvertisefields(models.Model): _name = "dss.advertisefields" _description = "DigitalSignage Werbefelder" _inherit = ['mail.thread','mail.activity.mixin'] - _rec_name = "feldname" + _rec_name = "auto_feldname" # _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()) @@ -928,11 +1162,15 @@ class dssadvertisefields(models.Model): user_create = fields.Char('Erstellungsuser',default=lambda self: self._default_create_user()) user_lastedit = fields.Char('Änderungsuser') issaved = fields.Boolean('ist gespeichert') + # uuid = fields.Char('UUID', required=True, translate=True) + auto_feldname = fields.Char('Projekt_Feldname', required=True) + display = fields.Char('Designname') feldname = fields.Char('Feldname', required=True) project = fields.Many2one('dss.projects' , string='Project', store=True) project_id = fields.Integer(related='project.projectid', string='Project ID') contract = fields.Many2one('dss.contracts' , string='Vertrag', store=True) + contract_project_id = fields.Integer(related='contract.project_id', string='Project ID') color_used = fields.Char(string='Color Index') color_unused = fields.Char(string='Color Index') mediastructure = fields.Many2one('dss.adstructures',string='Feldaufbau',tracking=True) @@ -947,6 +1185,23 @@ class dssadvertisefields(models.Model): return str(self.env.user.name) + @api.onchange('project') + def _onchange_project(self): + autoid = "" + autoid = str(self.project_id)+"_"+str(self.feldname) + self.auto_feldname =autoid + + @api.onchange('contract') + def _onchange_contract(self): + autoid = "" + _logger.info('Contract Änderung prüfe Projekte !' + str(self.project_id) + ' / ' + str(self.contract_project_id)) + if not self.project_id == self.contract_project_id: + _logger.info('Contract Änderung unterschiedliche Projekte !'+str(self.project_id)+' / '+str(self.contract_project_id)) + raise ValidationError(_("Gewähltes Projekt und Projekt des Vertrages sind unterschiedlich !")) + else: + autoid = str(self.project_id)+"_"+str(self.feldname) + self.auto_feldname =autoid + @api.onchange('mediastructure') def _onchange_mediastructure_id(self): restr = 'keine' @@ -1232,8 +1487,8 @@ class dsscontractads(models.Model): parent_ad = fields.Many2one('dss.ads' , string='UrsprungsWerbung', store=True) parent_ad_uuid = fields.Char(related='parent_ad.uuid') description = fields.Text('Beschreibung',track_visibility='onchange') - amount = fields.Float('Extrakosten') - order = fields.Integer('Reihenfolge') + amount = fields.Float('Extrakosten',track_visibility='onchange',tracking=True) + order = fields.Integer('Reihenfolge',track_visibility='onchange',tracking=True) # need_media = fields.Many2many('dss.mediarelations','ad',string='Medien') need_media = fields.One2many('dss.mediarelations','ad',string='Medien') @@ -1405,3 +1660,120 @@ class dsscontractads(models.Model): text = self.env['dss.texts'].search([('text_id','=',tid)], limit=1) if text: self.write({'description':text.description}) + + +class dssscreendesign(models.Model): + _name = "dss.screendesign" + _description = "DigitalSignage Screen Designer" + _inherit = ['mail.thread','mail.activity.mixin'] + _rec_name = "screenname" + 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') + + screenname = fields.Char('Bildschirmname',track_visibility='onchange',tracking=True) + fields = fields.One2many('dss.advertisefields','display',string='Werbefelder',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 get_data(self): + outlist = {'uuid' : 2222} + return outlist + +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',track_visibility='onchange',tracking=True) + triggertyp = fields.Selection([('FIELD_A','Feldänderung allgemein'),('FIELD_S','Feldänderung spezifisch'),('FIELD_K','Feldwert berechnet'),('MANUAL','Menuell ausgelösst')],'Triggertyp',track_visibility='onchange',tracking=True) + trigger_table = fields.Many2one('ir.model','Nutzbar in',help='Für welche Daten ist dieser Tigger gültig ?',track_visibility='onchange',tracking=True) + trigger_field = fields.Many2one('ir.model.fields', help='Feldname in der Tabelle',track_visibility='onchange',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',track_visibility='onchange',tracking=True) + trigger_value = fields.Char('Feldwert für Trigger',track_visibility='onchange',tracking=True) + trigger_Aktionen = fields.Many2many('dss.triggeractions',string='Aktionen bei auslösen des Triggers',track_visibility='onchange',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) + +class dsstriggertypes(models.Model): + _name = "dss.triggeractions" + _description = "DigitalSignage Trigger Aktionen" + _inherit = ['mail.thread','mail.activity.mixin'] + _rec_name = "triggeractionname" + 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') + + triggeractionname = fields.Char('Triggeraktionname',track_visibility='onchange',tracking=True) + triggeractiontyp = fields.Selection([('EMAIL','EMail senden'),('ACTIV','Aufgabe erzeugen'),('DSEDIT','Datensatz ändern'),('TUYA','Tuya Aktion auslössen')],'Aktionstyp',track_visibility='onchange',tracking=True) + email_getfrom = fields.Selection([('FIX','Email fest hinterlegt'),('DATA','Email in Feld hinterlegt')],'Emailadresse von',track_visibility='onchange',tracking=True) + email_fix_email_sender = fields.Many2one('res.partner','Absender',help='Email Sender Adresse der Aktion',track_visibility='onchange',tracking=True) + email_fix_email = fields.Many2one('res.partner','Empfänger',help='Email Emüfänger Adresse für Benachrichtigung/Triggeraktion',track_visibility='onchange',tracking=True) + email_data_table = fields.Many2one('ir.model','Nutzbar in',help='Für welche Daten ist diese Aktion gültig ?',track_visibility='onchange',tracking=True) + email_data_field = fields.Many2one('ir.model.fields', help='Feldname in der Tabelle',track_visibility='onchange',tracking=True) + email_template = fields.Many2one('mail.template','Emailvorlage',track_visibility='onchange',tracking=True) + + field = fields.Char('Feldname',help='Feldname in o.g. Tebelle.',track_visibility='onchange',tracking=True) + type_s = fields.Char('Feldwertoperator',track_visibility='onchange',tracking=True) + value_s = fields.Char('Feldwert für Trigger',track_visibility='onchange',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) + +class dsstriggertypes(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',track_visibility='onchange',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) diff --git a/security/groups.xml b/security/groups.xml index d4b7f9a..3119259 100755 --- a/security/groups.xml +++ b/security/groups.xml @@ -17,4 +17,9 @@ + + Standarduser mit Tuya Berechtigung + + + \ No newline at end of file diff --git a/security/ir.model.access.csv b/security/ir.model.access.csv index d642c2f..855c8b9 100755 --- a/security/ir.model.access.csv +++ b/security/ir.model.access.csv @@ -21,3 +21,7 @@ digitalsignage_dss_mediarelations_group_user,access.dss.mediarelations,model_dss digitalsignage_dss_advertisefields_group_user,access.dss.advertisefields,model_dss_advertisefields,base.group_user,1,1,1,1 digitalsignage_dss_import_group_user,access.dss.import,model_dss_import,base.group_user,1,1,1,1 digitalsignage_dss_settings_group_user,access.dss.settings,model_dss_settings,base.group_user,1,1,1,1 +digitalsignage_dss_screendesign_group_user,access.dss.screendesign,model_dss_screendesign,base.group_user,1,1,1,1 +digitalsignage_dss_triggertypes_group_user,access.dss.triggertypes,model_dss_triggertypes,base.group_user,1,1,1,1 +digitalsignage_dss_triggeractions_group_user,access.dss.triggeractions,model_dss_triggeractions,base.group_user,1,1,1,1 +digitalsignage_dss_triggergroups_group_user,access.dss.triggergroups,model_dss_triggergroups,base.group_user,1,1,1,1 diff --git a/static/src/css/dss.css b/static/src/css/dss.css index 5482c25..fc0842f 100755 --- a/static/src/css/dss.css +++ b/static/src/css/dss.css @@ -16,4 +16,9 @@ .openerp .system_icon_small >img { height:90px; width:90px; +} + +.dss-smallbutton >img { + height:20px; + width:20px; } \ No newline at end of file diff --git a/static/src/css/screenDesignerView.css b/static/src/css/screenDesignerView.css new file mode 100644 index 0000000..06b9181 --- /dev/null +++ b/static/src/css/screenDesignerView.css @@ -0,0 +1,61 @@ +#rcorners1 { + border-radius: 25px; + background: #73AD21; + padding: 20px; + width: 200px; + height: 150px; +} +.bottom-bar { + padding: 10px; + position: fixed; + top: 100px; + left: 0; + width: 20%; + height: 90%; + background: #333333; + color: #ffffff; + box-shadow: 0 0 5px rgba(0, 0, 0, 0.25); + box-sizing: border-box; +} + +.bottom-bar__header { + max-width: 500px; + height:50px; + margin: 0 auto; + display: flex; + justify-content: space-between; +} + +.bottom-bar__header > * { + display: flex; + align-items: center; +} + +.bottom-bar__text { + font-family:arial; + padding-right: 10px; +} + +.bottom-bar__close { + background: none; + border: none; + color: #ffffff; + cursor: pointer; + font-size: 2em; +} + +.bottom-bar__content_2 { + background-color:#BBB; + margin: 0 auto; + padding: 0 auto; + max-width: 500px; + height:80%; + display: flex; + justify-content: space-between; +} + +.bottom-bar__content_2 > * { + display: flex; + align-items: center; +} + diff --git a/static/src/js/screenDesignerView.js b/static/src/js/screenDesignerView.js new file mode 100644 index 0000000..0ab0692 --- /dev/null +++ b/static/src/js/screenDesignerView.js @@ -0,0 +1,61 @@ +odoo.define('dss.screenDesigner', function (require) { +"use strict"; + +var AbstractAction = require('web.AbstractAction'); +var core = require('web.core'); +var field_utils = require('web.field_utils'); +var QWeb = core.qweb; +var web_client = require('web.web_client'); +var ajax = require('web.ajax'); +var _t = core._t; +var rpc = require('web.rpc'); +var self = this; +var session = require('web.session'); + +var screenDesigner = AbstractAction.extend({ + contentTemplate: 'dssscreenDesignerView', + init: function(parent, context) { + this._super(parent, context); + this.dashboard_templates = ['MainSection']; + }, + start: function() { + var self = this; + this.set("title", 'Dashboard'); + return this._super().then(function() { + self.render_dashboards(); + }); + }, + willStart: function(){ + var self = this; + return this._super() + }, + render_dashboards: function() { + var self = this; + this.fetch_data() + var templates = [] + var templates = ['MainSection']; + _.each(templates, function(template) { + self.$('.o_hr_dashboard').append(QWeb.render(template, {widget: self})) + }); + }, + fetch_data: function() { + var self = this +// fetch data to the tiles + var def1 = this._rpc({ + model: 'dss.screendesign', + method: "get_data", + }) + .then(function (result) { + $('#product_templates').append('' + result.uuid + ''); + $('#variants_count').append('' + result.uuid + ''); + $('#products_storable').append('' + result.uuid + ''); + $('#product_consumable').append('' + result.uuid + ''); + }); + }, +}); + +core.action_registry.add('dss_screenDesigner_js_action', screenDesigner); + +return screenDesigner; + +}); diff --git a/static/src/xml/screenDesignerView.xml b/static/src/xml/screenDesignerView.xml new file mode 100644 index 0000000..9ca650b --- /dev/null +++ b/static/src/xml/screenDesignerView.xml @@ -0,0 +1,35 @@ + + + + +
+
+
+
+

Feldübersicht

+
+ +
+
+
+
+
+
+ + +
+
+
+
+

Feld - Designer

+
+
+ + +
+ +
+
+
+ +
\ No newline at end of file diff --git a/views/.mc.menu b/views/.mc.menu deleted file mode 100755 index f82ee7a..0000000 --- a/views/.mc.menu +++ /dev/null @@ -1,379 +0,0 @@ -shell_patterns=0 - -############################################################################## -# %% The % character -# %f The current file (if non-local vfs, file will be copied locally and -# %f will be full path to it) -# %p The current file -# %d The current working directory -# %s "Selected files"; the tagged files if any, otherwise the current file -# %t Tagged files -# %u Tagged files (and they are untagged on return from expand_format) -# %view Runs the commands and pipes standard output to the view command -# If %view is immediately followed by '{', recognize keywords -# ascii, hex, nroff and unform -# -# If the format letter is in uppercase, it refers to the other panel -# -# With a number followed the % character you can turn quoting on (default) -# and off. For example: -# %f quote expanded macro -# %1f ditto -# %0f don't quote expanded macro -############################################################################## - -+ ! t t -@ Do something on the current file - CMD=%{Enter command} - $CMD %f - -+ t t -@ Do something on the tagged files - CMD=%{Enter command} - for i in %t ; do - $CMD "$i" - done - -0 Edit a bug report and send it to root - I=`mktemp "${MC_TMPDIR:-/tmp}/mail.XXXXXX"` || exit 1 - ${EDITOR-vi} "$I" - test -r "$I" && mail root < "$I" - rm -f "$I" - -=+ f \.1$ | f \.3$ | f \.4$ | f \.5$ | f \.6$ | f \.7$ | f \.8$ | f \.man$ & t r -1 Display the file with roff -man - %view{ascii,nroff} roff -c -Tlatin1 -mandoc %f - -2 Call the info hypertext browser - info - -= t d -3 Compress the current subdirectory (tar.gz) - Pwd=`basename %d /` - echo -n "Name of the compressed file (without extension) [$Pwd]: " - read tar - [ "$tar"x = x ] && tar="$Pwd" - cd .. && \ - tar cf - "$Pwd" | gzip -f9 > "$tar.tar.gz" && \ - echo "../$tar.tar.gz created." - -4 Compress the current subdirectory (tar.bz2) - Pwd=`basename %d /` - echo -n "Name of the compressed file (without extension) [$Pwd]: " - read tar - [ "$tar"x = x ] && tar="$Pwd" - cd .. && \ - tar cf - "$Pwd" | bzip2 -f > "$tar.tar.bz2" && \ - echo "../$tar.tar.bz2 created." - -5 Compress the current subdirectory (tar.7z) - Pwd=`basename %d /` - echo -n "Name of the compressed file (without extension) [$Pwd]: " - read tar - [ "$tar"x = x ] && tar="$Pwd" - cd .. && \ - tar cf - "$Pwd" | 7za a -si "$tar.tar.7z" && \ - echo "../$tar.tar.7z created." - -6 Compress the current subdirectory (tar.xz) - Pwd=`basename %d /` - echo -n "Name of the compressed file (without extension) [$Pwd]: " - read tar - [ "$tar"x = x ] && tar="$Pwd" - cd .. && \ - tar cf - "$Pwd" | xz -f > "$tar.tar.xz" && \ - echo "../$tar.tar.xz created." - -7 Compress the current subdirectory (tar.zst) - Pwd=`basename %d /` - echo -n "Name of the compressed file (without extension) [$Pwd]: " - read tar - [ "$tar"x = x ] && tar="$Pwd" - cd .. && \ - tar cf - "$Pwd" | zstd -f > "$tar.tar.zst" && \ - echo "../$tar.tar.zst created." - -= f \.c$ & t r -+ f \.c$ & t r & ! t t -c Compile and link current .c file - make "`basename %f .c`" 2>/dev/null || cc -O -o "`basename %f .c`" %f - -+ t r & ! t t -a Append file to opposite - cat %f >> %D/%f - -+ t t -A Append files to opposite files - for i in %t ; do - cat "$i" >> %D/"$i" - done - -+ t r & ! t t -d Delete file if a copy exists in the other directory. - if [ %d = %D ]; then - echo "The two directories must be different." - exit 1 - fi - if [ -f %D/%f ]; then # if two of them, then - if cmp -s %D/%f %f; then - rm %f && echo %f": DELETED." - else - echo %f" and "%D/%f" differ: NOT deleted." - echo -n "Press RETURN " - read key - fi - else - echo %f": No copy in "%D/%f": NOT deleted." - fi - -+ t t -D Delete tagged files if a copy exists in the other directory. - if [ %d = %D ]; then - echo "The two directores must be different." - exit 1 - fi - for i in %t ; do - if [ -f %D/"$i" ]; then - SUM1=`sum "$i"` - SUM2=`sum %D/"$i"` - if [ "$SUM1" = "$SUM2" ]; then - rm "$i" && echo "${i}: DELETED." - else - echo "$i and "%D"/$i differ: NOT deleted." - fi - else - echo "$i has no copy in "%D": NOT deleted." - fi - done - -m View manual page - MAN=%{Enter manual name} - %view{ascii,nroff} MANROFFOPT='-c -Tlatin1' MAN_KEEP_FORMATTING=1 man -P cat "$MAN" - -= f \.gz$ & t r -+ ! t t -n Inspect gzip'ed newsbatch file - dd if=%f bs=1 skip=12 | zcat | ${PAGER-more} - # assuming the cunbatch header is 12 bytes long. - -= t r & -+ ! t t -h Strip headers from current newsarticle - CHECK=`awk '{print $1 ; exit}' %f` 2>/dev/null - case "$CHECK" in - Newsgroups:|Path:) - I=`mktemp "${MC_TMPDIR:-/tmp}/news.XXXXXX"` || exit 1 - cp %f "$I" && sed '/^'"$CHECK"' /,/^$/d' "$I" > %f - [ "$?" = "0" ] && rm "$I" - echo %f": header removed." - ;; - *) - echo %f" is not a news article." - ;; - esac - -+ t t -H Strip headers from the marked newsarticles - for i in %t ; do - CHECK=`awk '{print $1 ; exit}' "$i"` 2>/dev/null - WFILE=`mktemp "${MC_TMPDIR:-/tmp}/news.XXXXXX"` || exit 1 - case "$CHECK" in - Newsgroups:|Path:) - cp "$i" "$WFILE" && sed '/^'"$CHECK"' /,/^$/d' "$WFILE" > "$i" - if [ "$?" = "0" ]; then - rm "$WFILE"; echo "$i header removed. OK." - else - echo "Oops! Please check $i against $WFILE." - fi - ;; - *) - echo "$i skipped: Not a news article." - ;; - esac - done - -= t r -+ ! t t -r Copy file to remote host - echo -n "To which host?: " - read Host - echo -n "To which directory on $Host?: " - read Dir - rcp -p %f "${Host}:${Dir}" - -+ t t -R Copy files to remote host (no error checking) - echo -n "Copy files to which host?: " - read Host - echo -n "To which directory on $Host? :" - read Dir - rcp -pr %u "${Host}:${Dir}" - -= f \.tex$ & t r -+ f \.tex$ & t r & ! t t -t Run latex on file and show it with xdvi - latex %f && xdvi "`basename %f .tex`".dvi - -=+ f ^part | f ^Part | f uue & t r -+ t t -U Uudecode marked news articles (needs work) - ( - for i in %t ; do # strip headers - FIRST=`awk '{print $1 ; exit}' "$i"` - cat "$i" | sed '/^'"$FIRST"' /,/^$/d' - done - ) | sed '/^$/d' | sed -n '/^begin 6/,/^end$/p' | uudecode - if [ "$?" != "0" ]; then - echo "Cannot decode "%t"." - fi - echo "Please test the output file before deleting anything." - -=+ f \.tar\.gz$ | f \.tar\.z$ | f \.tgz$ | f \.tpz$ | f \.tar\.lz$ | f \.tar\.lz4$ | f \.tar\.lzma$ | f \.tar\.7z$ | f \.tar\.xz$ | f \.tar\.zst | f \.tar\.Z$ | f \.tar\.bz2$ & t rl -x Extract the contents of a compressed tar file - unset PRG - case %f in - *.tar.7z) PRG="7za e -so";; - *.tar.bz2) PRG="bunzip2 -c";; - *.tar.gz|*.tar.z|*.tgz|*.tpz|*.tar.Z) PRG="gzip -dc";; - *.tar.lz) PRG="lzip -dc";; - *.tar.lz4) PRG="lz4 -dc";; - *.tar.lzma) PRG="lzma -dc";; - *.tar.xz) PRG="xz -dc";; - *.tar.zst) PRG="zstd -dc";; - *) exit 1;; - esac - $PRG %f | tar xvf - - -= t r -+ ! t t -y Gzip or gunzip current file - unset DECOMP - case %f in - *.gz|*.[zZ]) DECOMP=-d;; - esac - # Do *not* add quotes around $DECOMP! - gzip $DECOMP -v %f - -+ t t -Y Gzip or gunzip tagged files - for i in %t ; do - unset DECOMP - case "$i" in - *.gz|*.[zZ]) DECOMP=-d;; - esac - gzip $DECOMP -v "$i" - done - -+ ! t t -b Bzip2 or bunzip2 current file - unset DECOMP - case %f in - *.bz2) DECOMP=-d;; - esac - bzip2 $DECOMP -v %f - -+ t t -B Bzip2 or bunzip2 tagged files - for i in %t ; do - unset DECOMP - case "$i" in - *.bz2) DECOMP=-d;; - esac - bzip2 $DECOMP -v "$i" - done - -+ f \.tar.gz$ | f \.tgz$ | f \.tpz$ | f \.tar.Z$ | f \.tar.z$ | f \.tar.bz2$ | f \.tar.F$ & t r & ! t t -z Extract compressed tar file to subdirectory - unset D - set gzip -cd - case %f in - *.tar.F) D=`basename %f .tar.F`; set freeze -dc;; - *.tar.Z) D=`basename %f .tar.Z`;; - *.tar.bz2) D=`basename %f .tar.bz2`; set bunzip2 -c;; - *.tar.gz) D=`basename %f .tar.gz`;; - *.tar.z) D=`basename %f .tar.z`;; - *.tgz) D=`basename %f .tgz`;; - *.tpz) D=`basename %f .tpz`;; - esac - mkdir "$D"; cd "$D" && ("$1" "$2" ../%f | tar xvf -) - -+ t t -Z Extract compressed tar files to subdirectories - for i in %t ; do - set gzip -dc - unset D - case "$i" in - *.tar.F) D=`basename "$i" .tar.F`; set freeze -dc;; - *.tar.Z) D=`basename "$i" .tar.Z`;; - *.tar.bz2) D=`basename "$i" .tar.bz2`; set bunzip2 -c;; - *.tar.gz) D=`basename "$i" .tar.gz`;; - *.tar.z) D=`basename "$i" .tar.z`;; - *.tgz) D=`basename "$i" .tgz`;; - *.tpz) D=`basename "$i" .tpz`;; - esac - mkdir "$D"; (cd "$D" && "$1" "$2" "../$i" | tar xvf -) - done - -+ f \.gz$ | f \.tgz$ | f \.tpz$ | f \.Z$ | f \.z$ | f \.bz2$ & t r & ! t t -c Convert gz<->bz2, tar.gz<->tar.bz2 & tgz->tar.bz2 - unset D - unset EXT - case %f in - *.Z) EXT=Z;; - *.bz2) EXT=bz2;; - *.gz) EXT=gz;; - *.tgz) EXT=tgz;; - *.tpz) EXT=tpz;; - *.z) EXT=z;; - esac - case "$EXT" in - bz2|Z|gz|z) D=`basename %f ."$EXT"`;; - tgz|tpz) D=`basename %f ."$EXT"`.tar;; - esac - if [ "$EXT" = "bz2" ]; then - bunzip2 -v %f - gzip -f9 -v "$D" - else - gunzip -v %f - bzip2 -v "$D" - fi - -+ t t -C Convert gz<->bz2, tar.gz<->tar.bz2 & tgz->tar.bz2 - for i in %t ; do - unset D - unset EXT - case "$i" in - *.Z) EXT=Z;; - *.bz2) EXT=bz2;; - *.gz) EXT=gz;; - *.tgz) EXT=tgz;; - *.tpz) EXT=tpz;; - *.z) EXT=z;; - esac - case "$EXT" in - bz2|Z|gz|z) D=`basename "$i" ."$EXT"`;; - tgz|tpz) D=`basename "$i" ."$EXT"`.tar;; - esac - if [ "$EXT" = "bz2" ]; then - bunzip2 -v "$i" - gzip -f9 -v "$D" - else - gunzip -v "$i" - bzip2 -v "$D" - fi - done - -+ x /usr/bin/open | x /usr/local/bin/open & x /bin/sh -o Open next a free console - open -s -- sh - -+ x /usr/bin/open | x /usr/local/bin/open & x /bin/sh -O Odoo Refresh - sh /root/refresh_odoo.sh - -+ x /usr/bin/open | x /usr/local/bin/open & x /bin/sh -G git push - git push -u origin main - - diff --git a/views/dss_advertisementfields.xml b/views/dss_advertisementfields.xml index e6a8018..bbd35b3 100755 --- a/views/dss_advertisementfields.xml +++ b/views/dss_advertisementfields.xml @@ -27,8 +27,9 @@ + -

Die Struktur kann erst nach Speichern der Grunddaten eingerichtet werden !

+

Die Struktur kann erst nach Speichern der Grunddaten eingerichtet werden !

@@ -36,6 +37,7 @@
+ @@ -44,11 +46,16 @@ + - - - + + + + + + + diff --git a/views/dss_contracts.xml b/views/dss_contracts.xml index 359ca45..fb957c5 100755 --- a/views/dss_contracts.xml +++ b/views/dss_contracts.xml @@ -23,8 +23,28 @@
+ + dss_project_contracts_tree + dss.contracts + + + + + + + + + + + + + + + + + - DigitalSignage Projekt Vertraeg + DigitalSignage Projekt Vertraege ir.actions.act_window dss.contracts form @@ -84,7 +104,8 @@ {"default_allow_billable": 1} - + + DigitalSignage Alle Vertraege ir.actions.act_window dss.contracts @@ -104,14 +125,14 @@ dss_contracts_tree dss.contracts - + - - - + + + - + @@ -293,8 +314,8 @@ -
-

@@ -320,14 +341,14 @@
-
- +
+
- +
@@ -354,6 +375,14 @@
+
+
+ + +
+

>
@@ -407,6 +436,7 @@ + @@ -510,4 +540,33 @@ + + Standard Vertragsdaten setzen + + + form + code + + action = records.setStandardValues() + + + + + 1. Standard Vertragsdaten setzen (ID, NAME usw.) + + + tree + code + action = records.setTreeStandardValues() + + + + 2. Erstkampagnen erzeugen + + + tree + code + action = records.setFirstKampagne() + + diff --git a/views/dss_eventdays.xml b/views/dss_eventdays.xml new file mode 100644 index 0000000..ebe9f73 --- /dev/null +++ b/views/dss_eventdays.xml @@ -0,0 +1,68 @@ + + + + + dss_eventdays_tree + dss.eventdays + + + + + + + + + + + + + + dss_eventdays_form + dss.eventdays + +
+
+
+ + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + + DigitalSignage EventSpieltage + ir.actions.act_window + dss.eventdays + tree,form + {} + +

+ Neuen Spieltag erstellen +

+
+
+ + +
\ No newline at end of file diff --git a/views/dss_geraetetypen.xml b/views/dss_geraetetypen.xml index f9bef52..09d2b99 100755 --- a/views/dss_geraetetypen.xml +++ b/views/dss_geraetetypen.xml @@ -6,6 +6,12 @@ dss.geraetetypen
+
+
@@ -16,9 +22,25 @@ + + + - + +
+ + + + + + + + + +
+
+ diff --git a/views/dss_projects.xml b/views/dss_projects.xml index 13d6c53..ab0e198 100755 --- a/views/dss_projects.xml +++ b/views/dss_projects.xml @@ -1,6 +1,26 @@ + + dss_projects_form + dss.projects + + + + + + + + + + + + + + + + + dss_projects_form dss.projects @@ -8,32 +28,78 @@ + + - - + - - + + - - - - - - - - - - + + + + + + + + +
+
+ + + +
+
+
+
+ + + +
+
+ + + +
+
+
@@ -60,7 +126,7 @@ dss.projects - + @@ -100,7 +166,8 @@ - +
@@ -140,13 +207,15 @@ - - - - - - - + + + + + + + + + @@ -155,7 +224,8 @@ ir.actions.act_window dss.projects kanban,form,tree - {} + + {'search_default_actual_projects': 1}

Fuege ein System ein ! diff --git a/views/dss_screendesign.xml b/views/dss_screendesign.xml new file mode 100644 index 0000000..76c8ca4 --- /dev/null +++ b/views/dss_screendesign.xml @@ -0,0 +1,10 @@ + + + + + Attendance + dss_screenDesigner_js_action + + + + \ No newline at end of file diff --git a/views/dss_settings.xml b/views/dss_settings.xml index a8448e9..e5869e1 100755 --- a/views/dss_settings.xml +++ b/views/dss_settings.xml @@ -39,6 +39,13 @@

+
+ + + + + +
diff --git a/views/dss_trigger_actions.xml b/views/dss_trigger_actions.xml new file mode 100755 index 0000000..a150287 --- /dev/null +++ b/views/dss_trigger_actions.xml @@ -0,0 +1,82 @@ + + + + + dss_triggeractions_form + dss.triggeractions + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + + dss_triggeractions_tree + dss.triggeractions + + + + + + + + + + + + DigitalSignage Trigger Aktionen + ir.actions.act_window + dss.triggeractions + tree,form + {} + +

+ Neuen Standardtext erstellen +

+
+
+ +
diff --git a/views/dss_triggertypes.xml b/views/dss_triggertypes.xml new file mode 100755 index 0000000..3982dae --- /dev/null +++ b/views/dss_triggertypes.xml @@ -0,0 +1,72 @@ + + + + + dss_trigger_form + dss.triggertypes + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + + dss_trigger_tree + dss.triggertypes + + + + + + + + + + + DigitalSignage Trigger + ir.actions.act_window + dss.triggertypes + tree,form + {} + +

+ Neuen Standardtext erstellen +

+
+
+ +
diff --git a/views/mainsystem_view.xml b/views/mainsystem_view.xml index 03900ca..c5c54f8 100755 --- a/views/mainsystem_view.xml +++ b/views/mainsystem_view.xml @@ -194,45 +194,6 @@ - - - dss_eventdays_tree - dss.eventdays - - - - - - - - - - - - - dss_eventdays_form - dss.eventdays - -
- - - - - - - - - - -
- - - -
-
-
-
- dss_paysystem_fields_tree dss.paysystem_fields @@ -396,19 +357,6 @@ - - DigitalSignage EventSpieltage - ir.actions.act_window - dss.eventdays - tree,form - {} - -

- Neuen Spieltag erstellen -

-
-
- DigitalSignage Zahlungsfelder ir.actions.act_window diff --git a/views/menu.xml b/views/menu.xml index 4a464d7..fd4735a 100755 --- a/views/menu.xml +++ b/views/menu.xml @@ -203,7 +203,23 @@ + sequence="140"/> + + + + + + + + \ No newline at end of file