Version 1 SV

This commit is contained in:
jopster 2025-04-13 13:32:14 +02:00
parent 6d7f5a3c55
commit da4f3316c4
37 changed files with 606 additions and 110 deletions

View File

@ -9,7 +9,7 @@
'sequence': 20,
'summary': 'DigitalSignage Management',
'description': """DigitalSignage Management""",
'depends':['base','mail','web','website'],
'depends':['base','mail','web','website','website_event'],
'data': [
'security/groups.xml',
'security/ir.model.access.csv',
@ -84,6 +84,9 @@
'DigitalSignage/static/src/css/dss.css',
'DigitalSignage/static/src/scss/style.scss',
],
'web.assets_fontend': [
'DigitalSignage/static/src/js/dss_screenview_injector.js',
],
'web.assets_qweb': [
],
},

View File

@ -3,3 +3,4 @@
from . import main
from . import dss_screendesigner_controller
from . import dss_screenview_controller

BIN
controllers/__pycache__/__init__.cpython-311.pyc Executable file → Normal file

Binary file not shown.

Binary file not shown.

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import http
from odoo import http, models, api
import os
import os.path
import base64
@ -29,4 +29,5 @@ class screendesignercontroller(http.Controller):
'google_maps_api_key': google_maps_api_key,
}
return
return

View File

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import http, models, api
import os
import os.path
import base64
import logging
from odoo.http import request
_logger = logging.getLogger(__name__)
from odoo.tools.json import scriptsafe
class screenViewController(http.Controller):
@http.route('/dss/gocontract', type='json', auth='user')
def gocontract(self, id):
# Tu was mit den Daten
_logger.info('doch hier')
request.env.ref('DigitalSignage.DigitalSignage.action_dss_contracts').run()
print("Empfangen vom Frontend:", some_data)
return {'status': 'OK', 'message': 'Daten verarbeitet!'}

BIN
models/__pycache__/dss_advertisefields.cpython-311.pyc Executable file → Normal file

Binary file not shown.

Binary file not shown.

BIN
models/__pycache__/dss_m2mmail.cpython-311.pyc Executable file → Normal file

Binary file not shown.

View File

@ -108,6 +108,7 @@ class dsscontractads(models.Model):
contract = fields.Many2one('dss.contracts', store=True, tracking=True)
contract_id = fields.Char(related='contract.contract_id')
contract_name = fields.Char(related='contract.contract_name')
contract_fields = fields.Many2many(related='contract.werbe_feld_selected')
contract_need_media = fields.Many2many(related='contract.need_media', string='Vertragsmedien', tracking=True)
project = fields.Many2one('dss.projects', string='Project', store=True, tracking=True)
@ -166,6 +167,7 @@ class dsscontractads(models.Model):
special_reason = fields.Char('Sonderinformation',tracking=True)
@api.depends('date_korrekturfreigabe_ablauf')
def _date_korrekturfreigabe_ablauf_compute(self):
self.date_korrekturfreigabe_ablauf_compute = ''
@ -237,8 +239,10 @@ class dsscontractads(models.Model):
@api.onchange('date_korrekturabzug')
def _date_korrekturabzug_change(self):
for record in self:
_logger.info('Korrekturabzug änderung : C_' + str(self.id) + 'K_' + str(record.id)+' / '+str(record.date_korrekturabzug)+' / '+str(record._origin.date_korrekturabzug))
autodays=0
if record.date_korrekturabzug:
_logger.info('Korrekturabzug Änderung erfolgt : C_' + str(self.id) + 'K_' + str(record.id))
autodays=self.env['dss.settings'].search([],limit=1).freigabe_auto_time
record.date_korrekturfreigabe_ablauf = record.date_korrekturabzug + relativedelta(days=autodays)
@ -464,3 +468,4 @@ class dsscontractads(models.Model):
def pyaddenddate(self):
return 1

View File

@ -10,6 +10,8 @@ import tempfile
import easywebdav
import os
import os.path
import requests
import hashlib
from odoo import api, fields, models, _
@ -65,12 +67,17 @@ class dssadvertisefields(models.Model):
is_btn = fields.Boolean('Feld ist Button',help="Feld hat einen Button auf eineen TSS System ?",tracking=True, default=True)
btn_fromtemplate = fields.Many2one('dss.advertisefields.templates',tracking=True)
btn_displaytemplate = fields.Many2one('dss.display.templates',string="Bildschirmvorlage",tracking=True)
btn_fromtemplate = fields.Many2one('dss.advertisefields.templates',string="Buttonvorlage",tracking=True)
btn_pos_x = fields.Integer('Position im Display X (px)', tracking=True)
btn_pos_y = fields.Integer('Position im Display Y (px)', tracking=True)
btn_pos_w = fields.Integer('Breite des Feldes (px)', tracking=True)
btn_pos_h = fields.Integer('Höhe des Feldes (px)', tracking=True)
btn_name = fields.Char('Button name',tracking=True)
btn_image = fields.Char('Button Bild Pfad',tracking=True)
btn_image_hash = fields.Char('Button Bild Hash',tracking=True)
btn_image_bin = fields.Binary('Button Bild Binary',tracking=True)
btn_image_bin_base64 = fields.Char('Button Bild Base64',tracking=True,compute='_compute_base64', store=True)
btn_fieldname = fields.Char('Feldname',tracking=True)
btn_visible = fields.Boolean('Feld wird angezeigt',tracking=True, default=True)
btn_active = fields.Boolean('Feld ist bedienbar/aktiv',tracking=True, default=True)
@ -83,7 +90,7 @@ class dssadvertisefields(models.Model):
btn_gallery_rows = fields.Integer('Zeilen der Gallery', tracking=True)
btn_gallery_cols = fields.Integer('Spalten der Gallery', tracking=True)
btn_gallery_prv_w = fields.Integer('Gallery Bildpreview Breite', tracking=True)
btn_gallery_pev_h = fields.Integer('Gallery Bildpreview Höhe', tracking=True)
btn_gallery_prv_h = fields.Integer('Gallery Bildpreview Höhe', tracking=True)
btn_has_timer = fields.Boolean('Button Timeout',tracking=True, default=True)
btn_has_timer_time = fields.Integer('Button Timer-Zeit', tracking=True)
btn_editable = fields.Boolean('Button Editierbar',tracking=True, default=True)
@ -118,6 +125,8 @@ class dssadvertisefields(models.Model):
btn_text_3_font = fields.Char('Textzeile 3 Schriftart', tracking=True)
btn_text_4_font = fields.Char('Textzeile 4 Schriftart', tracking=True)
loopfiles = fields.Char('Durchlaufdateien', tracking=True)
def _default_projektfeld(self):
return "000_unbekannt"
@ -193,8 +202,8 @@ class dssadvertisefields(models.Model):
self.btn_playlist_zuordnung = self.btn_fromtemplate.btn_playlist_zuordnung
self.btn_gallery_rows = self.btn_fromtemplate.btn_gallery_rows
self.btn_gallery_cols = self.btn_fromtemplate.btn_gallery_cols
self.btn_gallery_prv_w = self.btn_fromtemplate.btn_gallery_pev_w
self.btn_gallery_pev_h = self.btn_fromtemplate.btn_gallery_pev_h
self.btn_gallery_prv_w = self.btn_fromtemplate.btn_gallery_prv_w
self.btn_gallery_prv_h = self.btn_fromtemplate.btn_gallery_prv_h
self.btn_has_timer = self.btn_fromtemplate.btn_has_timer
self.btn_has_timer_time = self.btn_fromtemplate.btn_has_timer_time
self.btn_editable = self.btn_fromtemplate.btn_editable
@ -208,15 +217,59 @@ class dssadvertisefields(models.Model):
self.btn_text_2_visible = self.btn_fromtemplate.btn_text_2_visible
self.btn_text_3_visible = self.btn_fromtemplate.btn_text_3_visible
self.btn_text_4_visible = self.btn_fromtemplate.btn_text_4_visible
self.btn_text_1_pos_x = self.btn_fromtemplate.self.btn_text_1_pos_x
self.btn_text_1_pos_y = self.btn_fromtemplate.self.btn_text_1_pos_y
self.btn_text_2_pos_x = self.btn_fromtemplate.self.btn_text_2_pos_x
self.btn_text_2_pos_y = self.btn_fromtemplate.self.btn_text_2_pos_y
self.btn_text_3_pos_x = self.btn_fromtemplate.self.btn_text_3_pos_x
self.btn_text_3_pos_y = self.btn_fromtemplate.self.btn_text_3_pos_y
self.btn_text_4_pos_x = self.btn_fromtemplate.self.btn_text_4_pos_x
self.btn_text_4_pos_y = self.btn_fromtemplate.self.btn_text_4_pos_y
self.btn_text_1_pos_x = self.btn_fromtemplate.btn_text_1_pos_x
self.btn_text_1_pos_y = self.btn_fromtemplate.btn_text_1_pos_y
self.btn_text_2_pos_x = self.btn_fromtemplate.btn_text_2_pos_x
self.btn_text_2_pos_y = self.btn_fromtemplate.btn_text_2_pos_y
self.btn_text_3_pos_x = self.btn_fromtemplate.btn_text_3_pos_x
self.btn_text_3_pos_y = self.btn_fromtemplate.btn_text_3_pos_y
self.btn_text_4_pos_x = self.btn_fromtemplate.btn_text_4_pos_x
self.btn_text_4_pos_y = self.btn_fromtemplate.btn_text_4_pos_y
self.btn_text_1_font = self.btn_fromtemplate.btn_text_1_font
self.btn_text_2_font = self.btn_fromtemplate.btn_text_2_font
self.btn_text_3_font = self.btn_fromtemplate.btn_text_3_font
self.btn_text_4_font = self.btn_fromtemplate.btn_text_4_font
def py_openadvfield(self):
action = self.env["ir.actions.actions"]._for_xml_id("DigitalSignage.action_dss_advertisefields_fill")
action['context']='{"active_id":'+str(self.id)+'}'
action['res_id']=self.id
return action
def btn_image_import(self):
action = self.env["confirmation.wizard"].confirm_message(_("Das Bild wirklich importieren ?"),title="Bitte bestätigen",method="btn_image_import_do",records=self,callback_params={"template":self.id})
if action:
return action
def btn_image_import_do(self,template):
try:
response = requests.get(self.btn_image, stream=True)
if response.status_code == 200:
# Encode the image content to base64
image_data = base64.b64encode(response.content)
# Save the image to the Binary field
self.btn_image_bin = image_data
# Calculate the hash of the image
image_hash = hashlib.sha256(response.content).hexdigest()
# Save the hash to the hash field
self.btn_image_hash = image_hash
else:
raise ValidationError(_("Failed to download the image. HTTP Status: %s") % response.status_code)
except requests.exceptions.RequestException as e:
raise ValidationError(_("An error occurred while downloading the image: %s") % str(e))
def btn_image_import_local(self):
action = self.env["confirmation.wizard"].confirm_message(_("Das Bild wirklich importieren ?"),title="Bitte bestätigen",method="btn_image_import_do_local",records=self,callback_params={"template":self.id})
if action:
return action
@api.depends('btn_image_bin')
def _compute_base64(self):
for record in self:
if record.btn_image_bin:
record.btn_image_bin_base64 = base64.b64encode(record.btn_image_bin).decode('utf-8')
else:
record.btn_image_bin_base64 = False

View File

@ -60,6 +60,7 @@ class dssadvertisefields(models.Model):
btn_pos_w = fields.Integer('Breite des Feldes (px)', tracking=True)
btn_pos_h = fields.Integer('Höhe des Feldes (px)', tracking=True)
btn_name = fields.Char('Button name',tracking=True)
btn_image = fields.Char('Button Bild',tracking=True)
btn_fieldname = fields.Char('Feldname am Display',tracking=True)
btn_visible = fields.Boolean('Feld wird angezeigt',tracking=True, default=True)
btn_active = fields.Boolean('Feld ist bedienbar/aktiv',tracking=True, default=True)
@ -69,9 +70,10 @@ class dssadvertisefields(models.Model):
btn_gallery_rows = fields.Integer('Zeilen der Gallery', tracking=True)
btn_gallery_cols = fields.Integer('Spalten der Gallery', tracking=True)
btn_gallery_prv_w = fields.Integer('Gallery Bildpreview Breite', tracking=True)
btn_gallery_pev_h = fields.Integer('Gallery Bildpreview Höhe', tracking=True)
btn_gallery_prv_h = fields.Integer('Gallery Bildpreview Höhe', tracking=True)
btn_has_timer = fields.Boolean('Button Timeout',tracking=True, default=False)
btn_has_timer_time = fields.Integer('Button Timer-Zeit', tracking=True)
is_btn = fields.Boolean('ist Button',tracking=True, default=True)
btn_editable = fields.Boolean('Button Editierbar',tracking=True, default=True)
btn_special_actionimage = fields.Char('Anzeigebild Spezialform ', tracking=True)
btn_special_actionimage_x = fields.Integer('X-Position Anzeigebild', tracking=True)

View File

@ -33,7 +33,7 @@ import sys
TUYA_LOGGER.setLevel(logging.DEBUG)
# logging.setLoggerClass(OdooCustomLogger)
logging.setLoggerClass(OdooCustomLogger)
_logger = logging.getLogger(__name__)
class dsscontracts(models.Model):
@ -163,6 +163,8 @@ class dsscontracts(models.Model):
shortwerbe_feld_selected = fields.Char(related='werbe_feld_selected.feldname',string='Werbefelder',tracking=True)
cutshortwerbe_feld_selected = fields.Char(string='gekürzte Felder',compute='_compute_cutshort')
werbe_feld_selected_btn_img = fields.Binary(related="werbe_feld_selected.btn_image_bin",string='Buttonbild',tracking=True)
# need_media = fields.Many2many('dss.mediarelations','mediarelations_contract_rel','contract_id','mediarelations_id',string='benötigte Medien')
last_media = fields.Many2many('dss.mediarelations',string='Medien',domain="[('isreference','=',False)]")
# last_media = fields.Many2many('dss.mediarelations','mediarelations_ad_relations','contract_id','mediarelations_id',string='Medien')
@ -285,17 +287,28 @@ class dsscontracts(models.Model):
@api.depends('ads_topics')
def _compute_themenliste(self):
_logger.info('Contract Themenliste Berechnung : C_' + str(self.id))
# _logger.info('Contract Themenliste Berechnung : C_' + str(self.id))
for record in self:
if record.ads_topics:
record.ads_topics_text = ', '.join(record.ads_topics.mapped('thema'))
else:
record.ads_topics_text = ''
@api.onchange('ads_last_date_korrekturabzug')
def _ads_last_date_korrekturabzug_change(self):
_logger.info('Korrekturabzug änderung C')
for record in self:
_logger.info('Korrekturabzug änderung C: C_' + str(self.id) + 'K_' + str(record.id)+' / '+str(record.ads_last_date_korrekturabzug)+' / '+str(record._origin.ads_last_date_korrekturabzug))
autodays=0
if record.ads_last_date_korrekturabzug:
_logger.info('Korrekturabzug Änderung erfolgt C: C_' + str(self.id) + 'K_' + str(record.id))
autodays=self.env['dss.settings'].search([],limit=1).freigabe_auto_time
record.ads_last_date_korrekturfreigabe_ablauf = record.ads_last_date_korrekturabzug + relativedelta(days=autodays)
@api.depends('vertragssumme')
def _compute_prov(self):
_logger.info('contract Provision Berechnung : C_' + str(self.id));
# _logger.info('contract Provision Berechnung : C_' + str(self.id));
if self.provisionstyp.provisionbase == 'VSUM':
if not self.provisionstyp.provisioncalc:
prozent=self.provisionstyp.provisionprozent
@ -306,9 +319,9 @@ class dsscontracts(models.Model):
def _compute_provisionspayedpercent(self):
addval = 0
for prov in self.provisions:
_logger.info('contract Provision Payed_part : C_' + str(self.id)+' / '+str(prov.provisionprozent));
# _logger.info('contract Provision Payed_part : C_' + str(self.id)+' / '+str(prov.provisionprozent));
addval = addval + prov.provisionprozent
_logger.info('Contract Provision payed : C_' + str(self.id)+' V '+str(addval));
# _logger.info('Contract Provision payed : C_' + str(self.id)+' V '+str(addval));
self.provisionspayedpercent = addval
@api.onchange('provisionstyp')

View File

@ -1,9 +1,11 @@
import uuid
from .dsslogger import OdooCustomLogger
import logging
import datetime
from odoo import api, fields, models, _
from odoo import tools
logging.setLoggerClass(OdooCustomLogger)
_logger = logging.getLogger(__name__)
class dssm2mvalues(models.Model):
@ -19,6 +21,11 @@ class dssm2mvalues(models.Model):
# Extrahiere die nächsten 3 Ziffern
project_id = email_text[pos + 11:pos + 14].strip()
self.project_id = project_id
pos = email_text.find("Schwellwert ")
_logger.info("Import M2M Emails - Get ID. File - Message : pos "+str(pos))
# Extrahiere die nächsten 3 Ziffern
level = email_text[pos + 12:pos + 13].strip()
self.level = level
self.analyzed = True
@api.model
@ -31,14 +38,27 @@ class dssm2mvalues(models.Model):
cron_job._trigger()
return result
def write(self, vals):
# Reset latitude/longitude in case we modify the address without
# updating the related geolocation fields
result = super().write(vals)
return result
_name = "dss.m2mmail"
_description = "DigitalSignage M2M Rückmeldungen"
# _rec_name = "statusname"
_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.Datetime('Erstellungsdatum',default=lambda self: self._default_create_date())
date_lastedit = fields.Datetime('Änderungsdatum')
analyzed = fields.Boolean('Analysiert', default=False, tracking=True)
project_id = fields.Char(string='Projekt-ID',tracking=True)
project_id = fields.Char(string='Projekt-ID',tracking=True)
project = fields.Many2one('dss.projects', string='Projekt', compute='_compute_project')
level = fields.Char('Schwellengrenze',tracking=True)
@api.model
def _default_create_date(self):
return datetime.datetime.now()
@api.depends('project_id')
def _compute_project(self):

View File

@ -69,6 +69,8 @@ class dssprojects(models.Model):
grundsystem_showonlinestate = fields.Boolean(related='grundsystemname.showonlinestate')
grundsystem_showonlinestate_type = fields.Selection(related='grundsystemname.showonlinestate_type')
btntemplate = fields.Many2one('dss.display.templates',string='Buttonsvorlage',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)
@ -187,17 +189,20 @@ class dssprojects(models.Model):
# context = action['context'].replace('active_id', str(self.id))
# domain = action['domain'].replace('active_id', str(self.id))
# _logger.info('Vertraege fuer : '+str(self.id))
return {
'type': 'ir.actions.act_window',
'view_type':'kanban',
'view_mode':'kanban,tree,screenview',
'res_model':'dss.contracts',
'target':'current',
'context':'{"default_project":'+str(self.id)+',"show_project_update":True}',
'res_id':self.id,
'display_name' : self.name,
'domain':'[("project","=",'+str(self.id)+')]'
}
# return {
# 'type': 'ir.actions.act_window',
# 'view_type':'kanban',
# 'view_mode':'kanban,tree,screenview',
# 'res_model':'dss.contracts',
# 'target':'current',
# 'context':'{"default_project":'+str(self.id)+',"show_project_update":True}',
# 'res_id':self.id,
# 'display_name' : self.name,
# 'domain':'[("project","=",'+str(self.id)+')]'
# }
action = self.env["ir.actions.actions"]._for_xml_id("DigitalSignage.action_dss_project_contracts")
return action
# context = ast.literal_eval(context)
# context = "{
# 'create': self.active,
@ -269,6 +274,42 @@ class dssprojects(models.Model):
for pro in projekte:
self.compute_getonlinestate_single(pro)
@api.model
def get_data(self,template):
if not template:
outlist = [{"error":"Kein Projekt übermittelt"}]
else:
project = self.env['dss.projects'].search([('id',"=",template)])
contracts = self.env['dss.contracts'].search([('project',"=",project.id),('contract_state','=',4)])
if not project.btntemplate:
outlist=[{"error":"Kein Button-template definiert"}]
else:
#alldata = self.env['dss.advertisefields.templates'].search([('displaytemplate',"=",project.btntemplate.id)])
outlist = ([])
#self.env["confirmation.wizard"].with_context(hide_cancel=True).confirm_no_action_message(message="Debug : "+str(len(alldata))+"/"+str(alldata),title="Notification")
for contract in contracts:
for feld in contract.werbe_feld_selected:
if feld.is_btn:
if contract.client:
name1 = contract.contact_company_name
name2 = contract.contact_dsspartner_vorname+' '+contract.contact_dsspartner_name
name3 = contract.contact_street2
name4 = contract.contact_zip+' '+contract.contact_city
else:
name1 = contract.client_short_company
name2 = contract.client_short_vorname+' '+contract.client_short_name
name3 = contract.client_short_strasse
name4 = contract.client_short_plz+' '+contract.client_short_ort
if feld.btn_image_bin:
# Convert the binary image data to a Base64 string
image_base64 = str(feld.btn_image_bin)[2:][:-1]
else:
image_base64 = ''
_logger.info("Button Image : "+str(feld.btn_image_bin))
outlist.append({'uuid':contract.uuid,'pos_x':feld.btn_pos_x,'pos_y':feld.btn_pos_y,'pos_w':feld.btn_pos_w,'pos_h':feld.btn_pos_h,'feldname':feld.feldname,'kunde_1':name1,'kunde_2':name2,'kunde_3':name3,'kunde_4':name4,'btn_image':image_base64})
return outlist
def compute_getonlinestate_single(self,project):
#proj = self.env['dss.projects'].search([('id',"=",project.id)])
proj = project
@ -364,8 +405,24 @@ class dssprojects(models.Model):
else:
colorval = "#a0a0a0"
proj['onlinestate_1']=colorval
@api.model
def go_contract(self,uuid):
_logger.info("UUID : "+str(uuid))
if uuid:
contract = self.env['dss.contracts'].search([('uuid','=',uuid)])
if contract:
action = self.env["ir.actions.actions"]._for_xml_id("DigitalSignage.action_dss_contracts")
action['context'] = {'default_project': contract.project.id}
action['domain'] = [('id', '=', contract.id)]
action['res_id'] = contract.id
return action
else:
_logger.info("UUID : "+str(uuid)+" not found")
return False
else:
_logger.info("UUID : "+str(uuid)+" not found")
return False
def method(self):
return (

View File

@ -168,7 +168,7 @@ class dsscontracts(models.Model):
'contract_name': self.contract_name,
'contract_state': self.env['dss.contractstate'].search([("statusname","=","Angelegt")]).id,
'werbe_feld_selected': self.werbe_feld_selected,
'client': self.client,
'client': self.client.id,
'client_short_vorname': self.client_short_vorname,
'client_short_name': self.client_short_name,
'client_short_email': self.client_short_email,

View File

@ -39,10 +39,13 @@ digitalsignage_dss_contracts_ads_topics_group_user,access.dss_contracts_ads_topi
digitalsignage_dss_triggerconditions_group_user,access.dss.triggerconditions,model_dss_triggerconditions,base.group_user,1,1,1,1
digitalsignage_dss_marker_group_user,access.dss.marker,model_dss_marker,base.group_user,1,1,1,1
digitalsignage_dss_triggeractions_groups_user,access.dss.triggeractions.groups,model_dss_triggeractions_groups,base.group_user,1,1,1,1
DigitalSignage_dss_triggervalues,access.dss.triggervalues,DigitalSignage.model_dss_triggervalues,base.group_user,1,0,0,0
DigitalSignage_dss_statesave,access.dss.statesave,DigitalSignage.model_dss_statesave,base.group_user,1,0,0,0
DigitalSignage_dss_activity_mixin,access.dss.activity_mixin,DigitalSignage.model_dss_activity_mixin,base.group_user,1,0,0,0
DigitalSignage_dss_triggermodel,access.dss.triggermodel,DigitalSignage.model_dss_triggermodel,base.group_user,1,0,0,0
DigitalSignage_dss_invoices,access.dss.invoices,DigitalSignage.model_dss_invoices,base.group_user,1,1,1,1
DigitalSignage_dss_onlinestate,access.dss.onlinestate,DigitalSignage.model_dss_onlinestate,base.group_user,1,1,1,1
DigitalSignage_dss_m2mmail,access.dss.m2mmail,DigitalSignage.model_dss_m2mmail,base.group_user,1,1,1,1
DigitalSignage_dss_triggervalues,access.dss.triggervalues,model_dss_triggervalues,base.group_user,1,0,0,0
DigitalSignage_dss_statesave,access.dss.statesave,model_dss_statesave,base.group_user,1,0,0,0
DigitalSignage_dss_activity_mixin,access.dss.activity_mixin,model_dss_activity_mixin,base.group_user,1,0,0,0
DigitalSignage_dss_triggermodel,access.dss.triggermodel,model_dss_triggermodel,base.group_user,1,0,0,0
DigitalSignage_dss_invoices,access.dss.invoices,model_dss_invoices,base.group_user,1,1,1,1
DigitalSignage_dss_onlinestate,access.dss.onlinestate,model_dss_onlinestate,base.group_user,1,1,1,1
DigitalSignage_dss_m2mmail,access.dss.m2mmail,model_dss_m2mmail,base.group_user,1,1,1,1
digitalsignage_dss_display_templates_group_user,access.dss.display.templates,model_dss_display_templates,base.group_user,1,1,1,1
digitalsignage_dss_triggeractions_groups_group_user,access.dss.triggeractions.groups,model_dss_triggeractions_groups,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
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
39 digitalsignage_dss_triggerconditions_group_user access.dss.triggerconditions model_dss_triggerconditions base.group_user 1 1 1 1
40 digitalsignage_dss_marker_group_user access.dss.marker model_dss_marker base.group_user 1 1 1 1
41 digitalsignage_dss_triggeractions_groups_user access.dss.triggeractions.groups model_dss_triggeractions_groups base.group_user 1 1 1 1
42 DigitalSignage_dss_triggervalues access.dss.triggervalues DigitalSignage.model_dss_triggervalues model_dss_triggervalues base.group_user 1 0 0 0
43 DigitalSignage_dss_statesave access.dss.statesave DigitalSignage.model_dss_statesave model_dss_statesave base.group_user 1 0 0 0
44 DigitalSignage_dss_activity_mixin access.dss.activity_mixin DigitalSignage.model_dss_activity_mixin model_dss_activity_mixin base.group_user 1 0 0 0
45 DigitalSignage_dss_triggermodel access.dss.triggermodel DigitalSignage.model_dss_triggermodel model_dss_triggermodel base.group_user 1 0 0 0
46 DigitalSignage_dss_invoices access.dss.invoices DigitalSignage.model_dss_invoices model_dss_invoices base.group_user 1 1 1 1
47 DigitalSignage_dss_onlinestate access.dss.onlinestate DigitalSignage.model_dss_onlinestate model_dss_onlinestate base.group_user 1 1 1 1
48 DigitalSignage_dss_m2mmail access.dss.m2mmail DigitalSignage.model_dss_m2mmail model_dss_m2mmail base.group_user 1 1 1 1
49 digitalsignage_dss_display_templates_group_user access.dss.display.templates model_dss_display_templates base.group_user 1 1 1 1
50 digitalsignage_dss_triggeractions_groups_group_user access.dss.triggeractions.groups model_dss_triggeractions_groups base.group_user 1 1 1 1
51 digitalsignage_dss_screendesign_group_user access.dss.screendesign model_dss_screendesign base.group_user 1 1 1 1

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 KiB

View File

@ -0,0 +1,20 @@
odoo.define('dss.screenView_handler', function (require) {
"use strict";
var Dialog = require('web.Dialog');
var core = require('web.core');
var _t = core._t;
var publicWidget = require('web.public.widget')
publicWidget = publicWidget.Widget.extend({
selector:'.tooltip-container',
events: {
'click .alert_onclick': '_alert_onclick',
},
_alert_onclick: function (ev) {
alert('onclick');
Dialog.alert(self, _t("Alert on clicking the element"), {
title: _t('onclick'),
});
},
})
});

View File

@ -15,6 +15,7 @@ export const HelloWorldView = BasicView.extend({
}),
getRenderer(parent, state) {
// alert('getRenderer')
state = Object.assign({}, state, this.rendererParams);
return new RendererWrapper(null, this.config.Renderer, state);
},

View File

@ -1,79 +1,130 @@
/** @odoo-module **/
import { useService } from "@web/core/utils/hooks";
import { Component, markup, onWillStart, useRef, xml } from "@odoo/owl";
import { useEnv, Component, markup, onWillStart,onMounted,onWillUnmount, useRef, xml } from "@odoo/owl";
import { registry } from "@web/core/registry";
import { browser } from "@web/core/browser/browser";
export class ScreenViewRenderer extends Component {
aktcontext = "";
aktcontext = "";
async setup() {
alert('render '+JSON.stringify(this.props))
setup() {
// alert('render '+JSON.stringify(this.props))
this.rpc = useService("rpc");
//this.action = useService("action");
this.env = useEnv();
onWillStart(async () => {
this.willStart()
await this.willStart(this.props)
});
// this._onClickGlobal = this._handleClick.bind(this);
// onMounted(() => browser.addEventListener("click", this._onClickGlobal));
// onWillUnmount(() => browser.removeEventListener("click", this._onClickGlobal));
}
async willStart() {
async willStart(props) {
var self = this;
await this.render_Screen()
await this.render_Screen(props)
}
onMouseEnter(ev) {
//var index = [...ev.currentTarget.parentNode.children].indexOf(ev.currentTarget);
//if (ev.currentTarget.tagName === "TH") {
alert('MouseEnter')
}
async render_Screen() {
var self = this;
alert('render_Screen '+this)
// Event-Handler für den Click
//_handleClick(event) {
handleClick() {
// if (event.target.classList.contains("tooltip-container")) {
console.log("Div clicked!", event.target);
this.rpc({
model : 'dss.projects',
method: "go_contract",
args: [event.target.dataset.uuid]
}).then(function (action) {
alert(JSON.stringify(action))
if (action.error) {
console.error(action.error);
} else {
this.action.doAction(action);
}
})
// }
}
/* this.rpc('/dss/gocontract',{
id: event.target.dataset.uuid
}).then(function (action) {
alert(action)
if (action.error) {
console.error(action.error);
} else {
// Zugriff auf den actionService
const actionService = registry.category("services").get("action");
actionService.do_action(action).catch((error) => {
console.error("Error executing action:", error);
});
}
}).catch((error) => {
console.error("Error fetching action:", error);
});
alert("Div clicked!");
*/
// Lifecycle-Methode: Wird aufgerufen, bevor die Komponente aus dem DOM entfernt wird
async render_Screen(props) {
var meins = "";
var divele = "";
var templates = []
var templates = ['MainSection'];
if (this.props.domain =[]) {
var def0 =this.rpc({
model: 'dss.display.templates',
method: "get_data",
args: [],
}).then(function (result) {
var $dropdown = document.querySelector('.ddown')
if (result.length>0) {
result.forEach(element => {
$dropdown.append(new Option(element.displayname, element.nr));
})
}
})
}
// document.addEventListener("click",_onclickevent)
// document.addEventListener("change",_onchangeevent)
if (this.props.domain != []) {
if (props.domain != []) {
// alert(' - '+props)
var def1 =this.rpc({
model: 'dss.advertisefields.templates',
// model: 'dss.advertisefields.templates',
// method: "get_data",
model: 'dss.projects',
method: "get_data",
args: [[props.context.screenlayout]],
args: [[props.context.active_id]],
}).then(function (result) {
var displaycss = 'background-color:#38AFA0;float:left;border-style: solid;border-width: 0.1px;'
const element = document.querySelector('.meincanvas')
const rect = element.getBoundingClientRect();
const topPosition = rect.top + window.scrollY;
const doelement = document.querySelector('.meincanvas')
// document.addEventListener("click",_onclickevent)
const rect = doelement.getBoundingClientRect();
const topPosition = rect.top //+ window.scrollY;
var maxx = 1920
var maxy = 1080
var topstart = topPosition + 60
var width = window.innerWidth-40;
var scale_faktor = (width / 3860)
var height = Math.round(2200 * scale_faktor)
meins = '<div style="background-color:#000000;padding:20px;height:'+height+'px;floating:left">'
if (result.length>0) {
var scale_faktor = (width / maxx)
var height = Math.round((maxy+40) * scale_faktor)
meins = '<div style="background-color:#000000;padding:20px;height:'+height+'px;floating:left">'
if (result.length<2) {
if (result[0].error) {
alert(result[0].error);
}
} else {
result.forEach(element => {
var ele_pos_x=element.pos_x*scale_faktor+20
var ele_pos_y=element.pos_y*scale_faktor+topstart
var ele_pos_y=element.pos_y*scale_faktor+20//+topstart
var ele_pos_h=element.pos_h*scale_faktor
var ele_pos_w=element.pos_w*scale_faktor
meins = meins + '<div class="ddbtn" style="'+displaycss+'position:absolute;left:'+ele_pos_x+'px;top:'+ele_pos_y+'px;width:'+ele_pos_w+'px;height:'+ele_pos_h+'px;">'+element.feldname+'</div>'
divele = '<div class="tooltip-container" id="clickableDiv" class="ddbtn" style="'+displaycss+'position:absolute;left:'+ele_pos_x+'px;top:'+ele_pos_y+'px;width:'+ele_pos_w+'px;height:'+ele_pos_h+'px;" data-uuid="'+element.uuid+'" t-on-click="handleClick">'
if (element.btn_image != '') {
divele += '<img class="_alert_onclick" src="data:image/png;base64,' + element.btn_image + '" style="width:100%;height:100%;"/>';
}
divele += '<span class="tooltip">'
divele += '<div>'+element.feldname+'</div>'
divele += '<div>'+element.kunde_1+'</div>'
divele += '<div>'+element.kunde_2+'</div>'
divele += '<div>'+element.kunde_3+'</div>'
divele += '<div>'+element.kunde_4+'</div></span>'
divele += '</div>'
meins = meins + divele
});
}
_.each(templates, function(template) {doelement.innerHTML= meins});
})
}

View File

@ -16,6 +16,7 @@ var aktcontext = "";
function _onclickevent(event) {
// Check if the clicked element has the class "button"
alert('onclick');
if (event.target.classList.contains("ddbtn")) {
alert(JSON.stringify($(event.currentTarget)))
};

View File

@ -38,4 +38,61 @@
border-left: 1px solid #ccc;
border-top: 1px solid #ccc;
z-index: 999;
}
}
.tooltip-container {
cursor: pointer;
position: relative;
display: inline-block;
}
.tooltip {
opacity: 0;
z-index: 99;
color: #bbb;
width: 220px;
display: block;
font-size: 11px;
padding: 5px 10px;
border-radius: 3px;
text-align: center;
text-shadow: 1px 1px 2px #111;
background: rgba(51, 51, 51, 0.9);
border: 1px solid rgba(34, 34, 34, 0.9);
box-shadow: 0 0 3px rgba(0, 0, 0, 0.5);
-webkit-transition: all 0.2s ease-in-out;
-moz-transition: all 0.2s ease-in-out;
-o-transition: all 0.2s ease-in-out;
-ms-transition: all 0.2s ease-in-out;
transition: all 0.2s ease-in-out;
-webkit-transform: scale(0);
-moz-transform: scale(0);
-o-transform: scale(0);
-ms-transform: scale(0);
transform: scale(0);
position: absolute;
right: -0px;
bottom: 10px;
}
.tooltip:before,
.tooltip:after {
content: "";
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-top: 10px solid rgba(51, 51, 51, 0.9);
position: absolute;
bottom: -10px;
left: 23%;
}
.tooltip-container:hover .tooltip,
a:hover .tooltip {
opacity: 1;
-webkit-transform: scale(1);
-moz-transform: scale(1);
-o-transform: scale(1);
-ms-transform: scale(1);
transform: scale(1);
}

View File

@ -3,10 +3,7 @@
<t t-name="dss.screenviewrenderer" owl="1">
<field name="screenname"/>
<select type="text" name="displaytemplate" class="form-control ddown">
</select>
<span class="meincanvas"/>
<p>Hello</p>
</t>
</templates>

View File

@ -6,13 +6,7 @@
<div class="bottom-bar ms-4" data-bottombar="cookieMessage" id="rcorner1">
<div class="bottom-bar__header">
</div>
<div class="bottom-bar__content_2">
<span class="meinfeld">Displayvorlage :</span>
<select type="text" name="displaytemplate" class="form-control ddown">
</select>
</div>
<div class="bottom-bar__content_3">
<span>test</span>
</div>
</div>
</div>

View File

@ -185,7 +185,19 @@
</div>
</div>
</page>
<page name="informations" string="entahltene Dateien">
<page name="informations" string="zu füllende Felder">
<group>
<field name="contract_fields" string="Inhalte">
<tree string="Felder" editable="top" create="1" edit="1" >
<button class="oe_stat_button" icon="fa-pencil-square-o" name="py_openadvfield" type="object" title="openfields_1"/>
<field name="feldname" string="Feldname"/>
<field name="auto_feldname" string="Feldname (intern)"/>
<field name="mediastructure" string="Medien"/>
</tree>
</field>
</group>
</page>
<page name="informations" string="enthaltene Dateien">
<field name="need_media">
<tree string="Dateien" editable="False" create="False">
<field name="field" string="von Feld"/>

View File

@ -12,8 +12,8 @@
<field name="contract">
</field>
<field name="isblocked" widget="boolean_toggle"/>
<field name="color_used" widget="color"/>
<field name="color_unused" widget="color"/>
<field name="btn_displaytemplate"/>
<field name="btn_fromtemplate" domain="[('displaytemplate','=',btn_displaytemplate)]"/>
</tree>
</field>
</record>
@ -58,8 +58,11 @@
</group>
</page>
<page name="button" string="Button Informationen" attrs="{'invisible': [('is_btn','!=',True)]}">
<field name="btn_fromtemplate" string="Button Template"/>
<button string="Template übernehmen" name="pyactiontaketemplate" type="object" class="btn-primary o_open_tasks" data-hotkey="t"/>
<group>
<field name="btn_displaytemplate" string="Button Template"/>
<field name="btn_fromtemplate" string="Button Template" domain="[('displaytemplate','=',btn_displaytemplate)]"/>
<button string="Template übernehmen" name="pyactiontaketemplate" type="object" class="btn-primary o_open_tasks" data-hotkey="t"/>
</group>
<notebook>
<page name="basesettings" string="Grundeinstellungen">
<group>
@ -87,7 +90,7 @@
<field name="btn_gallery_rows"/>
<field name="btn_gallery_cols"/>
<field name="btn_gallery_prv_w"/>
<field name="btn_gallery_pev_h"/>
<field name="btn_gallery_prv_h"/>
<field name="btn_gallery_cols"/>
</group>
<group name="specialcontent" attrs="{'invisible': [('btn_action_active', '!=', '14'),('btn_action_active', '!=', '9'),('btn_action_active', '!=', '12')]}">
@ -157,6 +160,9 @@
<field name="res_model">dss.advertisefields</field>
<field name="view_mode">tree,form</field>
<field name="context">{}</field>
<field name="view_ids" eval="[(5, 0, 0),
(0, 0, {'view_mode': 'tree', 'view_id': ref('dss_advertisefields_view_tree')}),
(0, 0, {'view_mode': 'form', 'view_id': ref('dss_advertisefields_view_form')})]"/>
<field name="help" type="html">
<p class="'o_view_nocontent_smiling_face">
Neues Werbefeld erstellen
@ -173,4 +179,163 @@
<field name="code">action = records.check_contract_multi_Values()</field>
</record>
<record id="dss_advertisefields_fill_form" model="ir.ui.view">
<field name="name">dss_advertisefields_fill_form</field>
<field name="model">dss.advertisefields</field>
<field name="arch" type="xml">
<form>
<sheet>
<group>
<group name="basethings">
<field name="feldname" string="Feldname"/>
<field name="project" string="Projekt"/>
<field name="auto_feldname" string="Projekt_Feld" readonly="1"/>
<field name="is_btn"/>
</group>
</group>
<notebook>
<page name="button" string="Button Informationen" attrs="{'invisible': [('is_btn','!=',True)]}">
<notebook>
<page name="basesettings" string="Grundeinstellungen">
<group>
<field name="btn_name"/>
<field name="btn_fieldname"/>
<field name="btn_visible" widget="boolean_toggle"/>
<field name="btn_active" widget="boolean_toggle"/>
<field name="btn_editable" widget="boolean_toggle"/>
</group>
</page>
<page name="basepositions" string="Buttonpositionen">
<group>
<field name="btn_pos_x"/>
<field name="btn_pos_y"/>
<field name="btn_pos_w"/>
<field name="btn_pos_h"/>
</group>
</page>
<page name="baseactions" string="Aktionen">
<group>
<field name="btn_action_inactive"/>
<field name="btn_action_active"/>
<field name="btn_gallery_id"/>
<field name="btn_gallery_rows"/>
<field name="btn_gallery_cols"/>
<field name="btn_gallery_prv_w"/>
<field name="btn_gallery_prv_h"/>
</group>
<group name="specialcontent" attrs="{'invisible': [('btn_action_active', '!=', '14'),('btn_action_active', '!=', '9'),('btn_action_active', '!=', '12')]}">
<field name="btn_has_timer" widget="boolean_toggle"/>
<field name="btn_has_timer_time"/>
<field name="btn_special_actionimage"/>
<field name="btn_special_actionimage_x"/>
<field name="btn_special_actionimage_y"/>
<field name="btn_special_actionimage_w"/>
<field name="btn_special_actionimage_h"/>
<field name="btn_special_actionimage_time"/>
</group>
</page>
<page name="basetextsettings" string="Texteinstellungen">
<group>
<field name="btn_text_1_visible" widget="boolean_toggle"/>
<field name="btn_text_2_visible" widget="boolean_toggle"/>
<field name="btn_text_3_visible" widget="boolean_toggle"/>
<field name="btn_text_4_visible" widget="boolean_toggle"/>
<field name="btn_text_1_pos_x" attrs="{'invisible': [('btn_text_1_visible', '!=', True)]}"/>
<field name="btn_text_1_pos_y" attrs="{'invisible': [('btn_text_1_visible', '!=', True)]}"/>
<field name="btn_text_2_pos_x" attrs="{'invisible': [('btn_text_2_visible', '!=', True)]}"/>
<field name="btn_text_2_pos_y" attrs="{'invisible': [('btn_text_2_visible', '!=', True)]}"/>
<field name="btn_text_3_pos_x" attrs="{'invisible': [('btn_text_3_visible', '!=', True)]}"/>
<field name="btn_text_3_pos_y" attrs="{'invisible': [('btn_text_3_visible', '!=', True)]}"/>
<field name="btn_text_4_pos_x" attrs="{'invisible': [('btn_text_4_visible', '!=', True)]}"/>
<field name="btn_text_4_pos_y" attrs="{'invisible': [('btn_text_4_visible', '!=', True)]}"/>
<field name="btn_text_1_font" attrs="{'invisible': [('btn_text_1_visible', '!=', True)]}"/>
<field name="btn_text_2_font" attrs="{'invisible': [('btn_text_2_visible', '!=', True)]}"/>
<field name="btn_text_3_font" attrs="{'invisible': [('btn_text_3_visible', '!=', True)]}"/>
<field name="btn_text_4_font" attrs="{'invisible': [('btn_text_4_visible', '!=', True)]}"/>
</group>
</page>
<page name="content" string="Inhalte">
<div class="row">
<div class="col-5">
<group>
<field name="btn_image"/>
</group>
</div>
<div class="col-5">
<div class="row">
<div class="col-10">
<button name="btn_image_import" type="object" class="btn-primary o_open_tasks" string="Aus Web laden" data-hotkey="t"/>
</div>
<div class="col-10">
<button name="btn_image_import_local" type="object" class="btn-primary o_open_tasks" string="Lokale Datei hochladen" data-hotkey="l"/>
</div>
</div>
</div>
</div>
<div class="row">
<group>
<field name="btn_image_hash" readonly="1"/>
<field name="btn_image_bin" widget="image" filename="btn_image"/>
</group>
</div>
<group>
<field name="btn_playlist_zuordnung"/>
<field name="btn_playlist_filename"/>
</group>
<group>
<field name="btn_gallery_filename"/>
</group>
<group>
<field name="btn_text_1"/>
<field name="btn_text_2"/>
<field name="btn_text_3"/>
<field name="btn_text_4"/>
</group>
<group>
<field name="btn_center_video_1"/>
<field name="btn_center_video_2"/>
<field name="btn_center_video_3"/>
<field name="btn_center_video_4"/>
</group>
</page>
</notebook>
</page>
<page name="informations" string="Interne Informationen">
<group>
<field name="issaved" string="gespeichert"/>
<field name="date_create" string="Erstellt am"/>
<field name="user_create" string="Erstellt am"/>
<field name="auto_feldname"/>
<field name="display"/>
</group>
</page>
</notebook>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" options="{'post_refresh':True}" help="Follow this project to automatically track the events associated to tasks and issues of this project." groups="base.group_user"/>
<field name="activity_ids"/>
<field name="message_ids"/>
</div>
</form>
</field>
</record>
<record id="action_dss_advertisefields_fill" model="ir.actions.act_window">
<field name="name">dss_advertisefields_fill</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">dss.advertisefields</field>
<field name='target'>current</field>
<field name="view_mode">form</field>
<field name="context">{}</field>
<field name="help" type="html">
<p class="'o_view_nocontent_smiling_face">
Neues Werbefeld erstellen
</p>
</field>
</record>
</odoo>

View File

@ -52,7 +52,7 @@
<field name="btn_gallery_rows"/>
<field name="btn_gallery_cols"/>
<field name="btn_gallery_prv_w"/>
<field name="btn_gallery_pev_h"/>
<field name="btn_gallery_prv_h"/>
<field name="btn_gallery_cols"/>
</group>
<group name="specialcontent" attrs="{'invisible': [('btn_action_active', '!=', '14'),('btn_action_active', '!=', '9'),('btn_action_active', '!=', '12')]}">

View File

@ -94,10 +94,11 @@
<field name="name">DigitalSignage Projekt Vertraege</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">dss.contracts</field>
<field name="view_mode">kanban,tree,form,activity</field>
<field name="domain">[('projectid', '=', active_id)]</field>
<field name="view_mode">kanban,tree,form,activity,screenview</field>
<field name="domain">[('project', '=', active_id)]</field>
<field name="context">{
'default_projectid': active_id
'default_project': active_id,
'default_project_id': active_id,
'show_project_update': True
}
</field>
@ -292,10 +293,15 @@
</header>
<sheet>
<div class="row">
<h1>
<field name="contract_auto_name" string="Autom. Vertragskennung"/>
</h1>
</div>
<div class="col-7">
<h1>
<field name="contract_auto_name" string="Autom. Vertragskennung" style="width:100%;" />
</h1>
</div>
<div class="col-5" style="text-align: right">
<field name="werbe_feld_selected_btn_img" widget="image" attrs="{'invisible': [('werbe_feld_selected_btn_img','=',False)]}"/>
</div>
</div>
<div class="row">
<hr></hr>
</div>
@ -1177,5 +1183,14 @@
</record>
</data>
<record id="action_dss_contracts" model="ir.actions.act_window">
<field name="name">Vertrag anzeigen</field>
<field name="res_model">dss.contracts</field>
<field name="view_mode">form</field>
<field name="view_id" ref="dss_main_contracts_form"/>
<field name="target">new</field>
<field name="context">{}</field>
</record>
</odoo>

View File

@ -25,6 +25,7 @@
<tree string="Vertragsuebersicht">
<field name="uuid"/>
<field name="analyzed" widget="boolean_toggle"/>
<field name="level"/>
<field name="project_id"/>
<field name="project"/>
</tree>
@ -41,6 +42,7 @@
<group name="interval" string="Intervaldaten">
<field name="uuid"/>
<field name="analyzed" widget="boolean_toggle"/>
<field name="level"/>
<field name="project_id"/>
<field name="project" readonly="1"/>
</group>

View File

@ -46,6 +46,7 @@
<field name="grundsystemname" string="Kategorie"/>
<field name="errichtet_am"/>
<field name="aktstatus_color" widget="color"/>
<field name="btntemplate"/>
</group>
<div class="row" >
<div class="col-6">