Sicherung

This commit is contained in:
jopster 2025-07-07 08:22:23 +02:00
parent da4f3316c4
commit a2e4beba27
57 changed files with 2488 additions and 269 deletions

5
ToDo.txt Executable file
View File

@ -0,0 +1,5 @@
/*
** TODO :
** WISH :
** BUG : Screenview bring tFehler wenn ein Filter eingetragen ist - Ursache : domains[0][2] ist dann anders belegt - im dss_screenview_model.loaddata(data)
*/

View File

@ -70,12 +70,18 @@
'DigitalSignage/static/src/js/dss_screenview_renderer.js',
'DigitalSignage/static/src/js/dss_screenview_register.js',
'DigitalSignage/static/src/js/dss_screenview_model.js',
'DigitalSignage/static/src/scss/dss_nextcloudwidget.scss',
'DigitalSignage/static/src/xml/dss_nextcloudwidget.xml',
'DigitalSignage/static/src/js/dss_nextcloudwidget.js',
'DigitalSignage/static/src/xml/dss_nextcloudwidget_short.xml',
'DigitalSignage/static/src/js/dss_nextcloudwidget_short.js',
'DigitalSignage/static/src/js/form_label.js',
'DigitalSignage/static/src/js/dss_tagclick.js',
'DigitalSignage/static/src/js/form_button.js',
'DigitalSignage/static/src/js/kanban_button.js',
'DigitalSignage/static/src/xml/form_button.xml',
'DigitalSignage/static/src/js/dss_klistmanager.js',
'DigitalSignage/static/src/js/screenDesignerViewReload.js',
'DigitalSignage/static/src/xml/form_button.xml',
'DigitalSignage/static/src/xml/form_label.xml',
],
'web.assets_common': [
@ -88,7 +94,11 @@
'DigitalSignage/static/src/js/dss_screenview_injector.js',
],
'web.assets_qweb': [
'DigitalSignage/static/src/xml/kanban_button.xml',
],
},
'license': 'LGPL-3',
}
##https://www.odoo.com/documentation/16.0/developer/reference/frontend/owl_components.html
##

View File

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

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

Binary file not shown.

Binary file not shown.

View File

Binary file not shown.

View File

@ -0,0 +1,136 @@
import io
import easywebdav
import json
from odoo.http import Controller, route, request
from webdav4.client import Client
from webdav4.fsspec import WebdavFileSystem
from typing import ( BinaryIO )
import logging
import base64
_logger = logging.getLogger(__name__)
class MyController(Controller):
@route('/my/webdav/files', auth='user', type='json')
def list_files(self,path):
client = WebdavFileSystem("https://cloud.logumedia.de/remote.php/dav/files/OdooDav/", auth=("odooClient@logumedia.de", "lm2020#OdooDav"))
files = client.ls(path, detail=True)
#client.upload_file("Gorilla.jpg", "Photos/Gorilla.jpg") webdav = easywebdav.connect(
_logger.info("webdav : "+str(files))
return files
# return [{'name': f.name, 'size': f.size} for f in files]
@route('/my/webdav/upload', auth='user', type='json', methods=['POST'])
def upload_file(self, path, filename, filedata):
client = Client("https://cloud.logumedia.de/remote.php/dav/files/OdooDav/", auth=("odooClient@logumedia.de", "lm2020#OdooDav"))
filedata = filedata.split("base64,")[-1]
_logger.info('Als Byte : '+str(bytes(filedata, encoding='utf-8')))
infile = open('/opt/odoo/addons/DigitalSignage/temp/temp_in.temp', 'wb')
filedataStr=str(filedata)
_logger.info('Als String : '+str(filedataStr))
decoded_data = base64.b64decode(bytes(filedata, encoding='utf-8'))
try:
decoded_data = base64.b64decode(filedataStr)
except base64.binascii.Error as e:
if 'Incorrect padding' in str(e):
filedataStr += b'=' * (4 - len(filedataStr) % 4)
decoded_data = base64.b64decode(filedataStr)
infile.write(decoded_data)
infile.close()
_logger.info(str(f"{path}/{filename}") + str(base64.b64decode(decoded_data)))
infile = open('/opt/odoo/addons/DigitalSignage/temp/temp_in.temp', 'rb')
client.upload_fileobj(infile, f"{path}/{filename}")
_logger.info(f"File {filename} uploaded to {path}")
return True
@route('/my/webdav/getfile', auth='user', type='json')
def get_file(self,path,filename):
client = Client("https://cloud.logumedia.de/remote.php/dav/files/OdooDav/", auth=("odooClient@logumedia.de", "lm2020#OdooDav"))
#files = client.cp('dav://'+path+'/'+filename,'/opt/odoo/addons/DigitalSignage/temp/'+filename)
infile = open('/opt/odoo/addons/DigitalSignage/temp/temp.temp', 'wb')
files = client.download_fileobj(path+'/'+filename,infile)
infile = open('/opt/odoo/addons/DigitalSignage/temp/temp.temp', 'rb')
indata = infile.read()
_logger.info("webdav : "+str(indata))
encoded_file = base64.b64encode(indata)
#client.upload_file("Gorilla.jpg", "Photos/Gorilla.jpg") webdav = easywebdav.connect(
_logger.info("webdav : "+str(encoded_file))
return encoded_file
# return [{'name': f.name, 'size': f.size} for f in files]
@route('/my/webdav/makefolder', auth='user', type='json', methods=['POST'])
def make_folder(self, path, folder_name):
client = Client("https://cloud.logumedia.de/remote.php/dav/files/OdooDav/", auth=("odooClient@logumedia.de", "lm2020#OdooDav"))
folder_path = f"{path}/{folder_name}"
try:
client.mkdir(folder_path)
_logger.info(f"Folder {folder_name} created at {path}")
return {"success": True, "message": f"Folder {folder_name} created at {path}"}
except Exception as e:
_logger.error(f"Error creating folder {folder_name} at {path}: {str(e)}")
return {"success": False, "message": f"Error creating folder: {str(e)}"}
@route('/my/webdav/deletefile', auth='user', type='json')
def delete_file(self,filename):
client = Client("https://cloud.logumedia.de/remote.php/dav/files/OdooDav/", auth=("odooClient@logumedia.de", "lm2020#OdooDav"))
#files = client.cp('dav://'+path+'/'+filename,'/opt/odoo/addons/DigitalSignage/temp/'+filename)
infile = open('/opt/odoo/addons/DigitalSignage/temp/temp.temp', 'wb')
files = client.remove(filename)
return True
# return [{'name': f.name, 'size': f.size} for f in files]
@route('/dss/getscreendata', type='json', auth='user')
def getscreendata(self, Domain):
# Tu was mit den Daten
screendef =[]
return screendef
@route('/dss/setbtnfile', type='json', auth='user')
def setbtnfile(self, contract,filename):
contract = request.env['dss.contracts'].search([('id', '=', contract)])
if len(contract.werbe_feld_selected) == 1:
client = Client("https://cloud.logumedia.de/remote.php/dav/files/OdooDav/", auth=("odooClient@logumedia.de", "lm2020#OdooDav"))
#files = client.cp('dav://'+path+'/'+filename,'/opt/odoo/addons/DigitalSignage/temp/'+filename)
infile = open('/opt/odoo/addons/DigitalSignage/temp/temp_set.temp', 'wb')
files = client.download_fileobj(filename,infile)
infile = open('/opt/odoo/addons/DigitalSignage/temp/temp_set.temp', 'rb')
indata = infile.read()
encoded_file = base64.b64encode(indata)
_logger.info('JS : SetBtn File'+str(contract))
for feld in contract.werbe_feld_selected:
feld.btn_image = filename
feld.btn_image_bin = encoded_file
res = True
else:
res = "MULTI/"
ids = ""
for feld in contract.werbe_feld_selected:
res += feld.feldname
ids += str(feld.id)
if feld != contract.werbe_feld_selected[-1]:
ids += ':'
res += ':'
res += "/"+ids
return res
@route('/dss/setbtnfilefeld', type='json', auth='user')
def setbtnfilefeld(self, contract,filename,feldid):
feldids = feldid.split(':')
client = Client("https://cloud.logumedia.de/remote.php/dav/files/OdooDav/", auth=("odooClient@logumedia.de", "lm2020#OdooDav"))
#files = client.cp('dav://'+path+'/'+filename,'/opt/odoo/addons/DigitalSignage/temp/'+filename)
infile = open('/opt/odoo/addons/DigitalSignage/temp/temp_set.temp', 'wb')
files = client.download_fileobj(filename,infile)
infile = open('/opt/odoo/addons/DigitalSignage/temp/temp_set.temp', 'rb')
indata = infile.read()
encoded_file = base64.b64encode(indata)
for feld_id in feldids:
feld = request.env['dss.advertisefields'].search([('id', '=', feld_id)])
feld.btn_image = filename
feld.btn_image_bin = encoded_file
return True

4
controllers/dss_screenview_controller.py Normal file → Executable file
View File

@ -6,6 +6,7 @@ import os
import os.path
import base64
import logging
from odoo.http import request
_logger = logging.getLogger(__name__)
@ -19,4 +20,5 @@ class screenViewController(http.Controller):
_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!'}
return {'status': 'OK', 'message': 'Daten verarbeitet!'}

0
models/__pycache__/dss_ads.cpython-311.pyc Normal file → Executable file
View File

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

Binary file not shown.

Binary file not shown.

0
models/__pycache__/dss_m2mmail.cpython-311.pyc Normal file → Executable file
View File

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

Binary file not shown.

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

Binary file not shown.

View File

@ -270,6 +270,6 @@ class dssadvertisefields(models.Model):
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')
record.btn_image_bin_base64 = 'data:image/png;base64,'+str(record.btn_image_bin)
else:
record.btn_image_bin_base64 = False

View File

@ -49,6 +49,8 @@ class dssadvertisefields(models.Model):
templatefeldname = fields.Char('Template Feldname', required=True,tracking=True)
display = fields.Char('Ziel Feldname',tracking=True)
displaytemplate = fields.Many2one('dss.display.templates',string="Display Vorlage",tracking=True)
displaytemplate_fullsize_w = fields.Integer(related='displaytemplate.fullsize_w',string="Auflösung Breite",tracking=True)
displaytemplate_fullsize_h = fields.Integer(related='displaytemplate.fullsize_h',string="Auflösung Höhe",tracking=True)
feldname = fields.Char('Ziel Feldname', required=True,tracking=True)
color_used = fields.Char(string='Color Index',tracking=True)
color_unused = fields.Char(string='Color Index',tracking=True)

View File

@ -23,12 +23,15 @@ from odoo import tools
from . import dss_settings
from . import dss_ads
from odoo.exceptions import ValidationError
from odoo.exceptions import UserError
from datetime import date
from datetime import datetime
from dateutil.relativedelta import relativedelta
from pyffmpeg import FFmpeg
from tuya_iot import TuyaOpenAPI, TUYA_LOGGER
from tuya_connector import TuyaOpenAPI, TUYA_LOGGER
from webdav4.client import Client
from webdav4.fsspec import WebdavFileSystem
import sys
TUYA_LOGGER.setLevel(logging.DEBUG)
@ -115,13 +118,18 @@ class dsscontracts(models.Model):
contract_remark = fields.Html('Vertragshinweise',tracking=True)
project = fields.Many2one('dss.projects' , string='Project', store=True,tracking=True)
project_name = fields.Char(related='project.name')
project_id = fields.Integer(related='project.projectid', string='Project ID')
projectIid = fields.Integer('Project IID',tracking=True)
project_ad_structure = fields.Many2one(related='project.grundsystem_default_adstructure', string='Aufbau')
project_grundsystem_typ = fields.Char(related='project.grundsystem_typ', tracking=True)
project_grundsystem_typ = fields.Char(related='project.grundsystem_typ', tracking=True)
project_grundsystem_typ_cloud_contract_template = fields.Char(related='project.grundsystem_default_cloud_structure_contract', tracking=True)
project_grafiker = fields.Many2one(related="project.project_grafiker",tracking=True)
project_system_uuid = fields.Char(related='project.grundsystemnameuuid', tracking=True)
run_trigger = fields.Boolean(tracking=True)
run_uni_trigger = fields.Boolean(tracking=True)
run_uni_sub_trigger = fields.Boolean(tracking=True)
client = fields.Many2one('res.partner',string="Kunde (wenn angelegt)",domain="['&',('dsspartner','=',True),('dsspartner_werbung','=',True)]",tracking=True,help="Nur zu Benutzen wenn Kunden als Kontakt angelegt wurde")
client_id = fields.Char(string="KundenID (2Stellen)",help="Nur der 2 stellige letzte Teil der Kundennummer",tracking=True)
@ -164,6 +172,12 @@ class dsscontracts(models.Model):
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)
werbe_feld_selected_btn_img_base64 = fields.Char(related="werbe_feld_selected.btn_image_bin_base64")
werbe_feld_selected_btn_pos_x = fields.Integer(related="werbe_feld_selected.btn_pos_x", tracking=True)
werbe_feld_selected_btn_pos_y = fields.Integer(related="werbe_feld_selected.btn_pos_y", tracking=True)
werbe_feld_selected_btn_pos_w = fields.Integer(related="werbe_feld_selected.btn_pos_w", tracking=True)
werbe_feld_selected_btn_pos_h = fields.Integer(related="werbe_feld_selected.btn_pos_h", tracking=True)
werbe_feld_selected_btn_name = fields.Char(related="werbe_feld_selected.btn_name",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)]")
@ -180,11 +194,15 @@ class dsscontracts(models.Model):
start_date = fields.Date('Start/Auslief.datum',tracking=True,help="Datum des geplanten Startes der 1. Kampagne. Also die Uraustrahlung!")
contract_cancel_mon = fields.Integer('Kündigungsfrist Monaten',tracking=True)
contract_cancel_date = fields.Date('Kündigungsfrist Errechnet', tracking=True)
contract_iscanceled = fields.Boolean('Vertrag gekündigt',tracking=True)
contract_iscanceled_date = fields.Date('Vertrag gekündigt am',tracking=True)
contract_auto_extend = fields.Boolean('autom. V.Verlängerung',tracking=True)
contract_auto_extend_time = fields.Char('Verl. Monate',tracking=True)
scan_vertrag = fields.Binary('Datei')
scan_vertrag_filename = fields.Char("Dateiname") # Hilft, den Dateinamen zu speichern
no_cancel_calc = fields.Boolean('Berechnungen verbieten',tracking=True)
runtimesystem = fields.Selection([('M','Monatslaufzeit'),('T','Tagelaufzeit'), ('E','Eventlaufzeit'), ('S','Sonderlaufzeit')],tracking=True)
runtime_m = fields.Integer('Laufzeit Monate',tracking=True)
runtime_bonus_m = fields.Integer('zusätzl. Laufzeit Monate',tracking=True)
@ -281,7 +299,8 @@ class dsscontracts(models.Model):
web_contract = fields.Many2one('dss.web_contracts' , string='Web_Vertrag', store=True,tracking=True)
tv_reach_PLZ = fields.Char(string='Reichweite PLZ',tracking=True)
ads_radius_PLZ = fields.Integer('Umkreis PLZ in Km',tracking=True)
ads_count_perYear = fields.Selection([('30000','30.000'),('60000','60.000'),('120000','120.000'),('1000000','1.000.000')],'Einblendungen',tracking=True)
ads_count_perYear = fields.Selection([('30000','30.000'),('60000','60.000'),('120000','120.000'),('1000000','1.000.000')],'Einblendungen alt',tracking=True)
ads_count_perYear2 = fields.Integer('Einblendungen',tracking=True)
ads_topics = fields.Many2many('dss.contracts_ads_topics', string='Themenliste', tracking=True)
ads_topics_text = fields.Char('Themenliste gesamt',compute='_compute_themenliste')
@ -383,16 +402,17 @@ class dsscontracts(models.Model):
@api.onchange('project_id')
def _onchange_project_id(self):
_logger.info('project_id_change_1 : C_' + str(self) + ' - '+str(self.project))
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('project_id_change : C_' + str(self.id) + ' - '+str(cidstr)+' vs. '+str(self.contract_auto_id)+'/'+str(resstr)+' vs '+str(self.contract_auto_name));
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('project_id_change : C_' + str(self.id) + ' - '+str(cidstr)+' vs. '+str(self.contract_auto_id)+'/'+str(resstr)+' vs '+str(self.contract_auto_name))
self.contract_auto_name = resstr
self.contract_auto_id = cidstr
@ -407,7 +427,7 @@ class dsscontracts(models.Model):
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));
_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:
@ -876,7 +896,7 @@ class dsscontracts(models.Model):
else:
_logger.info('Click auf Werbekampagne : C_'+str(self.id)+'A_'+str(kamp.id)+' Media gleich '+str(kampagne.need_media))
else:
_logger.info('Prüfe Medien : C_'+str(self.id)+'A_'+str(kamp.id)+' Keine Kampagne gefunden !')
_logger.info('Prüfe Medien : C_'+str(self.id)+'A_' +str(kamp.id)+' Keine Kampagne gefunden !')
# _logger.info('Click auf Werbekampagne : '+str(self.id)+' 4 '+str(kampagne.id))
return {
'type': 'ir.actions.act_window',
@ -978,7 +998,7 @@ class dsscontracts(models.Model):
def pyaction_new_contract_kanban(self):
action = self.env['ir.actions.act_window'].with_context({'default_contractid': self.id})._for_xml_id('DigitalSignage.action_dss_project_new_contract_kanban')
action['display_name'] = self.contract_name
# action['domain'] = '[["projectid","=","4"]]'
action['domain'] = '[["id","=","'+str(self.id)+'"]]'
# context = action['context'].replace('', str(self.id))
# context = ast.literal_eval(context)
# context.update({
@ -989,7 +1009,47 @@ class dsscontracts(models.Model):
return action
def pyaction_dss_project_make_contract(self):
action = self.env['ir.actions.act_window'].with_context({'default_projectid': self.id})._for_xml_id('DigitalSignage.action_dss_project_view_contract')
#raise UserError(_("Inhalt : "+str(self.id)+" - "+str(self.contract_name)+" - "+str(self.client_id)))
newid =self.id
self.contract_auto_id = str(self.project_id) + str(self.client_id)
self.contract_auto_name = str(self.project_id) + str(self.client_id) + ' ' + str(self.contract_name)
projectcloudpath = self.project.cloudlink
if not projectcloudpath:
self.cloudlink = str(dss_settings.dssSettings.getprojectpath(self,self.project))+str(dss_settings.dssSettings.getClientpath(self,self))
else:
if projectcloudpath[0] != '$':
self.cloudlink = str(projectcloudpath)+str(dss_settings.dssSettings.getClientpath(self,self))
else:
self.cloudlink = str(dss_settings.dssSettings.getprojectpath(self,self.project))+str(dss_settings.dssSettings.getClientpath(self,self))
action = (self.env["confirmation.wizard"].confirm_message(_("Ist die Bezeichnung des neuen Kunden : "+self.contract_auto_name+" richtig ?( "+str(self.cloudlink)+" ) (Cloudornder wird entsprechend angelegt) !"),title="Bitte bestätigen",method="createcontract",records=self,callback_params={"template":self.id})
)
if action:
return action
def create_cloud_structure_client(self, newClient):
_logger.info("Create Cloud Structure for Client "+str(newClient.id)+" - "+str(newClient.cloudlink))
cloudpath = str(newClient.cloudlink)
client = Client("https://cloud.logumedia.de/remote.php/dav/files/OdooDav/", auth=("odooClient@logumedia.de", "lm2020#OdooDav"))
_logger.info("Neuer Cloud Path : "+str(cloudpath))
try:
#client.mkdir(new_folder)
#_logger.info("Make Cloud Path : "+str(new_folder))
_logger.info("Create Standard Cloud Structure for Client "+str(newClient.id)+" - "+str(newClient.cloudlink))
client.copy(newClient.project_grundsystem_typ_cloud_contract_template+'/',cloudpath)
_logger.info("Make Standard Cloud Path : "+str(cloudpath+'/'+str(newClient.project_grundsystem_typ_cloud_contract_template)))
except Exception as e:
_logger.info("Make Cloud Path error : "+str(e))
return True
def createcontract(self,template):
newid = template
newClient = self.env['dss.contracts'].search([('id','=',newid)])
dsscontracts.create_cloud_structure_client(self,newClient)
_logger.info('Neu angelegt : '+str(self.id)+' - '+str(self.contract_name)+' - '+str(self.client_id))
action = self.env['ir.actions.act_window'].with_context({'default_projectid': self.id})._for_xml_id('DigitalSignage.action_open_create_contract_new_edit')
action['domain'] = '[["id","=","'+str(newid)+'"]]'
action['res_id'] = newid
return action
@ -1046,3 +1106,157 @@ class dsscontracts(models.Model):
self.client_short_telefon=self.client.phone
self.client_short_mobil=self.client.mobile
self.client_short_email=self.client.email
def buildText(self):
_logger.info('Build Text for Contract : C_'+str(self.id))
if self.project_id:
projekt_id = self.project_id
else:
projekt_id = '000'
if self.project_name:
projekt = self.project_name
else:
projekt = 'Unbekannt'
if self.contract_name:
vertrag_name = self.contract_name
else:
vertrag_name = 'Unbekannt'
if self.contract_auto_id:
vertrag_id = self.contract_auto_id
else:
vertrag_id = 'XXXXX'
if self.client_short_vorname:
vname = self.client_short_vorname
else:
vname = 'Unbekannt'
if self.client_short_name:
name = self.client_short_name
else:
name = 'Unbekannt'
if self.client_short_strasse:
vstrasse = self.client_short_strasse
else:
vstrasse = 'Unbekannt'
if self.client_short_plz:
vplz = self.client_short_plz
else:
vplz = '00000'
if self.client_short_ort:
vort = self.client_short_ort
else:
vort = 'unbekannt'
vplz_vort = '%s %s' % (vplz,vort)
if self.client_short_email:
vemail = 'ist per Email über %s zu erreichen' % (self.client_short_email)
else:
vemail = 'ist nicht per Email zu erreichbar'
if self.client_short_telefon:
vtelefon = 'ist per Telefon unter %s zu erreichen' % (self.client_short_telefon)
else:
vtelefon = 'ist nicht per Telefon zu erreichen'
if self.client_short_mobil:
vmobil = 'ist per Mobiltelefon unter %s zu erreichen' % (self.client_short_mobil)
else:
vmobil = 'ist nicht per Mobiltelefon zu erreichen'
textprojekt= 'Es ist im Projekt %s_%s ' % (projekt_id,projekt)
vertragkopftext = 'ein Vertrag mit der Kundennummer %s und der Vertragskennung %s.' % (vertrag_id,vertrag_name)
kundentext = 'Dieser Kunde heisst %s %s und wohnt in der %s in %s. Der Kunde %s und %s und %s' % (vname,name,vstrasse,vplz_vort,vemail,vtelefon,vmobil)
if self.client_short_mobil:
vmobil = 'ist per Mobiltelefon unter %s zu erreichen' % (self.client_short_mobil)
else:
vmobil = 'ist nicht per Mobiltelefon zu erreichen'
if self.start_date:
startzeit = self.start_date.strftime('%d.%m.%Y')
else:
startzeit = 'unbekannt'
if self.contract_date:
startzeit = self.contract_date.strftime('%d.%m.%Y')
if self.runtime_finish:
if self.runtime_finish < date.today():
endzeit = 'Er ist bereits abgelaufen am %s' % (self.runtime_finish.strftime('%d.%m.%Y'))
else:
endzeit = 'Er endet am %s' % (self.runtime_finish.strftime('%d.%m.%Y'))
else:
endzeit = 'unbekannt'
laufzeitmodel = 'Laufzeitmodell unbekannt'
if self.runtimesystem == 'M':
laufzeitmodel = 'eine monatliche Laufzeit mit %s Monaten und %s Monaten Bonus' % (self.runtime_m,self.runtime_bonus_m)
elif self.runtimesystem == 'T':
laufzeitmodel = 'eine tägliche Laufzeit mit %s Tagen ' % (self.runtime_t)
elif self.runtimesystem == 'E':
laufzeitmodel = 'eine ereignisabhängige Laufzeit mit %s Ereignissen' % (len(self.runtime_events))
elif self.runtimesystem == 'S':
if self.runtime_finish:
laufzeitmodel = 'ein stichtagsabhängig Laufzeit bis zum %s' % (self.runtime_finish.strftime('%d.%m.%Y'))
else:
laufzeitmodel = 'ein stichtagsabhängig Laufzeit unbekannt'
kuendigungsfrist = 'Die Kündigungsfrist beträgt %s Monate' % (self.contract_cancel_mon)
if self.contract_cancel_date:
kuendigungsfrist = 'Die Kündigungsfrist beträgt %s Monate und endet am %s' % (self.contract_cancel_mon,self.contract_cancel_date.strftime('%d.%m.%Y'))
if self.contract_cancel_date < date.today():
kuendigungsfrist = 'Die Kündigungsfrist beträgt %s Monate und endet am %s' % (self.contract_cancel_mon,self.contract_cancel_date.strftime('%d.%m.%Y'))
vertragtext = 'Der Vertrag hat die Vertragskennung %s und ist am %s begonnen. Der Vertrag hat %s . %s. %s' % (vertrag_id,startzeit,laufzeitmodel,endzeit,kuendigungsfrist)
text = textprojekt + " "+vertragkopftext + kundentext + '. '+ vertragtext
return text
raise ValidationError((text))
_logger.info('Build Text for Contract : C_'+str(self.id)+' - '+str(text))
return text
def buildallText(self):
_logger.info('Build all Text for Contract : C_'+str(self))
if self and "all" in str(self[0]):
self = self.env['dss.contracts'].search([])
if not self:
raise ValidationError(_("The first record contains 'all' in its string representation."))
all_contract_text = ''
contracts = []
for record in self:
_logger.info('Build Text for Contract : C_'+str(record.id))
singletext = ' Ein Vertrag mit der ID '+str(record.id)+': '+record.buildText()
contracts += [singletext]
_logger.info('Build Text for Contract : C_'+str(record.id)+' - '+str(singletext))
all_contract_text += singletext
#raise ValidationError((all_contract_text))
return contracts
@api.model
def newwizzard(self,id):
project = self.env['dss.projects'].search([('id', '=', id)], limit=1)
_logger.info("Create new Contract Wizard - Project : "+str(project))
action = self.env["ir.actions.actions"]._for_xml_id("DigitalSignage.action_open_create_contract")
action['context'] = {'default_project': project.id}
return action

View File

@ -80,12 +80,18 @@ class dssimportinvoicelist(models.Model):
entry = self.env['dss.invoices'].create({'invoiceid':line[0],'from_import':self.id,'invoicename':line[1],'invoiceclientnr':line[3],'contract':client.id,'invoice_date':datetime.strptime(line[4],"%d.%m.%Y"),'is_printed':(line[5]=="Endgltig"),'ammount_netto':line[6].strip(),'ammount_ust':line[7].strip(),'ammount_brutto':line[8].strip(),'is_payed':(line[11]=="Ja"),'invoice_type':line[9],'invoice_reference':line[10]})
BotText='Rechnung ['+str(line[0])+'] für '+str(line[1])+' ('+str(line[3])+') neu erstellt als '
if (line[11]=="Ja"):
entry.is_payed_date = self.date_create
entry.is_payed = True
entry.is_payed_date = self.date_create
client.contract_payment_done = True
client.contract_payment_done_date = self.date_create
BotText = BotText +' bezahlt'
else:
client.contract_payment_done = False
client.contract_payment_done_date = ''
BotText = BotText +' nicht bezahlt'
client.client_invoices = [(4, entry.id)]
else:
client=oldimport.contract
if oldimport.is_payed:
if (line[11]=="Ja"):
_logger.info("Import Invoices - "+str(line[0])+' allready imported and payed - delete bevore import again !')
@ -95,6 +101,8 @@ class dssimportinvoicelist(models.Model):
if (line[11]=="Ja"):
oldimport.is_payed = True
oldimport.is_payed_date = self.date_create
client.contract_payment_done = True
client.contract_payment_done_date = self.date_create
BotText='Rechnung ['+str(line[0])+'] für '+str(line[1])+' ('+str(line[3])+') geändert in bezahlt !'
_logger.info("Import Invoices - "+str(line[0])+' allready imported and not Payed - now Payed')
else:

View File

@ -29,6 +29,8 @@ from dateutil.relativedelta import relativedelta
from pyffmpeg import FFmpeg
from tuya_iot import TuyaOpenAPI, TUYA_LOGGER
from tuya_connector import TuyaOpenAPI, TUYA_LOGGER
from webdav4.client import Client
from webdav4.fsspec import WebdavFileSystem
import sys
TUYA_LOGGER.setLevel(logging.DEBUG)
@ -66,10 +68,16 @@ class dssprojects(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')
grundsystem_default_cloud_structure_project = fields.Char(related='grundsystemname.default_cloud_structure_project')
grundsystem_default_cloud_structure_contract = fields.Char(related='grundsystemname.default_cloud_structure_contract')
grundsystem_showonlinestate = fields.Boolean(related='grundsystemname.showonlinestate')
grundsystem_showonlinestate_type = fields.Selection(related='grundsystemname.showonlinestate_type')
grundsystemicon_different = fields.Boolean('Grundsystem Icon anders',default=False,tracking=True)
grundsystemicon_different_image = fields.Binary('Anderes Icon',tracking=True)
btntemplate = fields.Many2one('dss.display.templates',string='Buttonsvorlage',tracking=True)
btntemplate_displaytemplate_fullsize_w = fields.Integer(related='btntemplate.fullsize_w',string="Auflösung Breite",tracking=True)
btntemplate_displaytemplate_fullsize_h = fields.Integer(related='btntemplate.fullsize_h',string="Auflösung Höhe",tracking=True)
standort = fields.Char('Beschreibung des Standortes')
standort_strasse = fields.Char('Strasse des Projektes',tracking=True)
@ -111,6 +119,9 @@ class dssprojects(models.Model):
zeitenf_off = fields.Float('Ausschaltzeit',tracking=True)
zeiten_notiz = fields.Char('Schaltzeiten Notizen', tracking=True)
errichtet_am = fields.Date('Errichtungstag',tracking=True)
cancel_am_in = fields.Date('Kündigung Insti - Eingang Kündigung',tracking=True)
cancel_am_to = fields.Date('Kündigung Insti - Kündigung zum',tracking=True)
finish_am = fields.Date('Beendigungstag',tracking=True)
standort_inout = fields.Selection([('indoor','im Gebäude'), ('outdoor','Aussenbereich'), ('semiindoor','Überdachter Aussenbereich'),('Divers','Andere Art')],tracking=True)
date_start_compute = fields.Date('Kalender Start intern',compute='_compute_calendar_start')
@ -423,13 +434,140 @@ class dssprojects(models.Model):
else:
_logger.info("UUID : "+str(uuid)+" not found")
return False
def getScreenViewData(self,domain):
ViewParams = {}
ViewParams.screensize_x=1980
ViewParams.screensize_y=1024
return ViewParams
def method(self):
return (
self.env["confirmation.wizard"]
.with_context(hide_cancel=True)
.confirm_no_action_message(
message="Message",
title="Notification"
)
)
def method(self):
return (
self.env["confirmation.wizard"]
.with_context(hide_cancel=True)
.confirm_no_action_message(
message="Message",
title="Notification"
)
)
@api.model
def newwizzard(self):
_logger.info("Create new Project")
action = self.env["ir.actions.actions"]._for_xml_id("DigitalSignage.new_wizard_action")
action['context'] = {'default_state': 'start'}
return action
class dssprojects_new_wizard(models.TransientModel):
_name = "dss.projects.new.wizard"
_description = "DigitalSignage Projekte - Wizard"
#_inherit = ['mail.thread','mail.activity.mixin']
_inherit = ['multi.step.wizard.mixin']
_rec_name = "projectid"
state = fields.Selection(selection='_selection_state', string='Status', default='start')
allow_back = fields.Boolean('Allow Back', default=False)
projectid = fields.Integer('Projekt ID', required=True)
projektname = fields.Char('Projektname', required=True)
name = fields.Char('Interner Name', required=True)
aktstatus = fields.Many2one('dss.projectstate',string='Aktueller Status:')
grundsystemname = fields.Many2one('dss.systemtypen', required=True)
grundsystemnameuuid = fields.Char(related='grundsystemname.uuid')
grundsystemicon = fields.Image(related='grundsystemname.icon')
grundsystem_default_adstructure = fields.Many2one(related='grundsystemname.default_adstructure')
grundsystem_ordner = fields.Char(related='grundsystemname.default_cloud_path')
isdifferendcouldstructure = fields.Boolean('Andere Cloud Struktur ?')
cloudgenerate = fields.Boolean('Cloud Struktur erzeugen ?')
differendcouldstructurefolder = fields.Char('Cloud Struktur')
kundenbeschreibung = fields.Char('Kundenbeschreibung')
run_uni_trigger = fields.Boolean('Allgemeine Trigger aktiv',default=True)
cloudlink = fields.Char('Cloud Verzeichnis',help='Verzeichnis für das Project innerhalb des Cloud Struktur')
standort = fields.Char('Beschreibung des Standortes')
standort_strasse = fields.Char('Strasse des Projektes')
standort_plz = fields.Char('PLZ des Projektes')
standort_ort = fields.Char('Ort des Projektes')
standort_bundesland = fields.Many2one('res.country.state',string='Bundesland des Projektes')
standort_land = fields.Many2one('res.country',string='Land des Projektes')
vertragsschreiber = fields.Many2one('res.partner',domain="['&',('dsspartner','=',True),('dsspartner_vertrieb','=',True)]")
standortpartner = fields.Many2one('res.partner',domain="['&',('dsspartner','=',True),('dsspartner_standort','=',True)]")
vertriebspartner = fields.Many2many('res.partner',domain="['&',('dsspartner','=',True),('dsspartner_vertrieb','=',True)]")
project_grafiker = fields.Many2one('res.partner',domain="['&',('dssinternpartner','=',True),('dssinternpartner_grafik','=',True)]")
@api.model
def _selection_state(self):
return [
('start', 'Start'),
('configure', 'Configure'),
('custom', 'Customize'),
('final', 'Final'),
]
def open_next(self):
_logger.info("Open Next")
# if self.state == 'start': self.state = 'configure'
# elif self.state == 'configure': self.state = 'custom'
# elif self.state == 'custom': self.state = 'final'
# elif self.state == 'final': self.action_create_project()
self.action_create_project()
def open_previous(self):
_logger.info("Open Previous")
if self.state == 'configure':
self.state = 'start'
elif self.state == 'custom':
self.state = 'configure'
elif self.state == 'final':
self.state = 'custom'
def state_exit_start(self):
self.state = 'configure'
def state_exit_configure(self):
self.state = 'custom'
def state_exit_custom(self):
self.state = 'final'
def _create_cloud_structure(self, newProjekt, isdifferendcouldstructure, differendcouldstructurefolder):
_logger.info("Create Cloud Structure for Project "+str(newProjekt.id)+" - "+str(newProjekt.cloudlink))
if isdifferendcouldstructure:
cloudpath = str(differendcouldstructurefolder)
else:
cloudpath = str(newProjekt.grundsystem_default_cloud_structure_project)
client = Client("https://cloud.logumedia.de/remote.php/dav/files/OdooDav/", auth=("odooClient@logumedia.de", "lm2020#OdooDav"))
new_folder = dss_settings.dssSettings.getprojectpath(self,newProjekt)
_logger.info("Neuer Cloud Path : "+str(new_folder))
try:
#client.mkdir(new_folder)
#_logger.info("Make Cloud Path : "+str(new_folder))
if isdifferendcouldstructure:
_logger.info("Create Differend Cloud Structure for Project "+str(newProjekt.id)+" - "+str(newProjekt.cloudlink))
client.copy(differendcouldstructurefolder+'/',new_folder)
_logger.info("Make Differend Cloud Path : "+str(new_folder+'/'+str(differendcouldstructurefolder)))
else:
_logger.info("Create Standard Cloud Structure for Project "+str(newProjekt.id)+" - "+str(newProjekt.cloudlink))
client.copy(newProjekt.grundsystem_default_cloud_structure_project+'/',new_folder)
_logger.info("Make Standard Cloud Path : "+str(new_folder+'/'+str(newProjekt.grundsystem_default_cloud_structure_project)))
except Exception as e:
_logger.info("Make Cloud Path error : "+str(e))
return True
def action_create_project(self):
_logger.info("Create Project")
newProjekt = self.env['dss.projects'].create({'projektname':self.projektname,'name':self.name,'aktstatus':self.aktstatus.id,'projectid':self.projectid,'grundsystemname':self.grundsystemname.id,'grundsystemnameuuid':self.grundsystemnameuuid,'grundsystemicon':self.grundsystemicon,'grundsystem_ordner':self.grundsystem_ordner,'grundsystem_default_adstructure':self.grundsystem_default_adstructure,'standort':self.standort,'standort_ort':self.standort_ort,'standort_plz':self.standort_plz,'standort_land':self.standort_land.id,'standort_bundesland':self.standort_bundesland.id,'standort_strasse':self.standort_strasse,'vertragsschreiber':self.vertragsschreiber.id,'standortpartner':self.standortpartner.id,'vertriebspartner': self.vertriebspartner.ids,'project_grafiker': self.project_grafiker.id,'short_partner_description':self.kundenbeschreibung})
newProjekt.cloudlink = dss_settings.dssSettings.getprojectpath(self,newProjekt)
if newProjekt:
_logger.info("Project created with ID : "+str(newProjekt.id))
if self.cloudgenerate:
_logger.info("Create Cloud Structure for Project "+str(newProjekt.id)+" - "+str(newProjekt.cloudlink))
self._create_cloud_structure(newProjekt,self.isdifferendcouldstructure, self.differendcouldstructurefolder)
return True

View File

@ -68,7 +68,7 @@ class dssSettings(models.Model):
settings = (self.env['dss.settings'].search([],limit=1))
wert = settings._origin.read([valuename])[0][valuename]
return wert
@api.model
def _get_path_converted(self,path,record):
alls = ''
_logger.info("GetPath with " + str(path)+ " and Record : "+str(record.id))
@ -158,6 +158,29 @@ class dssSettings(models.Model):
myview.unlink()
return 0
@api.model
def getprojectpath(self,project):
_logger.info("Get Project Path for "+str(project.id))
if project:
settings = (self.env['dss.settings'].search([],limit=1))
alls = dssSettings._get_path_converted(self,settings.def_project_cloudpath,project)
_logger.info("Get Project Path - Ergebnis : " + str(alls))
return alls
else:
_logger.info("Get Project Path - kein Projekt gefunden")
return ''
@api.model
def getClientpath(self,client):
_logger.info("Get Client Path for "+str(client.id))
if client:
settings = (self.env['dss.settings'].search([],limit=1))
alls = dssSettings._get_path_converted(self,settings.def_contract_cloudpath,client)
_logger.info("Get Client Path - Ergebnis : " + str(alls))
return alls
else:
_logger.info("Get Client Path - kein Client gefunden")
return ''
class dssSettingsSave(models.Model):

View File

@ -41,7 +41,9 @@ class dsssystemtypen(models.Model):
icon = fields.Image()
icon_5050 = fields.Image("Icon 50",compute='_compute_icon_5050')
default_adstructure = fields.Many2one('dss.adstructures',string='Standard-Werbeaufbau', tracking=True)
default_cloud_path = fields.Char('Standard Cloud Path', tracking=True)
default_cloud_path = fields.Char('Standard Cloud Pfad', tracking=True)
default_cloud_structure_project = fields.Char('Standard Cloud Projekt-Struktur (Pfad)', tracking=True)
default_cloud_structure_contract = fields.Char('Standard Cloud Kunden-Struktur (Pfad)', tracking=True)
email_template_welcome = fields.Many2one('mail.template',string='Mailvorlage für Willkommen', tracking=True)
email_template_zuarbeit = fields.Many2one('mail.template',string='Mailvorlage für Zuarbeiterrinnerung', tracking=True)
email_template_abzug = fields.Many2one('mail.template',string='Mailvorlage für Korrekturabzug', tracking=True)

View File

@ -83,6 +83,7 @@ class dsscontracts(models.Model):
werbe_feld_tv = fields.Selection([('L-Banner','L-Banner'),('Countdown','Countdown')], 'Paket', tracking=True)
werbe_feld_web = fields.Selection([('Standard','Standard'),('Premium','Premium')], 'Paket', tracking=True)
zahlweise = fields.Selection([('einmalig','einmalig'),('jaehrlich','jährlich'),('sonder','Sonderzahlweise')], 'Zahlweise', tracking=True)
paymentinterval = fields.Many2one('dss.payintervals',string='Abrechnungsinterval',tracking=True)
main_runtime = fields.Integer('Gesamtcliplänge',tracking=True)
split_runtime_count = fields.Integer('Clip Teilungen',tracking=True)
@ -113,12 +114,14 @@ class dsscontracts(models.Model):
tv_reach_PLZ = fields.Char('Reichweite PLZ',tracking=True)
ads_radius_PLZ = fields.Integer('Umkreis PLZ in Km',tracking=True)
ads_count_perYear = fields.Selection([('30000','30.000'),('60000','60.000'),('120000','120.000'),('1000000','1.000.000')],'Einblendungen',tracking=True)
# ads_count_perYear_related = fields.Selection(related='dss.contracts.ads_count_perYear',tracking=True)
ads_count_perYear = fields.Selection([('30000','30.000'),('60000','60.000'),('120000','120.000'),('1000000','1.000.000')],'Einblendungen alt',tracking=True)
ads_count_perYear2 = fields.Integer('Einblendungen',tracking=True)
# ads_count_perYear_related_re = fields.Selection(related='dss.contracts.ads_count_perYear',tracking=True)
ads_topic = fields.Selection([('auto','Auto'),('beauty','Beauty & Fashion'),('wirtschaft','Wirtschaft, Finanzen & News'),('food','Food'),('gesundheit','Gesundheit'),('lifestyle','Lifestyle'),('living','Living'),('entertainment','Entertainment'),('reise','Reise'),('technik','Technik'),('individuell','Individuell')],'Themen', tracking=True)
ads_topics = fields.Many2many('dss.contracts_ads_topics', string='Themenliste', tracking=True)
grafik_zuarbeitBis = fields.Date("Zuarbeit bis", tracking=True)
grafikerstellung = fields.Boolean("Grafikerstellung Logumedia", tracking=True)
boarding = fields.Boolean("Boarding", tracking=True)
scan_vertrag = fields.Binary('Datei')
file_name = fields.Char(string='Dateiname')
@ -167,6 +170,7 @@ class dsscontracts(models.Model):
'contract_auto_id': self.contract_auto_id,
'contract_name': self.contract_name,
'contract_state': self.env['dss.contractstate'].search([("statusname","=","Angelegt")]).id,
'paymentinterval': self.paymentinterval.id,
'werbe_feld_selected': self.werbe_feld_selected,
'client': self.client.id,
'client_short_vorname': self.client_short_vorname,
@ -179,7 +183,7 @@ class dsscontracts(models.Model):
'client_short_plz': self.client_short_plz,
'client_short_website': self.client_short_website,
'client_short_company': self.client_short_company,
'ads_count_perYear': self.ads_count_perYear,
'ads_count_perYear2': self.ads_count_perYear2,
'runtimesystem': self.runtimesystem,
'runtime_m': self.runtime_m,
'runtime_t': self.runtime_t,

View File

@ -1,5 +1,6 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
digitalsignage_dss_projects_group_user,access.dss.projects,model_dss_projects,base.group_user,1,1,1,1
digitalsignage_dss_projects_new_wizard_group_user,access.dss.projects.new.wizard,model_dss_projects_new_wizard,base.group_user,1,1,1,1
digitalsignage_dss_systems_group_user,access.dss.systems,model_dss_systems,base.group_user,1,1,1,1
digitalsignage_dss_geraetetypen_group_user,access.dss.geraetetypen,model_dss_geraetetypen,base.group_user,1,1,1,1
digitalsignage_dss_systemtypen_group_user,access.dss.systemtypen,model_dss_systemtypen,base.group_user,1,1,1,1

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 digitalsignage_dss_projects_group_user access.dss.projects model_dss_projects base.group_user 1 1 1 1
3 digitalsignage_dss_projects_new_wizard_group_user access.dss.projects.new.wizard model_dss_projects_new_wizard base.group_user 1 1 1 1
4 digitalsignage_dss_systems_group_user access.dss.systems model_dss_systems base.group_user 1 1 1 1
5 digitalsignage_dss_geraetetypen_group_user access.dss.geraetetypen model_dss_geraetetypen base.group_user 1 1 1 1
6 digitalsignage_dss_systemtypen_group_user access.dss.systemtypen model_dss_systemtypen base.group_user 1 1 1 1

View File

@ -0,0 +1,448 @@
/** @odoo-module **/
import { registry } from "@web/core/registry";
import { useBus, useService } from "@web/core/utils/hooks";
import { useInputField } from "@web/views/fields/input_field_hook";
import time from 'web.time';
var translation = require('web.translation');
var _t = translation._t;
const { Component,useRef} = owl;
var rpc = require('web.rpc')
export class cloudFolderViewerField extends Component {
static template = 'FieldDateMultipleDate'
setup(){
super.setup();
this.input = useRef('inputdate')
this.rpc = useService('rpc')
window.input = useRef('inputpath')
this.input = useRef('inputpath')
window.this=this
useInputField({ getValue: () => this.props.value || "", refName: "inputpath" });
if (this.props.value) {
this.readfiles(this.props.value);
} else {
this.readfiles('');
}
window.oncontextmenu = function (ev) {
if (ev.target.classList.contains('FileExplorerFilesField')) {
var ele = ev.target.parentElement;
} else {
if (ev.target.classList.contains('Breadcrumb_Text')) {
var ele = ev.target.parentElement;
} else {
var ele = ev.target;
}
}
console.log(ele);
if (ele.classList.contains('FileExplorerFilesLine') || ele.classList.contains('Breadcrumb')) {
console.log(ele);
if ((ele.dataset.type == "Breadcrumb") || (ele.dataset.type == "Folder")) {
var MainBox = document.querySelector(".CloudfileBrowser");
var contextBox = document.querySelector(".ContextFolderMenu");
var FeldSelectBox = document.querySelector(".FieldSelectMenu");
var CloudText = document.querySelector(".ContextCloudLinkMenuItem_text");
contextBox.style.left = `${ev.clientX-ele.offsetLeft}px`;
contextBox.style.top = `${ev.layerY}px`;
FeldSelectBox.style.left = `${ev.clientX-ele.offsetLeft}px`;
FeldSelectBox.style.top = `${ev.pageY}px`;
contextBox.classList.add("visible");
contextBox.classList.remove("hidden");
CloudText.innerHTML = "";
contextBox.dataset.file=ele.dataset.file;
CloudText.innerHTML = ele.dataset.file;
return false; // cancel default menu
}
if (ele.dataset.type == "File") {
var contextBox = document.querySelector(".ContextFileMenu");
var FeldSelectBox = document.querySelector(".FieldSelectMenu");
contextBox.style.left = `${ev.clientX-ele.offsetLeft}px`;
contextBox.style.top = `${ev.layerY}px`;
FeldSelectBox.style.left = `${ev.clientX-ele.offsetLeft}px`;
FeldSelectBox.style.top = `${ele.offsetTop}px`;
contextBox.classList.add("visible");
contextBox.classList.remove("hidden");
contextBox.dataset.file=ele.dataset.file;
return false; // cancel default menu
}
}
return false; // cancel default menu
}
}
_onUploadClick(ev) {
var contextBox = document.querySelector(".ContextMenu");
contextBox.classList.remove("visible");
contextBox.classList.add("hidden");
var ext = contextBox.dataset.file;
const toBase64 = file => new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = reject;
});
const fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.multiple = true;
fileInput.addEventListener('change', async (event) => {
const files = event.target.files;
if (files.length > 0) {
for (const file of files) {
try {
await rpc.query({
route: '/my/webdav/upload',
params: {
path: ext || '/',
filename: file.name,
filedata: await toBase64(file),
},
});
alert(_t(`File "${file.name}" uploaded successfully.`));
} catch (error) {
alert(_t(`Failed to upload file "${file.name}".`));
}
}
this.readfiles(ext || '/');
}
});
fileInput.click();
}
_onSetCloudClick(ev) {
console.log(ev);
if (ev.target.classList.contains('FileExplorerFilesLine')) {
var ele = ev.target.parentElement;
} else {
if (ev.target.classList.contains('Breadcrumb_Text')) {
var ele = ev.target.parentElement;
} else {
if (ev.target.classList.contains('ContextMenuItem_text')) {
var ele = ev.target.parentElement.parentElement;
} else {
if (ev.target.classList.contains('ContextCloudLinkMenuItem_text')) {
var ele = ev.target.parentElement.parentElement;
} else {
var ele = ev.target;
}
}
}
}
console.log(ele);
if (confirm(_t("Folder selected : " + ele.dataset.file + "\nAre you sure you want to select this folder?"))) {
window.this.props.record.update({ [window.this.props.name]: '/'+ele.dataset.file });
return false;
}
}
_onContextMenueMouseLeave(ev) {
var contextBox = document.querySelector(".ContextFileMenu");
if (contextBox.dataset.file != undefined) {
contextBox.dataset.file = undefined;
}
contextBox.classList.remove("visible");
contextBox.classList.add("hidden");
var contextBox = document.querySelector(".ContextFolderMenu");
if (contextBox.dataset.file != undefined) {
contextBox.dataset.file = undefined;
}
contextBox.classList.remove("visible");
contextBox.classList.add("hidden");
var contextBox = document.querySelector(".ContextMenu");
if (contextBox.dataset.file != undefined) {
contextBox.dataset.file = undefined;
}
contextBox.classList.remove("visible");
contextBox.classList.add("hidden");
var FeldSelectBox = document.querySelector(".FieldSelectMenu");
if (FeldSelectBox.dataset.file != undefined) {
FeldSelectBox.dataset.file = undefined;
}
FeldSelectBox.classList.remove("visible");
FeldSelectBox.classList.add("hidden");
}
_onSetBtnImageClickField(ev) {
var FeldSelectBox = document.querySelector(".FieldSelectMenu");
FeldSelectBox.classList.remove("visible");
FeldSelectBox.classList.add("hidden");
console.log(ev);
var ele = ev.target.parentElement;
console.log(ele);
var ext = ele.dataset.file;
console.log(ext);
console.log(ele.dataset.feldid);
//.split('.').pop().trim();
console.log('/'+ext+'/');
if (ext.match(/\.(jpg|jpeg|png|gif)$/i)) {
console.log('/'+ext+'/+');
rpc.query({
route: '/dss/setbtnfilefeld',
params: {contract: this.props.record.data.id,
filename: ele.dataset.file,
feldid: ele.dataset.feldid},
}).then(success => {
console.log(success);
if (success != true) {
alert(_t("Error: " + success));
} else {
alert(_t(" Erfolgreich zugewiesen !"));
}
})
}
}
_onSetBtnImageClick(ev) {
console.log(this.props.record.data.id);
var contextBox = document.querySelector(".ContextMenu");
contextBox.classList.remove("visible");
contextBox.classList.add("hidden");
var ext = contextBox.dataset.file;
//.split('.').pop().trim();
console.log('/'+ext+'/');
if (ext.match(/\.(jpg|jpeg|png|gif)$/i)) {
console.log('/'+ext+'/+');
rpc.query({
route: '/dss/setbtnfile',
params: {contract: this.props.record.data.id,
filename: contextBox.dataset.file},
}).then(success => {
console.log(success);
if (success != true) {
if (success.startsWith("MULTI")) {
var fields = success.split("/")[1]
var fieldIds = success.split("/")[2]
var FeldSelectBox = document.querySelector(".FieldSelectMenu");
FeldSelectBox.classList.add("visible");
FeldSelectBox.classList.remove("hidden");
var FeldSelectBox = document.querySelector(".item0");
if (FeldSelectBox != undefined) {
FeldSelectBox.parentNode.dataset.feldid = fieldIds;
FeldSelectBox.parentNode.dataset.feld = fields;
}
var Singlefields = fields.split(":");
var Singlefieldids = fieldIds.split(":");
var Nr = 0;
Singlefields.forEach(element => {
Nr += 1;
var FeldSelectBox = document.querySelector(".item"+Nr);
if (FeldSelectBox != undefined) {
FeldSelectBox.parentNode.classList.add("visible");
FeldSelectBox.parentNode.classList.remove("hidden");
FeldSelectBox.parentNode.dataset.feldid = Singlefieldids[Nr-1];
FeldSelectBox.parentNode.dataset.feld = element;
FeldSelectBox.parentNode.dataset.file = ext;
FeldSelectBox.innerHTML = 'Auf Feld '+element+' zuweisen';
FeldSelectBox.dataset.field = Singlefieldids[Nr-1];
}
});
} else {
alert(_t("Error: " + success));
}
}
})
}
}
_onMoveToArchivClick(ev) {
var contextBox = document.querySelector(".ContextMenu");
contextBox.classList.remove("visible");
contextBox.classList.add("hidden");
alert('move to archive');
}
_onDownloadClick(ev) {
var contextBox = document.querySelector(".ContextMenu");
contextBox.classList.remove("visible");
contextBox.classList.add("hidden");
alert('download');
}
_onDeleteClick(ev) {
var contextBox = document.querySelector(".ContextMenu");
contextBox.classList.remove("visible");
contextBox.classList.add("hidden");
var filename = contextBox.dataset.file;
console.log(filename);
try {
rpc.query({
route: '/my/webdav/deletefile',
params: {
filename: filename || '/',
},
}).then(success => {;
console.log(success);
if (success != true) {
alert(_t("Error: " + success));
} else {
alert(_t(" Datein "+filename+" Erfolgreich gelöscht !"));
}
$(".FileExplorerFilesBackground").html("");
const parentPath = filename.substring(0, filename.lastIndexOf('/'));
console.log(filename);
console.log(parentPath);
this.readfiles(parentPath);
});
} catch (error) {
console.error(error);
alert(_t(`Failed to delete file "${filename}".`));
}
}
_onMakeFolderClick(ev) {
var contextBox = document.querySelector(".ContextMenu");
contextBox.classList.remove("visible");
contextBox.classList.add("hidden");
var filename = contextBox.dataset.file;
console.log(filename);
var foldername = prompt(_t("Folder name"), "New Folder");
if (foldername == null) {
return false;
}
if (foldername == "") {
alert(_t("Error: Folder name is empty"));
return false;
}
try {
rpc.query({
route: '/my/webdav/makefolder',
params: {
filename: filename || '/',
foldername: foldername,
},
}).then(success => {;
console.log(success);
if (success != true) {
alert(_t("Error: " + success));
} else {
alert(_t(" Ordner "+foldername+" Erfolgreich erstellt !"));
}
});
} catch (error) {
console.error(error);
alert(_t(`Failed to create folder "${foldername}".`));
}
$(".FileExplorerFilesBackground").html("");
this.readfiles(filename);
}
_onSelectDateField(ev) {
$(".FileExplorerFilesBackground").html("");
this.readfiles(this.input.el.value);
}
readfiles(path) {
$(".FileExplorerFilesBackground").html("");
path = path.trim(); // Trim whitespace from the path
var prepath = path;
rpc.query({
route: '/my/webdav/files',
params: {path: path},
}).then(files => {
//container = ev.document.getElementById('FileExplorerFiles');
//console.log(conatiner);
var etype = "";
var myline ="";
if (path != "") {
var preprepath = prepath.substring(0, prepath.lastIndexOf('/'));
myline = "<div class='FileExplorerFilesLine' id='.' data-file='"+preprepath+"' data-type='Folder'>";
myline += "<div class='FileExplorerFilesField FileExplorerFilesLineIcon'>Folder</div>";
myline += "<div class='FileExplorerFilesField FileExplorerFilesLineName'>..</div>";
myline += "<div class='FileExplorerFilesField FileExplorerFilesLineSize'>-</div>";
myline += "<div class='FileExplorerFilesField FileExplorerFilesLineDate'>-</div>";
myline += "</div>";
self.$('.FileExplorerFilesBackground').append(myline)
}
var breadcrumbox = document.querySelector(".Breadcrumb_Text");
breadcrumbox.innerHTML="";
breadcrumbox.innerHTML=prepath;
breadcrumbox = document.querySelector(".Breadcrumb");
breadcrumbox.dataset.file=prepath;
files.forEach(element => {
myline="";
if (element.type == "file") {
etype = "File"
} else {
etype = "Folder"
};
if (path != "") {
var mypath = path.length;
if (path[0] == "/") {
mypath = mypath - 1;
}
var ename = element.name.slice(mypath+1);
} else {
var ename = element.name;
}
myline += "<div class='FileExplorerFilesLine' id='"+element.etag+"' data-file='"+element.name+"' data-fileonly='"+ename+"' data-prepath='"+prepath+"' data-type='"+etype+"'>";
myline += "<div class='FileExplorerFilesField FileExplorerFilesLineIcon'>"+etype+"</div>";
myline += "<div class='FileExplorerFilesField FileExplorerFilesLineName' data-file='"+ename+"'>"+ename+"</div>";
myline += "<div class='FileExplorerFilesField FileExplorerFilesLineSize'>"+element.size+"</div>";
myline += "<div class='FileExplorerFilesField FileExplorerFilesLineDate'>"+element.modified+"</div>";
myline += "</div>";
self.$('.FileExplorerFilesBackground').append(myline)
//container.appendChild(myline);
});
});
}
_onFileclick(ev){
this._onContextMenueMouseLeave(ev);
if (ev.target.classList.contains('FileExplorerFilesField')) {
var ele = ev.target.parentElement;
} else {
var ele = ev.target;
}
if (ele.dataset.type == "Folder") {
$(".FileExplorerFilesBackground").html("");
this.readfiles(ele.dataset.file);
}
if (ele.dataset.type == "File") {
var ext = ele.dataset.file;
//.split('.').pop().trim();
console.log('/'+ext+'/');
if (ext.match(/\.(jpg|jpeg|png|gif)$/i)) {
console.log('/'+ext+'/+');
rpc.query({
route: '/my/webdav/getfile',
params: {path: ele.dataset.prepath,
filename: ele.dataset.fileonly},
}).then(file64 => {
console.log(file64);
var contentbox = document.querySelector(".o_content");
var imgelement = document.querySelector(".ImageShowContainerBlur");
console.log(imgelement);
imgelement.classList.add("ImageShowContainerBlurVisible");
imgelement.classList.remove("hidden");
imgelement.classList.add("isvisible");
var img = imgelement.querySelector(".ImageShow");
img.src = "data:image/*;base64,"+file64;
contentbox.append(imgelement);
});
};
}
}
_onImageClick(ev) {
var contentbox = document.querySelector(".o_content");
var imgelement = document.querySelector(".ImageShowContainerBlurVisible");
imgelement.classList.remove("isvisible");
imgelement.classList.add("hidden");
}
_onCloseclick(ev) {
var contentbox = document.querySelector(".o_content");
var imgelement = document.querySelector(".ImageShowContainerBlurVisible");
imgelement.classList.remove("isvisible");
imgelement.classList.add("hidden");
}
}
registry.category("fields").add("cloudFolderViewer", cloudFolderViewerField);

View File

@ -0,0 +1,251 @@
/** @odoo-module **/
import { registry } from "@web/core/registry";
import { useBus, useService } from "@web/core/utils/hooks";
import { useInputField } from "@web/views/fields/input_field_hook";
import time from 'web.time';
import { configListController } from "./form_button";
var translation = require('web.translation');
var _t = translation._t;
const { Component,useRef} = owl;
var rpc = require('web.rpc')
export class cloudFolderViewerFieldShort extends Component {
static template = 'cloudFolderViewerShort'
setup(){
super.setup();
this.input = useRef('inputdate')
this.rpc = useService('rpc')
this.id = Math.random().toString().slice(2, 6); // Generate a 4-digit random number as a string
this.insertid = false
window.input = useRef('inputpath');
this.input = useRef('inputpath')
window.
window.this=this
useInputField({ getValue: () => this.props.value || "", refName: "inputpath" });
window.onmousedown = function (ev) {
if (ev.target.classList.contains('CloudfileBrowserShort_Input')) {
ev.target.innerHTML = "";
const template = document.createElement('template');
template.innerHTML = `
<div class="CloudfileBrowser ${window.this.id}">
<div class="Breadcrumb ${window.this.id}" data-file="">
<span class="Breadcrumb_Text ${window.this.id}"></span>
</div>
<div class="FileExplorerFilesBackground ${window.this.id}"></div>
</div>
<div class="FileExplorerBackground ${window.this.id}">
<div class="FileExplorerHeaderBackground ${window.this.id}" t-on-click="_onHeaderclick">
<div class="FileExplorerHeader_fields FileExplorerHeader_field_type ${window.this.id}">
<span class="header_field_type ${window.this.id}">Typ</span>
</div>
<div class="FileExplorerHeader_fields FileExplorerHeader_field_name ${window.this.id}">
<span class="header_field_name ${window.this.id}">Name</span>
</div>
<div class="FileExplorerHeader_fields FileExplorerHeader_field_size ${window.this.id}">
<span class="header_field_size ${window.this.id}">Größe</span>
</div>
<div class="FileExplorerHeader_fields FileExplorerHeader_field_date ${window.this.id}">
<span class="header_field_date ${window.this.id}">Datum</span>
</div>
</div>
<div class="FileExplorerFilesBackground ${window.this.id}" t-on-click="_onFileclick" id="FileExplorerFiles">
</div>
</div>
<div class="ContextFolderMenu ${window.this.id} hidden">
<div class="ContextCloudLinkMenuItem ${window.this.id}">
<span class="ContextCloudLinkMenuItem_text ${window.this.id}"></span>
</div>
</div>
<div class="ImageShowContainerBlur ${window.this.id} hidden">
<img class="ImageShow" />
</div>
`;
ev.target.parentElement.appendChild(template.content.cloneNode(true));
if (this.props.value) {
this.readfiles(this.props.value);
} else {
this.readfiles('');
}
}
}
window.onmouseenter = function (ev) {
ev.target.add('hover');
}
window.oncontextmenu = function (ev) {
if (ev.target.classList.contains('FileExplorerFilesField_'+this.id)) {
var ele = ev.target.parentElement;
} else {
if (ev.target.classList.contains('Breadcrumb_Text')) {
var ele = ev.target.parentElement;
} else {
var ele = ev.target;
}
}
console.log(ele);
if (ele.classList.contains('FileExplorerFilesLine '+window.this.id) || ele.classList.contains('Breadcrumb '+window.this.id)) {
console.log(ele);
if ((ele.dataset.type == "Breadcrumb") || (ele.dataset.type == "Folder")) {
var MainBox = document.querySelector(".CloudfileBrowser ."+window.this.id);
var contextBox = document.querySelector(".ContextFolderMenu ."+window.this.id);
var CloudText = document.querySelector(".ContextCloudLinkMenuItem_text ."+window.this.id);
contextBox.style.left = `${ev.clientX-ele.offsetLeft}px`;
contextBox.style.top = `${ev.layerY}px`;
contextBox.classList.add("visible");
contextBox.classList.remove("hidden");
CloudText.innerHTML = "";
contextBox.dataset.file=ele.dataset.file;
CloudText.innerHTML = ele.dataset.file;
return false; // cancel default menu
}
}
return false; // cancel default menu
}
}
_onSetCloudClick(ev) {
console.log(ev);
if (ev.target.classList.contains('FileExplorerFilesLine '+window.this.id)) {
var ele = ev.target.parentElement;
} else {
if (ev.target.classList.contains('Breadcrumb_Text '+window.this.id)) {
var ele = ev.target.parentElement;
} else {
if (ev.target.classList.contains('ContextMenuItem_text')) {
var ele = ev.target.parentElement.parentElement;
} else {
if (ev.target.classList.contains('ContextCloudLinkMenuItem_text')) {
var ele = ev.target.parentElement.parentElement;
} else {
var ele = ev.target;
}
}
}
}
console.log(ele);
if (confirm(_t("Folder selected : " + ele.dataset.file + "\nAre you sure you want to select this folder?"))) {
window.this.props.record.update({ [window.this.props.name]: '/'+ele.dataset.file });
return false;
}
}
_onContextMenueMouseLeave(ev) {
var contextBox = document.querySelector(".ContextFolderMenu");
if (contextBox.dataset.file != undefined) {
contextBox.dataset.file = undefined;
}
contextBox.classList.remove("visible");
contextBox.classList.add("hidden");
var contextBox = document.querySelector(".ContextMenu");
if (contextBox.dataset.file != undefined) {
contextBox.dataset.file = undefined;
}
contextBox.classList.remove("visible");
contextBox.classList.add("hidden");
}
_onSelectDateField(ev) {
$(".FileExplorerFilesBackground_"+this.id).html("");
this.readfiles(this.input.el.value);
}
readfiles(path) {
if (this.insertid == false) {
var s = self.$(".CloudfileBrowserShort");
console.log(s);
s.addClass("CloudfileBrowserShort_" + this.id);
this.insertid = true;
}
// $(".FileExplorerFilesBackground_"+this.id).html("");
path = path.trim(); // Trim whitespace from the path
var prepath = path;
rpc.query({
route: '/my/webdav/files',
params: {path: path},
}).then(files => {
//container = ev.document.getElementById('FileExplorerFiles');
//console.log(conatiner);
var etype = "";
var myline ="";
if (path != "") {
var preprepath = prepath.substring(0, prepath.lastIndexOf('/'));
myline = "<div class='FileExplorerFilesLine "+window.this.id+"' id='.' data-file='"+preprepath+"' data-type='Folder'>";
myline += "<div class='FileExplorerFilesField "+window.this.id+" FileExplorerFilesLineIcon'>Folder</div>";
myline += "<div class='FileExplorerFilesField "+window.this.id+" FileExplorerFilesLineName'>..</div>";
myline += "<div class='FileExplorerFilesField "+window.this.id+" FileExplorerFilesLineSize'>-</div>";
myline += "<div class='FileExplorerFilesField "+window.this.id+" FileExplorerFilesLineDate'>-</div>";
myline += "</div>";
self.$('.FileExplorerFilesBackground').append(myline)
}
var breadcrumbox = document.querySelector(".Breadcrumb_Text ."+window.this.id);
breadcrumbox.innerHTML="";
breadcrumbox.innerHTML=prepath;
breadcrumbox = document.querySelector(".Breadcrumb ."+window.this.id);
breadcrumbox.dataset.file=prepath;
files.forEach(element => {
myline="";
if (element.type == "file") {
etype = "File"
} else {
etype = "Folder"
};
if (path != "") {
var mypath = path.length;
if (path[0] == "/") {
mypath = mypath - 1;
}
var ename = element.name.slice(mypath+1);
} else {
var ename = element.name;
}
myline += "<div class='FileExplorerFilesLine "+window.this.id+"' id='"+element.etag+"' data-file='"+element.name+"' data-fileonly='"+ename+"' data-prepath='"+prepath+"' data-type='"+etype+"'>";
myline += "<div class='FileExplorerFilesField "+window.this.id+" FileExplorerFilesLineIcon'>"+etype+"</div>";
myline += "<div class='FileExplorerFilesField "+window.this.id+" FileExplorerFilesLineName' data-file='"+ename+"'>"+ename+"</div>";
myline += "<div class='FileExplorerFilesField "+window.this.id+" FileExplorerFilesLineSize'>"+element.size+"</div>";
myline += "<div class='FileExplorerFilesField "+window.this.id+" FileExplorerFilesLineDate'>"+element.modified+"</div>";
myline += "</div>";
self.$('.FileExplorerFilesBackground '+window.this.id).append(myline)
//container.appendChild(myline);
});
});
}
_onFileclick(ev){
this._onContextMenueMouseLeave(ev);
if (ev.target.classList.contains('FileExplorerFilesField') && ev.target.classList.contains(window.this.id)) {
var ele = ev.target.parentElement;
} else {
var ele = ev.target;
}
if (ele.dataset.type == "Folder") {
$(".FileExplorerFilesBackground "+window.this.id).html("");
this.readfiles(ele.dataset.file);
}
if (ele.dataset.type == "File") {
}
}
_onImageClick(ev) {
var contentbox = document.querySelector(".o_content");
var imgelement = document.querySelector(".ImageShowContainerBlurVisible");
imgelement.classList.remove("isvisible");
imgelement.classList.add("hidden");
}
_onCloseclick(ev) {
var contentbox = document.querySelector(".o_content");
var imgelement = document.querySelector(".ImageShowContainerBlurVisible");
imgelement.classList.remove("isvisible");
imgelement.classList.add("hidden");
}
}
registry.category("fields").add("cloudFolderViewerShort", cloudFolderViewerFieldShort);

View File

@ -14,7 +14,6 @@ export class ScreenViewArchParser extends XMLParser {
const fieldNextIds = {};
let autofocusFieldId = null;
const activeFields = {};
alert("begin")
this.visitXML(xmlDoc, (node) => {
if (node.tagName === "field") {
alert('field')

View File

@ -3,60 +3,36 @@ import { Layout } from "@web/search/layout";
import { useBus, useService } from "@web/core/utils/hooks";
import { useModel } from "@web/views/model";
import { Component, onWillStart, useState} from "@odoo/owl";
import { ScreenViewRenderer } from "./dss_screenview_renderer";
const { onRendered } = owl;
export class ScreenViewController extends Component {
setup() {
alert('setup')
/* this.orm = useService("orm");
this.orm = useService("orm");
this.dialogService = useService("dialog");
this.router = useService("router");
this.user = useService("user");
this.viewService = useService("view");
this.ui = useService("ui");
this.state = useState({
isDisabled: false,
fieldIsDirty: false,
});
useBus(this.ui.bus, "resize", this.render);
this.resModel = this.props.resModel
this.resDomain = this.props.domain
// useBus(this.ui.bus, "resize", this.render);
var Container = document.querySelector('.o_action_manager');
var DarkPanel = '<div class="o_dark_panel"></div>';
console.log(Container);
console.log(DarkPanel);
Container.insertAdjacentHTML('afterend', DarkPanel);
this.model = useState(
new this.props.Model(
this.orm,
this.props.resModel,
this.props.fields,
this.props.archInfo,
this.props.domain
)
);
this.archInfo = this.props.archInfo;
const activeFields = this.archInfo.activeFields;
this.beforeLoadResolver = null;
const beforeLoadProm = new Promise((r) => {
this.beforeLoadResolver = r;
});
const { create, edit } = this.archInfo.activeActions;
this.canCreate = create && !this.props.preventCreate;
this.canEdit = edit && !this.props.preventEdit;
let mode = this.props.mode || "edit";
if (!this.canEdit) {
mode = "readonly";
}
this.model = useModel(
this.props.Model,
{
resModel: this.props.resModel,
resId: this.props.resId || false,
resIds: this.props.resIds,
fields: this.props.fields,
activeFields,
viewMode: "form",
rootType: "record",
mode,
beforeLoadProm,
component: this,
},
{
ignoreUseSampleModel: true,
}
);
*/
// The controller create the model and make it reactive so whenever this.model is
// accessed and edited then it'll cause a rerendering
// this.model = useState(
@ -71,6 +47,7 @@ export class ScreenViewController extends Component {
onWillStart(async () => {
await this.model.load();
});
onRendered(() => {
@ -78,11 +55,15 @@ export class ScreenViewController extends Component {
});
}
displayName() {
return this.model.root.data.display_name || this.env._t("New");
openView(domain, views, context) {
alert('openview');
}
displayName() {
return "DigitalSignage Projekt Vertraege - ScreenView ";
}
};
ScreenViewController.template = "dss.screenview";
ScreenViewController.components = { Layout };
ScreenViewController.components = { Layout, ScreenViewRenderer };

0
static/src/js/dss_screenview_injector.js Normal file → Executable file
View File

View File

@ -1,27 +1,111 @@
/** @odoo-module **/
import { useService } from "@web/core/utils/hooks";
import { KeepLast } from "@web/core/utils/concurrency";
import { Model } from "@web/views/model";
export class ScreenViewModel extends Model {
setup(params) {
// concurrency management
export class ScreenViewModel {
constructor(orm, resModel, fields, archInfo, domain) {
this.orm = orm;
this.resModel = resModel;
// We can access arch information parsed by the beautiful arch parser
const { fieldFromTheArch } = archInfo;
this.fieldFromTheArch = fieldFromTheArch;
this.fields = fields;
this.domain = domain;
this.keepLast = new KeepLast();
this.searchParams = {
context: {},
domain: [],
domains: [],
groupBy: [],
};
this.domain = []
}
// setup(params) {
// // concurrency management
// //alert(params.toString());
// this.rpc = useService("rpc");
// this.keepLast = new KeepLast();
// this.resModel = params.resModel;
// this.resDomain = params.component.props.domain;
// this.searchParams = {
// context: {},
// domain: [],
// domains: [],
// groupBy: [],
// };
// this.params = params;
// this.domain = []
// }
async load() {
//The keeplast protect against concurrency call
alert('load')
// const { length, records } = await this.keepLast.add(
// this.orm.webSearchRead(this.resModel, this.domain, [this.fieldFromTheArch], {})
// );
// this.records = records;
// this.recordsLength = length;
//The keeplast protect against concurrency call
console.log(this);
await this.keepLast.add(this.loaddata(this)); //this.loaddata(records));
console.log(this);
var element=document.querySelector('.o_dark_panel')
element.remove();;
}
/**
* @protected
*/
async loaddata(data) {
var newrecords = [];
var nullrecord = {};
var x = 0;
const projectrecord = await this.orm.searchRead('dss.projects', [['id','=',this.domain[0][2]]], [],{});
console.log('00- '+JSON.stringify(projectrecord));
nullrecord.max_w=projectrecord[0].btntemplate_displaytemplate_fullsize_w;
console.log(projectrecord[0].btntemplate_displaytemplate_fullsize_w);
nullrecord.max_h=projectrecord[0].btntemplate_displaytemplate_fullsize_h;
console.log(projectrecord[0].btntemplate_displaytemplate_fullsize_h);
var width = window.innerWidth-140;
console.log(width);
var scale_faktor = (width / nullrecord.max_w);
var height = Math.round((nullrecord.max_h+40) * scale_faktor) ;
console.log(height);
nullrecord.scale = scale_faktor;
nullrecord.screenwidth = width + 40;
nullrecord.screenheight = height + 100;
nullrecord.key=1111;
nullrecord.id=1111;
newrecords[0] = nullrecord;
x=1;
const { length, records } = await this.orm.webSearchRead('dss.contracts', this.domain, [],{});
for (const rawRecord of records) {
for (const feld of rawRecord.werbe_feld_selected) {
const feldrecords = await this.orm.searchRead('dss.advertisefields', [['id','=',feld],['is_btn','=',true]], [],{});
if (feldrecords.length > 0) {
var frecord = {}
frecord.id=rawRecord.id+'_'+feldrecords[0].id;
frecord.werbe_feld_selected_btn_pos_x=feldrecords[0].btn_pos_x*scale_faktor;
frecord.werbe_feld_selected_btn_pos_y=feldrecords[0].btn_pos_y*scale_faktor ;
frecord.werbe_feld_selected_btn_pos_w=feldrecords[0].btn_pos_w*scale_faktor;
frecord.werbe_feld_selected_btn_pos_h=feldrecords[0].btn_pos_h*scale_faktor;
frecord.werbe_feld_selected_btn_img=feldrecords[0].btn_image_bin;
frecord.uuid = rawRecord.uuid;
frecord.contractid = rawRecord.id;
frecord.shortwerbe_feld_selected = feldrecords[0].btn_fieldname;
frecord.client_short_company = rawRecord.client_short_company;
frecord.client_short_name = rawRecord.client_short_name;
frecord.client_short_vorname = rawRecord.client_short_vorname;
frecord.client_short_strasse = rawRecord.client_short_strasse;
frecord.client_short_plz = rawRecord.client_short_plz;
frecord.client_short_ort = rawRecord.client_short_ort;
frecord.key=rawRecord.id+'_'+feldrecords[0].id;
newrecords[x] = frecord;
x++;
}
}
}
this.records = newrecords;
this.recordsLength = newrecords.length;
}
async fetchrecords(length,data) {
//alert('fetchrecords')
alert(this.active_id)
const rawRecords = await this.orm.searchRead('dss.contracts', this.domain, []);
for (const rawRecord of rawRecords) {
records[rawRecord.id] = rawRecord;
}
return records;
}
}

View File

@ -1,30 +1,45 @@
/** @odoo-module **/
import AbstractView from "web.AbstractView";
import BasicView from "web.BasicView";
import view_registry from 'web.view_registry';
import { registry } from "@web/core/registry";
import { ScreenViewModel } from "./dss_screenview_model";
import { ScreenViewController } from "./dss_screenview_controller";
import { ScreenViewRenderer } from "./dss_screenview_renderer";
import { ScreenViewArchParser } from "./dss_screenview_archparser";
import AbstractView from "web.AbstractView";
import BasicView from "web.BasicView";
import view_registry from 'web.view_registry';
import RendererWrapper from 'web.RendererWrapper';
export const HelloWorldView = BasicView.extend({
viewType: 'screenview',
config: _.extend({}, BasicView.prototype.config, {
Renderer: ScreenViewRenderer
}),
export const ScreenView = {
type: "screenview",
getRenderer(parent, state) {
// alert('getRenderer')
state = Object.assign({}, state, this.rendererParams);
return new RendererWrapper(null, this.config.Renderer, state);
display_name: "ScreenView ",
icon: "fa fa-picture-o",
multiRecord: true,
ArchParser: ScreenViewArchParser,
Controller: ScreenViewController,
Model: ScreenViewModel,
Renderer: ScreenViewRenderer,
props: (genericProps, view) => {
const { ArchParser } = view;
const { arch } = genericProps;
const archInfo = new ArchParser().parse(arch);
return {
...genericProps,
Model: view.Model,
Renderer: view.Renderer,
archInfo,
};
},
});
};
view_registry.add('screenview', HelloWorldView)
registry.category("views").add("screenview", ScreenView);
//view_registry.add('screenview', HelloWorldView)
return ScreenView;
return HelloWorldView;
ScreenViewModel
// /*
// /** @odoo-module **/

View File

@ -4,6 +4,7 @@ import { useEnv, Component, markup, onWillStart,onMounted,onWillUnmount, useRef,
import { registry } from "@web/core/registry";
import { browser } from "@web/core/browser/browser";
var rpc = require('web.rpc')
export class ScreenViewRenderer extends Component {
aktcontext = "";
@ -11,16 +12,13 @@ export class ScreenViewRenderer extends Component {
setup() {
// alert('render '+JSON.stringify(this.props))
this.rpc = useService("rpc");
//this.action = useService("action");
this.action = useService("action");
this.env = useEnv();
onWillStart(async () => {
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(props) {
@ -28,106 +26,42 @@ export class ScreenViewRenderer extends Component {
await this.render_Screen(props)
}
// Event-Handler für den Click
//_handleClick(event) {
handleClick() {
// if (event.target.classList.contains("tooltip-container")) {
if (event.target.classList.contains("clickcontainer")) {
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);
console.log(event.target.dataset.uuid);
console.log(event.target.dataset.id);
this.action.doAction({
type: 'ir.actions.act_window',
res_model: 'dss.contracts',
res_id: parseInt(event.target.dataset.id),
resId: parseInt(event.target.dataset.id),
views: [[false, "form"]],
view_mode: "form",
target: "current",
});
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'];
// document.addEventListener("click",_onclickevent)
// document.addEventListener("change",_onchangeevent)
if (props.domain != []) {
// alert(' - '+props)
var def1 =this.rpc({
// model: 'dss.advertisefields.templates',
// method: "get_data",
model: 'dss.projects',
method: "get_data",
args: [[props.context.active_id]],
}).then(function (result) {
var displaycss = 'background-color:#38AFA0;float:left;border-style: solid;border-width: 0.1px;'
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 / 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+20//+topstart
var ele_pos_h=element.pos_h*scale_faktor
var ele_pos_w=element.pos_w*scale_faktor
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});
})
}
var meins = "";
var divele = "";
var templates = []
var templates = ['MainSection'];
console.log('1!!'+JSON.stringify(props))
console.log(this);
console.log(this.max_h);
var maxx = props.records[0].max_w;
var maxy = props.records[0].max_h;
var width = window.innerWidth-140;
var scale_faktor = (width / maxx)
var height = Math.round((maxy+40) * scale_faktor)
props.screenwidth = width + 40
props.scale = scale_faktor
props.screenheight = height + 100
props.records.resId = false
console.log('1!! - '+props);
}
}

47
static/src/js/dss_tagclick.js Executable file
View File

@ -0,0 +1,47 @@
/** @odoo-module **/
import { _t } from 'web.core';
import { useService } from "@web/core/utils/hooks";
import { Many2ManyTagsFieldColorEditable } from "@web/views/fields/many2many_tags/many2many_tags_field";
import { patch } from "@web/core/utils/patch";
const Dialog = require('web.Dialog');
patch(Many2ManyTagsFieldColorEditable.prototype, '/DigitalSignage/static/src/js/dss_tagclick.js',{
setup(){
this._super.apply(this,arguments);
this.action = useService("action");
},
onBadgeClick(ev, record) {
var copytext = ev.target.innerText;
var buttons = [
{
text: _t("Ok"),
classes: 'btn-primary',
close: true,
},
];
new Dialog(self, {
size: 'medium',
buttons: [
{
text: _t("Bearbeiten"), classes: 'btn-primary', close: true,
click: () => {
this.action.doAction({
type: 'ir.actions.act_window',
res_model: this.props.relation,
res_id: record.data.id,
views: [[false, 'form']],
target: 'current',
});
},
},
{
text: _t("Cancel"), close: true
},
],
$content: $('<div>', {
text: _t(" Feld bearbeiten ?"),
}),
}).open();
return this._super.apply(this, arguments);
}
})

View File

@ -9,6 +9,7 @@ var rpc = require('web.rpc')
export class configKanbanController extends KanbanController {
setup() {
super.setup();
this.action = useService("action");
}
SaveButtonClicked() {
alert("")
@ -59,6 +60,26 @@ export class configKanbanController extends KanbanController {
args: [],
});
}
newwizzard() {
const queryString = window.location.hash;
const urlParams = new URLSearchParams(queryString);
if (urlParams.get('model') == 'dss.projects') {
var action = rpc.query({
model: 'dss.projects',
method: 'newwizzard',
args: [],
});
}
if (urlParams.get('model') == 'dss.contracts') {
var action = rpc.query({
model: 'dss.contracts',
method: 'newwizzard',
args: [urlParams.get('active_id')],
});
}
this.action.doAction(action);
}
}
registry.category("views").add("button_in_kanban", {

View File

@ -0,0 +1,276 @@
.datepicker-dropdown {
top: 0;
left: 0;
padding: 4px
}
.FileExplorerBackground {
background-color: #5b5b5b;
border-color: #000000 ;
border-radius: 5px;
padding: 5px;
height: 400px
}
.FileExplorerHeaderBackground {
background-color: #3b3b3b;
border-color: #000000 ;
border-radius: 5px;
padding: 2px;
height: 35px;
width: 100%;
}
.FileExplorerHeader_fields {
background-color: #5b5bbb;
border-color: #000000 ;
border-radius: 5px;
padding: 5px;
float: left;
margin-left: 2px;
margin-right: 2px;
height: 100%;
}
.FileExplorerHeader_field_type {
width: 10%;
}
.FileExplorerHeader_field_name {
width: 40%;
}
.FileExplorerHeader_field_size {
width: 20%;
}
.FileExplorerHeader_field_date {
width: 27%;
}
.header_field_type {
color: #fff;
}
.header_field_name {
color: #fff;
}
.header_field_size {
color: #fff;
}
.header_field_date {
color: #fff;
}
.FileExplorerFilesBackground {
background-color: #5b5b5b;
border-color: #000000 ;
border-radius: 5px;
padding: 5px;
height: 90%;
width: 100%;
overflow: auto;
}
.FileExplorerFilesLine {
background-color: #3b3b3b;
border-color: #000000 ;
border-radius: 5px;
height: 20px;
width: 100%;
}
.FileExplorerFilesLine:hover {
background-color: #5b5bbb;
}
.FileExplorerFilesField {
white-space: nowrap;
overflow:hidden;
text-overflow: ellipsis;
color: #fff;
float: left;
}
.FileExplorerFilesLineIcon {
padding-left: 2px;
width: 10%;
}
.FileExplorerFilesLineName {
width: 40%;
}
.FileExplorerFilesLineSize {
width: 20%;
}
.FileExplorerFilesLineDate {
width: 27%;
}
.ImageShowContainerBlur {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.ImageShowContainer_shadow {
background-color: #5b5bbb;
position: fixed;
width: 90%;
height: 90%;
top: 120px;
left: 5%;
/* for IE */
opacity: 0.7;
box-shadow: 0 0 0 1000px rgba(0,0,0,.9);
/* for real browsers */
box-shadow: 0 0 0 100vmax rgba(0,0,0,.9);
pointer-events: none;
}
.ImageShowContainer_Header {
background-color: #FFFFFF;
position: fixed;
width: 100%;
height: 40px;
top: 0px;
left: 0px;
}
.ImageShowContainer_Header_text {
color: #000;
font-size: 20px;
font-weight: bold;
padding-left: 10px;
padding-top: 10px;
}
.ImageShowContainer {
background-color: #5b5bbb;
position: fixed;
width: 90%;
height: 90%;
top: 50px;
left: 5%;
}
.ImageShowClose {
position: absolute;
top: 0px;
right: 0px;
background-color: #5b5bbb;
border-radius: 5px;
padding: 2px;
width: 40px;
height: 40px;
text-align: center;
font-size: 20px;
color: #fff;
font-weight: bold;
}
.ImageShowClose:hover {
background-color: #8b8bbb;
}
.ImageShowCloseIcon {
color: #fff;
font-size: 20px;
}
.hidden {
display: none;
}
.isvisible {
display: block;
}
.visible {
display: block;
}
.ImageShow {
position: relative;
width: 90%;
top: 10px;
left: 10px;
}
.ContextMenu {
position: absolute;
background-color: #5b5bbb;
border-radius: 5px;
padding: 2px;
width: 200px;
height: auto;
z-index: 9999;
}
.ContextMenuItem {
background-color: #5b5bbb;
}
.ContextMenuItem:hover {
background-color: #8b8bbb;
}
.ContextMenuItem_text {
color: #fff;
font-size: 12px;
padding: 5px;
}
.ContextMenuItemSeperator {
background-color: #5b5bbb;
}
.ContextMenuItemSeperatorText {
color: #aaf;
font-size: 10px;
text-decoration: italic;
}
.FieldSelectMenu {
position: absolute;
background-color: #5b5bbb;
border-radius: 5px;
padding: 2px;
width: 200px;
height: auto;
z-index: 9999;
}
.FieldSelectMenuItem {
background-color: #5b5bbb;
}
.FieldSelectMenuItem:hover {
background-color: #8b8bbb;
}
.FieldSelectMenuItem_text {
color: #fff;
font-size: 12px;
padding: 5px;
}
.FieldSelectMenuItemSeperator {
background-color: #5b5bbb;
}
.ContextCloudLinkMenuItem_text {
color: #b9f;
font-size: 10px;
padding: -2px;
padding-left:5px;
}
.BreadcrumbBackground {
background-color: #5b5b5b;
border-color: #000000 ;
border-radius: 5px;
padding: 2px;
padding-left:5px;
height: 25px
}
.Breadcrumb {
}
.Breadcrumb_Text {
color: #b9f;
font-size: 12px;
}

View File

@ -95,4 +95,37 @@
-ms-transform: scale(1);
transform: scale(1);
}
.screenview_main {
background-color:#000000;
padding:20px;
float:left;
}
.screenview_field {
background-color:#38AFA0;
float:left;
border-style: solid;
border-width: 0.1px;
position:absolute;
}
.screenview_image {
width:100%;
height:100%;
}
.o_dark_panel {
background-color: #000000;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0.7;
z-index: 100;
}
.hidden {
display: none;
}

View File

@ -0,0 +1,122 @@
<templates>
<t t-name="FieldDateMultipleDate" owl="1">
<div class="CloudfileBrowser">
<input type="text" t-on-change="_onSelectDateField" t-ref="inputpath"/>
<div class="FileExplorerBackground BreadcrumbBackground">
<div class="Breadcrumb" data-type='Breadcrumb'>
<span class="Breadcrumb_Text"></span>
</div>
</div>
<div class="FileExplorerBackground">
<div class="FileExplorerHeaderBackground" t-on-click="_onHeaderclick">
<div class="FileExplorerHeader_fields FileExplorerHeader_field_type">
<span class="header_field_type">Typ</span>
</div>
<div class="FileExplorerHeader_fields FileExplorerHeader_field_name">
<span class="header_field_name">Name</span>
</div>
<div class="FileExplorerHeader_fields FileExplorerHeader_field_size">
<span class="header_field_size">Größe</span>
</div>
<div class="FileExplorerHeader_fields FileExplorerHeader_field_date">
<span class="header_field_date">Datum</span>
</div>
</div>
<div class="FileExplorerFilesBackground" t-on-click="_onFileclick" id="FileExplorerFiles">
</div>
</div>
<div class="ContextMenu ContextFileMenu hidden" t-on-mouseleave="_onContextMenueMouseLeave">
<div class="ContextMenuItemSeperator">
<span class="ContextMenuItemSeperatorText"> ---- Element benutzen ----</span>
</div>
<div class="ContextMenuItem image" t-on-click="_onSetBtnImageClick">
<span class="ContextMenuItem_text">als Buttonbild (akt. Kamp.)</span>
</div>
<div class="ContextMenuItem video" t-on-click="_onSetCenterVideoClick">
<span class="ContextMenuItem_text">Als Durchlaufvideo setzen</span>
</div>
<div class="ContextMenuItem video" t-on-click="_onSetClickVideoClick">
<span class="ContextMenuItem_text">Als Klickvideo setzen</span>
</div>
<div class="ContextMenuItemSeperator">
<span class="ContextMenuItemSeperatorText"> ---- Datei aktionen ----</span>
</div>
<div class="ContextMenuItem file" t-on-click="_onMoveToArchivClick">
<span class="ContextMenuItem_text">in Archiv Verschieben</span>
</div>
<div class="ContextMenuItem file" t-on-click="_onUploadClick">
<span class="ContextMenuItem_text">Hochladen</span>
</div>
<div class="ContextMenuItem file" t-on-click="_onDownloadClick">
<span class="ContextMenuItem_text">Herunterladen</span>
</div>
<div class="ContextMenuItem file" t-on-click="_onDeleteClick">
<span class="ContextMenuItem_text">Löschen</span>
</div>
<div class="ContextMenuItemSeperator">
<span class="ContextMenuItemSeperatorText"> ---- Ordneraktionen ----</span>
</div>
<div class="ContextMenuItem file" t-on-click="_onMakeFolderClick">
<span class="ContextMenuItem_text">Ordner Erstellen</span>
</div>
</div>
<div class="ContextMenu ContextFolderMenu hidden" t-on-mouseleave="_onContextMenueMouseLeave">
<div class="ContextMenuItemSeperator">
<span class="ContextMenuItemSeperatorText"> ---- Element benutzen ----</span>
</div>
<div class="ContextMenuItem image" t-on-click="_onSetCloudClick">
<span class="ContextMenuItem_text">als Cloudlink setzen</span><br/>
<span class="ContextCloudLinkMenuItem_text"></span>
</div>
<div class="ContextMenuItemSeperator">
<span class="ContextMenuItemSeperatorText"> ---- Dateiaktionen ----</span>
</div>
<div class="ContextMenuItem file" t-on-click="_onUploadClick">
<span class="ContextMenuItem_text">Hochladen</span>
</div>
<div class="ContextMenuItem file" t-on-click="_onDownloadClick">
<span class="ContextMenuItem_text">Herunterladen</span>
</div>
<div class="ContextMenuItem file" t-on-click="_onDeleteClick">
<span class="ContextMenuItem_text">Löschen</span>
</div>
<div class="ContextMenuItemSeperator">
<span class="ContextMenuItemSeperatorText"> ---- Ordneraktionen ----</span>
</div>
<div class="ContextMenuItem file" t-on-click="_onMakeFolderClick">
<span class="ContextMenuItem_text">Ordner Erstellen</span>
</div>
</div>
<div class="FieldSelectMenu hidden" t-on-mouseleave="_onContextMenueMouseLeave">
<div class="FieldSelectSeperator">
<span class="FieldSelectSeperatorText"> ---- Mehrere Felder !----</span>
</div>
<div class="FieldSelectMenuItem" t-on-click="_onSetBtnImageClickField">
<span class="FieldSelectMenuItem_text item0">Allen Feldern zuweisen</span>
</div>
<div class="FieldSelectMenuItem hidden" t-on-click="_onSetBtnImageClickField">
<span class="FieldSelectMenuItem_text item1"></span>
</div>
<div class="FieldSelectMenuItem hidden" t-on-click="_onSetBtnImageClickField">
<span class="FieldSelectMenuItem_text item2"></span>
</div>
<div class="FieldSelectMenuItem hidden" t-on-click="_onSetBtnImageClickField">
<span class="FieldSelectMenuItem_text item3"></span>
</div>
</div>
<div class="ImageShowContainerBlur hidden">
<div class="ImageShowContainer_shadow">
</div>
<div class="ImageShowContainer_Header">
<div>
<span class="ImageShowContainer_Header_text">Datei Ansicht</span>
</div>
<div class="ImageShowClose" t-on-click="_onCloseclick">X</div>
</div>
<div class="ImageShowContainer" t-on-click="_onImageClick" id="FileExplorerImage">
<img t-att-src="imagepath" class="ImageShow"/>
</div>
</div>
</div>
</t>
</templates>

View File

@ -0,0 +1,7 @@
<templates>
<t t-name="cloudFolderViewerShort" owl="1">
<div class="CloudfileBrowser">
<input class="CloudfileBrowserShort_Input" style="width:80%" type="text" t-on-change="_onSelectDateField" t-ref="inputpath"/>
</div>
</t>
</templates>

View File

@ -4,7 +4,9 @@
<t t-name="dss.screenview" owl="1">
<Layout display="props.display" className="'h-100 overflow-auto'">
<t t-component="props.Renderer" records="model.records" propsYouWant="'Hello world'"/>
<p>Test</p>
</Layout>
</t>
<div class="" t-attf-style="height:100px;width:100%">
<p>Scrollraum</p>
</div>
</t>
</templates>

View File

@ -2,8 +2,25 @@
<templates xml:space="preserve">
<t t-name="dss.screenviewrenderer" owl="1">
<field name="screenname"/>
<span class="meincanvas"/>
<div class="screenview_main" t-attf-style="height: {{props.screenheight}}px;width: {{props.screenwidth}}px">
<t t-set="index" t-value="0"/>
<t t-foreach="props.records" t-as="record" t-key="record.key">
<t t-set="ele_pos_x" t-value="record.werbe_feld_selected_btn_pos_x + 20"/>
<t t-set="ele_pos_y" t-value="record.werbe_feld_selected_btn_pos_y + 20"/>
<t t-set="ele_pos_w" t-value="record.werbe_feld_selected_btn_pos_w"/>
<t t-set="ele_pos_h" t-value="record.werbe_feld_selected_btn_pos_h"/>
<div class="clickcontainer tooltip-container screenview_field" t-attf-style="left: {{ele_pos_x}}px;top: {{ele_pos_y}}px;width: {{ele_pos_w}}px;height: {{ele_pos_h}}px;" t-attf-data-uuid="{{record.uuid}}" t-attf-data-id="{{record.id}}" t-on-click="handleClick">
<img t-if="record.werbe_feld_selected_btn_img" class="clickcontainer _alert_onclick screenview_img" t-attf-src="data:image/*;base64,{{record.werbe_feld_selected_btn_img}}" t-attf-style="width: {{ele_pos_w}}px;height: {{ele_pos_h}}px;" t-attf-data-uuid="{{record.uuid}}" t-attf-data-id="{{record.id}}"/>
<span class="clickcontainer tooltip" t-attf-data-uuid="{{record.uuid}}" t-attf-data-id="{{record.contractid}}">
<div class="clickcontainer tooltiptext" t-attf-data-id="{{record.id}}"><t t-esc="record.shortwerbe_feld_selected"/></div>
<div class="clickcontainer tooltiptext" t-attf-data-id="{{record.id}}"><t t-esc="record.client_short_company"/></div>
<div class="clickcontainer tooltiptext" t-attf-data-id="{{record.id}}"><t t-esc="record.client_short_vorname + ' ' + record.client_short_name"/></div>
<div class="clickcontainer tooltiptext" t-attf-data-id="{{record.id}}"><t t-esc="record.client_short_strasse"/></div>
<div class="clickcontainer tooltiptext" t-attf-data-id="{{record.id}}"><t t-esc="record.client_short_plz + ' ' + record.client_short_ort"/></div>
</span>
<div>
</t>
</div>
</t>
</templates>

View File

@ -1,18 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<templates xml:space="preserve">
<t t-inherit="web.ListView.Buttons" t-name="button_config.ListView.Buttons">
<xpath expr="//*[@class='btn btn-secondary fa fa-download o_list_export_xlsx']" position="before">
<button type="button" class="btn btn-secondary fa fa-save" id="history_btn" t-on-click="SaveButtonClicked" t-att-data-model-name="props.modelName" data-tooltip="Ansichteinstellungen speichern" />
<button type="button" class="btn btn-secondary fa fa-mail-reply" id="history_btn" t-on-click="ResetButtonClicked" t-att-data-model-name="props.modelName" data-tooltip="Ansichteinstellungen zurücksetzen" />
<xpath expr="//*[@class='o_list_buttons d-flex']" position="after">
<button type="button" class="btn btn-primary fa fa-plus" name="newwizzard" title="NEU Wizzard" id="newwizzard" t-on-click="newwizzard" t-att-data-model-name="props.modelName" data-tooltip="Neues Eintrag mit Unterstützung anlegen" />
</xpath>
</t>
<t t-inherit="web.KanbanView.Buttons" t-name="button_config.KanbanView.Buttons">
<xpath expr="//*[@class='btn btn-primary o-kanban-button-new']" position="after">
<button type="button" class="btn btn-secondary fa fa-save" id="history_btn" t-on-click="SaveButtonClicked" t-att-data-model-name="props.modelName" data-tooltip="Ansichteinstellungen speichern" />
<button type="button" class="btn btn-secondary fa fa-mail-reply" id="history_btn" t-on-click="ResetButtonClicked" t-att-data-model-name="props.modelName" data-tooltip="Ansichteinstellungen zurücksetzen" />
<button name="Onlinestatus" title="OnlineStatus" type="button" class="btn btn-primary o_open_tasks" id="history_btn" t-on-click="Getonlinestate" t-att-data-model-name="props.modelName" data-tooltip="Status abfragen" />
<button name="Onlinestatus" title="OnlineStatus" type="button" class="btn btn-primary o_open_tasks" id="method" t-on-click="Getmethod" t-att-data-model-name="props.modelName" data-tooltip="Status abfragen" />
<xpath expr="//*[@class='o_cp_buttons d-flex align-items-baseline']" position="after">
<button type="button" class="btn btn-primary fa fa-plus" name="newwizzard" title="NEU Wizzard" id="newwizzard" t-on-click="newwizzard" t-att-data-model-name="props.modelName" data-tooltip="Neuen Eintrag mit Unterstützung anlegen" />
</xpath>
</t>

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<templates xml:space="preserve">
<t t-inherit="web.ListRenderer" t-name="dss.ListRenderer_addon">
<xpath expr="//*[@class='form-check-label']" position="after">
<button type="button" class="btn btn-secondary fa fa-save" id="history_btn" t-on-click="SaveButtonClicked" t-att-data-model-name="props.modelName" />
</xpath>
</t>
</templates>

11
temp/list_renderer.xml Executable file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<templates xml:space="preserve">
<t t-inherit="web.ListRenderer" t-name="dss.ListRenderer_addon">
<xpath expr="//*[@class='o_list_buttons d-flex']" position="after">
<button type="button" class="btn btn-primary fa fa-plus" name="newwizzard" title="NEU Wizzard" id="newwizzard" t-on-click="newwizzard" t-att-data-model-name="props.modelName" data-tooltip="Neues Projekt mit Unterstützung anlegen" />
</xpath>
<xpath expr="//*[@class='o_cp_buttons d-flex align-items-baseline']" position="after">
<button type="button" class="btn btn-primary fa fa-plus" name="newwizzard" title="NEU Wizzard" id="newwizzard" t-on-click="newwizzard" t-att-data-model-name="props.modelName" data-tooltip="Neues Projekt mit Unterstützung anlegen" />
</xpath>
</t>
</templates>

0
temp/temp.temp Executable file
View File

234
temp/temp_in.temp Executable file
View File

@ -0,0 +1,234 @@
#!version:1.0.0.1
### This file is the exported MAC-all.cfg.
### For security, the following parameters with password haven't been display in this file.
###account.1.password =
account.1.auth_name = KAJIPJJH11
account.1.cid_source = 2
account.1.codec.pcmu.enable = 0
account.1.codec.pcmu.priority = 9
account.1.codec.g726_32.priority = 9
account.1.codec.g726_40.priority = 9
account.1.codec.12.payload_type = GSM
account.1.codec.12.priority = 9
account.1.codec.12.rtpmap = 3
account.1.codec.pcma.priority = 0
account.1.codec.g723_53.priority = 9
account.1.codec.g723_63.priority = 9
account.1.codec.g729.enable = 0
account.1.codec.g729.priority = 9
account.1.codec.g722.enable = 0
account.1.codec.g722.priority = 9
account.1.codec.ilbc.payload_type = iLBC
account.1.codec.ilbc.priority = 9
account.1.codec.g726_16.priority = 9
account.1.codec.g726_24.priority = 9
account.1.direct_pickup_code = *3
account.1.display_name = KAJIPJJH11
account.1.enable = 1
account.1.group_pickup_code = *3
account.1.label = 122 Technik Intern
account.1.nat.udp_update_enable = 0
account.1.nat.udp_update_time = 45
account.1.outbound_proxy.1.address = 109.68.97.123
account.1.outbound_proxy.1.port = 6050
account.1.outbound_proxy_enable = 1
account.1.reg_fail_retry_interval = 75
account.1.register_mac = 1
account.1.ringtone.ring_type = Ring1.wav
account.1.sip_server.1.address = 109.68.97.123
account.1.sip_server.1.expires = 120
account.1.sip_server.1.port = 6050
account.1.subscribe_mwi = 1
account.1.subscribe_mwi_to_vm = 1
account.1.unregister_on_reboot = 1
account.1.user_name = KAJIPJJH11
###account.2.hoteling.password =
account.2.password = P?KPM6U5pAfZ5td2jNqf
account.2.auth_name = 900
account.2.cid_source = 2
account.2.cid_source_ppi = 1
account.2.codec.pcmu.priority = 1
account.2.codec.12.payload_type = GSM
account.2.codec.12.rtpmap = 3
account.2.codec.opus.payload_type = opus
account.2.codec.opus.priority = 13
account.2.codec.pcma.priority = 2
account.2.codec.g729.priority = 3
account.2.codec.g722.priority = 4
account.2.codec.ilbc.payload_type = iLBC
account.2.display_name = Technik-JS
account.2.enable = 1
account.2.hoteling.user_id = 0
account.2.label = 900
account.2.nat.rport = 1
account.2.picture_info_enable = 1
account.2.reason_code_name.1 = 0
account.2.sip_server.1.address = tel.logumedia.de
account.2.sip_server.1.expires = 120
account.2.sip_server.1.transport_type = 1
account.2.sip_server.2.expires = 120
account.2.sip_server.2.transport_type = 1
account.2.subscribe_mwi_to_vm = 1
account.2.user_name = 900
account.2.unregister_on_reboot = 0
default_input_method.xml_browser_input_screen = abc
directory.edit_default_input_method = abc
directory.search_default_input_method = abc
features.acoustic_shield.mode = 0
features.alert_info_tone = 1
features.blf_active_backlight.enable = 0
features.call_completion.call_back.enable = 0
features.call_log_show_num = 2
features.call_out_history_by_off_hook.enable = 1
features.caller_name_type_on_dialing = 1
features.conference.with_previous_call.enable = 1
features.config_dsskey_length = 1
features.custom_version_info = 2025-05-05 12:23
features.direct_ip_call_enable = 0
features.dnd.large_icon.enable = 1
features.dtmf.hide = 1
features.dtmf.hide_delay = 1
features.forward_call_popup.enable = 0
features.headset_prior = 1
features.http_or_https.connect.keep_alive = 1
features.intercom.allow = 0
features.intercom.barge = 1
features.key_as_send = 0
features.key_tone = 0
features.missed_call_popup.enable = 0
features.noise_filtering_rev.enable = 0
features.pickup.direct_pickup_code = *3
features.pickup.direct_pickup_enable = 1
features.pickup.group_pickup_code = *3
features.pickup.group_pickup_enable = 1
features.power_saving.power_led_flash.off_time = 1000
features.power_saving.power_led_flash.on_time = 0
features.relog_offtime = 30
features.save_init_num_to_history.enable = 0
features.send_key_tone = 0
features.text_message.enable = 0
features.text_message_popup.enable = 0
features.voice_mail_popup.enable = 0
features.xml_browser.loading_tip.delay = 0
lang.gui = German
ldap.incoming_call_special_search.enable = 1
ldap.ldap_sort = 1
linekey.1.type = 0
linekey.10.line = 1
linekey.10.type = 0
linekey.11.line = 1
linekey.11.type = 0
linekey.12.line = 1
linekey.12.type = 0
linekey.2.line = 1
linekey.2.type = 0
linekey.3.line = 1
linekey.3.type = 0
linekey.4.line = 1
linekey.4.type = 0
linekey.5.line = 1
linekey.5.type = 0
linekey.6.line = 1
linekey.6.type = 0
linekey.7.line = 1
linekey.7.type = 0
linekey.8.line = 1
linekey.8.type = 0
linekey.9.line = 1
linekey.9.type = 0
local_time.date_format = 5
local_time.end_time = 10/26/3
local_time.interval = 1800
local_time.ntp_server1 = 162.159.200.123
local_time.ntp_server2 = de.pool.ntp.org
local_time.start_time = 3/30/2
local_time.summer_time = 1
local_time.time_zone = +1
local_time.time_zone_name = Germany(Berlin)
phone_setting.active_backlight_level = 10
phone_setting.autop_led_flash_enable = 0
phone_setting.backgrounds = Config:Default.jpg
phone_setting.backgrounds_with_dsskey_unfold = Default.png
phone_setting.contact_photo_display.enable = 2
phone_setting.dsskey_label.display_method = 1
phone_setting.emergency.number = 0110,0112,0911,0999,911,999
phone_setting.hold_and_held_power_led_flash_enable = 1
phone_setting.inactive_backlight_level = 1
phone_setting.inter_digit_time = 14
phone_setting.is_deal180 = 0
phone_setting.page_tip = 1
phone_setting.ring_type = Ring1.wav
phone_setting.show_code403 = 1
phone_setting.talk_and_dial_power_led_enable = 1
phone_setting.warnings_display.mode = 0
programablekey.1.history_type = 0
programablekey.1.label = Ruflisten
programablekey.1.line = 1
programablekey.14.type = 27
programablekey.14.value = https://ds.cloud-cfg.com/yealink/805EC0992847/af17250469f15697b6f0afd1aaa7e304a1801ab7cca6f77effd8e1ae41edef17/callprofiles
programablekey.2.label = DND
programablekey.2.type = 5
programablekey.3.label = Menü
programablekey.3.type = 27
programablekey.3.value = https://ds.cloud-cfg.com/yealink/805EC0992847/af17250469f15697b6f0afd1aaa7e304a1801ab7cca6f77effd8e1ae41edef17/menu
programablekey.4.label = Telefonbuch
programablekey.4.type = 27
programablekey.4.value = https://ds.cloud-cfg.com/yealink/805EC0992847/af17250469f15697b6f0afd1aaa7e304a1801ab7cca6f77effd8e1ae41edef17/phonebook
programablekey.5.history_type = 0
programablekey.5.line = 1
programablekey.6.type = 30
programablekey.7.type = 27
programablekey.7.value = https://ds.cloud-cfg.com/yealink/805EC0992847/af17250469f15697b6f0afd1aaa7e304a1801ab7cca6f77effd8e1ae41edef17/menu
programablekey.8.type = 27
programablekey.8.value = https://ds.cloud-cfg.com/yealink/805EC0992847/af17250469f15697b6f0afd1aaa7e304a1801ab7cca6f77effd8e1ae41edef17/phonebook
push_xml.phonebook_in_talking.url = https://ds.cloud-cfg.com/yealink/805EC0992847/af17250469f15697b6f0afd1aaa7e304a1801ab7cca6f77effd8e1ae41edef17/phonebook
sip.disp_incall_to_info = 1
sip.escape_displayname.enable = 1
sip.listen_port = 6050
sip.trust_ctrl = 1
sip.use_23_as_pound = 0
transfer.dsskey_deal_type = 1
voice.cng = 0
voice.handset.tia4965.enable = 0
voice.headset.tia4965.enable = 0
voice.tone.country = Germany
voice_mail.number.1 = voicemail
### Static Configuration ###
static.auto_provision.connect.keep_alive = 0
static.auto_provision.custom.protect = 0
static.auto_provision.dhcp_option.enable = 0
static.auto_provision.pnp_enable = 0
static.auto_provision.repeat.enable = 1
static.auto_provision.repeat.minutes = 329
static.auto_provision.server.url =
static.auto_provision.weekly.begin_time = 01:00
static.auto_provision.weekly.end_time = 03:00
static.local_log.level = 0
static.network.802_1x.proxy_eap_logoff.enable = 1
static.network.attempt_expired_time = 20
static.network.pc_port.mode = 1
static.network.port.max_rtpport = 15000
static.network.port.min_rtpport = 14000
static.network.qos.signaltos = 24
static.network.wifi.internet_port.type = 0
static.network.wifi.ip_address_mode = 0
static.network.wifi.ipv6_icmp_v6.enable = 1
static.network.wifi.ipv6_internet_port.type = 0
static.network.wifi.ipv6_prefix = 64
static.network.wifi.ipv6_static_dns_enable = 0
static.network.wifi.preference = 0
static.network.wifi.static_dns_enable = 0
static.security.trust_certificates = 0
static.security.user_name.admin = operator
static.security.user_name.user = 122
static.security.user_name.var = admin
static.security.var_enable = 1
static.syslog.level = 0
static.syslog.log_level = 0
static.syslog.prepend_mac_address.enable = 1
static.wui.default_https_enable = 0
static.zero_touch.wait_time = 3

BIN
temp/temp_set.temp Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 MiB

View File

@ -38,8 +38,6 @@
</field>
<div colspan="2" style="font-color:#E00000;"><p>Die Struktur kann erst nach Speichern der Grunddaten eingerichtet werden !</p></div>
<field name="mediastructure" attrs="{'invisible': [('issaved','!=',True)]}" />
<field name="color_used" widget="color"/>
<field name="color_unused" widget="color"/>
<field name="isblocked" widget="boolean_toggle"/>
<field name="is_btn"/>
</group>
@ -125,7 +123,46 @@
</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"/>
@ -138,8 +175,10 @@
<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="user_create" string="Erstellt durch"/>
<field name="color_used" />
<field name="color_unused" />
<field name="auto_feldname" widget="cloudFolderViewer"/>
<field name="display"/>
</group>
</page>
@ -179,7 +218,7 @@
<field name="code">action = records.check_contract_multi_Values()</field>
</record>
<record id="dss_advertisefields_fill_form" model="ir.ui.view">
<!-- <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">
@ -322,7 +361,7 @@
</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>

View File

@ -7,6 +7,7 @@
<field name="priority" eval="16"/>
<field name="arch" type="xml">
<tree string="Werbefeld Templates" multi_edit="1" edit="1">
<field name="id"/>
<field name="templatefeldname"/>
<field name="displaytemplate"/>
<field name="feldname"/>

View File

@ -128,7 +128,7 @@
<field name="model">dss.contracts</field>
<field name="priority" eval="17"/>
<field name="arch" type="xml">
<tree string="Vertragsuebersicht" editable="bottom" multi_edit="1" edit="1" default_order="client_id" >
<tree string="Vertragsuebersicht" editable="bottom" multi_edit="1" edit="1" default_order="client_id">
<field name="contract_auto_name" optional="show" readonly="1"/>
<field name="contract_name" optional="hide"/>
<field name="project_id" optional="hide"/>
@ -179,6 +179,18 @@
</field>
</record>
<record id="dss_project_contracts_kanban_inherit_js_class" model="ir.ui.view">
<field name="name">dss_project_contracts_kanban_inherit</field>
<field name="model">dss.contracts</field>
<field name="inherit_id" ref="DigitalSignage.dss_main_contracts_kanban"/>
<field name="arch" type="xml">
<xpath expr="//kanban" position="attributes">
<attribute name="js_class">button_in_kanban</attribute>
</xpath>
</field>
</record>
<record id="action_dss_project_new_contract_kanban" model="ir.actions.act_window">
<field name="name">DigitalSignage Projekt Vertraege</field>
<field name="type">ir.actions.act_window</field>
@ -207,6 +219,15 @@
<label for="client_id" string="Kundennummer (2 stellig)"/><field name="client_id" placeholder="XX (2 Stellen)"/>
<label for="contract_name" string="Eigene Vertragskennung"/><field name="contract_name" placeholder="Kurzbezeichnung"/>
</h3>
<group>
<field name="contract_state" string="Vertragsstatus" help="ACHTUNG !!! Automatische Mail wird versendet !"/>
</group>
<group>
<field name="project"/>
</group>
<group>
<field name="werbe_feld_selected" string="Werbefeld" widget="many2many_tags" option="{'not_delete': True}" domain="[('project','=',project),'|',('contract','=',False),('isblocked','=',False)]" context="{'tree_view_ref' : 'DigitalSignage.dss_advertisefields_view_form'}" options="{'color_field': 'color_used'}"/>
</group>
</div>
</div>
<div class="row mt16 o_settings_container"/>
@ -231,12 +252,20 @@
</field>
</record>
<record id="action_open_create_contract_new_edit" model="ir.actions.act_window">
<field name="name">Vertrag erstellen</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="context">{"default_allow_billable": 1}</field>
</record>
<record id="action_open_create_contract" model="ir.actions.act_window">
<field name="name">Vertrag erstellen</field>
<field name="res_model">dss.contracts</field>
<field name="view_mode">form</field>
<field name="view_id" ref="dss_project_new_contract_kanbanform_footer"/>
<field name="target">new</field>
<field name="view_id" ref="dss_project_new_contract_kanbanform_footer"/>
<field name="context">{"default_allow_billable": 1}</field>
</record>
@ -308,43 +337,37 @@
<div class="row">
<div class="col-7">
<div class="row">
<div class="col-3">
<group>
<field name="project_id" string="Projekt ID"/>
</group>
</div>
<div class="col-7">
</div>
<div class="row">
<group>
<field name="project" string="Projekt"/>
</group>
</div>
</div>
<div class="row">
<div class="col-3">
<group>
<field name="client_id" string="Kunden ID"/>
</group>
</div>
</div>
<hr></hr>
<div class="row">
<div class="col-20">
<div class="row">
<div class="col-4">
<group>
<field name="contract_auto_id" string="Kundennummer"/>
</group>
</div>
<div class="col-8">
</div>
<div class="row">
<group>
<field name="contract_name" string="Vertragskennung"/>
</group>
</div>
</div>
<div class="row">
<div class="col-8">
<group>
<field name="werbe_feld_selected" string="Werbefeld" widget="many2many_tags" option="{'not_delete': True}" domain="[('project','=',project),'|',('contract','=',False),('isblocked','=',False)]"/>
<field name="werbe_feld_selected" string="Werbefeld" widget="many2many_tags" option="{'not_delete': True}" domain="[('project','=',project),'|',('contract','=',False),('isblocked','=',False)]" context="{'tree_view_ref' : 'DigitalSignage.dss_advertisefields_view_form'}" options="{'color_field': 'color_used'}"/>
</group>
<hr></hr>
<group>
@ -372,6 +395,11 @@
<div class="row">
<group>
<field name="contract_state" string="Vertragsstatus" help="ACHTUNG !!! Automatische Mail wird versendet !" />
</group>
</div>
<div class="row">
<group>
<field name="ads_last_adtype" string="Kampagnenstatus" help="ACHTUNG !!! Automatische wird evtl. Mail versendet !" readonly="1"/>
</group>
</div>
<div class="row">
@ -624,7 +652,7 @@
</group>
</div>
<div class="col-2">
<button icon="DigitalSignage/static/src/img/dsscalc.png" title="calc_1" name="pyaction_dss_contract_calc_runtime" type="object" class="dss-smallbutton" data-hotkey="c" help="Berechnet das Laufzeitende des Vertrages und trägt diesen in einen Kalender ein !"/>
<button icon="DigitalSignage/static/src/img/dsscalc.png" title="calc_1" name="pyaction_dss_contract_calc_runtime" type="object" class="dss-smallbutton" data-hotkey="c" help="Berechnet das Laufzeitende des Vertrages und trägt diesen in einen Kalender ein !" attrs="{'invisible':[('no_cancel_calc','=',True)]}"/>
<button icon="DigitalSignage/static/src/img/calendar.png" title="calendar_1" name="pyaction_dss_contract_addcalendar_runtime" type="object" class="dss-smallbutton" data-hotkey="d" help="Trägt den Ablauftag in einen Kalender ein !" attrs="{'invisible': ['|',('runtime_finish','=',False),('runtime_calendar_event','!=',False)]}"/>
<button icon="DigitalSignage/static/src/img/calendar_rf.png" title="calendar_2" name="pyaction_dss_contract_addcalendar_rf_runtime" type="object" class="dss-smallbutton" data-hotkey="d" help="Trägt den Ablauftag in einen Kalender ein !" attrs="{'invisible': [('runtime_calendar_event','=',False)]}"/>
</div>
@ -639,7 +667,8 @@
<div class="col-2">
<br></br>
<br></br>
<button icon="DigitalSignage/static/src/img/dsscalc.png" title="calc_2" name="pyaction_dss_contract_calc_runtime_end" type="object" class="dss-smallbutton" data-hotkey="c" help="Berechnet das Laufzeitende des Vertrages und trägt diesen in einen Kalender ein !" attrs="{'invisible':[('contract_cancel_mon','=',0)]}"/>
<button icon="DigitalSignage/static/src/img/dsscalc.png" title="calc_2" name="pyaction_dss_contract_calc_runtime_end" type="object" class="dss-smallbutton" data-hotkey="c" help="Berechnet das Laufzeitende des Vertrages und trägt diesen in einen Kalender ein !" attrs="{'invisible':['|',('contract_cancel_mon','=',0),('no_cancel_calc','=',True)]}"/>
<field string="x" help="verbietet die automatische Berechnung" name="no_cancel_calc" widget="boolean_toggle"/>
</div>
</div>
<div class="row" >
@ -654,6 +683,18 @@
</group>
</div>
</div>
<div class="row" >
<div class="col-4">
<group>
<field name="contract_iscanceled" widget="boolean_toggle"/>
</group>
</div>
<div class="col-4">
<group>
<field name="contract_iscanceled_date"/>
</group>
</div>
</div>
<div class="row" >
<div class="col-5">
<group string="Abrechnungsmodus">
@ -714,6 +755,7 @@
<field name="tv_reach_PLZ"/>
<field name="ads_radius_PLZ"/>
<field name="ads_count_perYear"/>
<field name="ads_count_perYear2"/>
<field name="ads_topics"/>
</group>
</page>
@ -824,10 +866,12 @@
</page>
<page name="informations" string="Interne Informationen">
<notebook>
<page name="grundsettings" string="Grunddaten">
<page name="cloudsettings" string="Cloud Dateien">
<group>
<field name="cloudlink"/>
<field name="cloudlink" widget="cloudFolderViewer"/>
</group>
</page>
<page name="grundsettings" string="Grunddaten">
<group>
<field name="contract_id" string="Kunden/Vert.nummer" readonly="1"/>
<field name="id" string="Vertrags Interne Id" readonly="1"/>
@ -960,7 +1004,8 @@
quick_create_view="dss_contracts_view_form_simplified_footer"
on_create="pyaction_new_contract_kanban"
> -->
<kanban class="o_kanban_mobile oe_background_gray o_emphasize_colors" on_create="quick_create" quick_create_view="DigitalSignage.dss_project_new_contract_kanbanform" action="pyaction_view_contract" type="object" default_group_by="contract_state" default_order="client_id">-->
<kanban class="o_kanban_mobile oe_background_gray o_emphasize_colors" on_create="quick_create" quick_create_view="DigitalSignage.dss_project_new_contract_kanbanform" action="pyaction_view_contract" type="object" default_group_by="contract_state" default_order="client_id desc">
<!-- <kanban class="o_kanban_mobile oe_background_gray o_emphasize_colors" action="pyaction_view_contract" type="object" default_group_by="contract_state" default_order="client_id">-->
<field name="contract_name"/>
<field name="contract_state"/>
<field name="contract_state_color"/>
@ -1161,6 +1206,15 @@
<field name="code">action = records.setFirstKampagne()</field>
</record>
<record id="action_set_alltext" model="ir.actions.server">
<field name="name">Alle Texte erzeugen</field>
<field name="model_id" ref="model_dss_contracts"/>
<field name="binding_model_id" ref="model_dss_contracts"/>
<field name="binding_view_types">tree</field>
<field name="state">code</field>
<field name="code">action = records.buildallText()</field>
</record>
<record id="action_set_SaveViewState" model="ir.actions.server">
<field name="name">Zum Cloud-Ordner springen</field>
<field name="model_id" ref="model_dss_contracts"/>
@ -1170,6 +1224,15 @@
<field name="code">action = records.jumpcloud()</field>
</record>
<record id="action_test_Textoutput" model="ir.actions.server">
<field name="name">Zusammenfassung anzeigen</field>
<field name="model_id" ref="model_dss_contracts"/>
<field name="binding_model_id" ref="model_dss_contracts"/>
<field name="binding_view_types">form</field>
<field name="state">code</field>
<field name="code">action = records.buildText()</field>
</record>
<data noupdate="1">
<record id="dss_cron_scheduler_recurring_action_2" model="ir.cron">
<field name="name">Contract Trigger Check</field>

View File

@ -32,7 +32,7 @@
<field name="model">dss.projects</field>
<field name="arch" type="xml">
<form>
<field name="grundsystem_showonlinestate_type"/>
<field name="grundsystem_showonlinestate_type"/>
<sheet>
<group>
<field name="invisible" widget="boolean_toggle"/>
@ -44,7 +44,13 @@
<field name="name"/>
<field name="standort_inout"/>
<field name="grundsystemname" string="Kategorie"/>
<field name="grundsystemicon" widget="image" string="intern" class="system_icon_small oe_avatar"/>
<field name="grundsystemicon_different" widget="boolean_toggle"/>
<field name="grundsystemicon_different_image" widget="image" class="system_icon_small oe_avatar"/>
<field name="errichtet_am"/>
<field name="cancel_am_in"/>
<field name="cancel_am_to"/>
<field name="finish_am"/>
<field name="aktstatus_color" widget="color"/>
<field name="btntemplate"/>
</group>
@ -239,7 +245,7 @@
<field name="model">dss.projects</field>
<field name="priority" eval="16"/>
<field name="arch" type="xml">
<kanban class="o_kanban_mobile" action="pyaction_view_contracts" type="object" default_group_by="grundsystemname" default_order="projectid">
<kanban class="o_kanban_mobile" action="pyaction_view_contracts" type="object" default_group_by="grundsystemname" default_order="projectid" create="false">
<field name="projektname"/>
<field name="aktstatus_color"/>
<field name="grundsystem_showonlinestate"/>
@ -249,6 +255,7 @@
<field name="playername_1"/>
<field name="playername_2"/>
<field name="playername_3"/>
<field name="grundsystemicon_different"/>
<templates>
<t t-name="kanban-box">
<t t-set="colonr" t-value="aktstatus_color"/>
@ -257,8 +264,9 @@
<div t-attf-class="#{colo} oe_kanban_global_click o_has_icon oe_kanban_content oe_kanban_card">
<div t-attf-class="oe_kanban_content oe_kanban_global_click o_kanban_get_form">
<div class="row" style="--gutter-x:10px;">
<div class="col-2" style="padding-left: 1px">
<field name="grundsystemicon" widget="image" string="intern" class="system_icon_small oe_avatar"/>
<div class="col-2" style="padding-left: 1px">
<field name="grundsystemicon" widget="image" string="intern" class="system_icon_small oe_avatar" attrs="{'invisible': [('grundsystemicon_different', '=', True)]}"/>
<field name="grundsystemicon_different_image" widget="image" string="intern" class="system_icon_small oe_avatar" attrs="{'invisible': [('grundsystemicon_different', '!=', True)]}"/>
<!-- <img t-attf-src="/DigitalSignage/static/images/{{grundsystemnameicon5050}}.jpg"></img>-->
</div>
<div class="col-10">
@ -361,7 +369,7 @@
<field name="model">dss.projects</field>
<field name="priority" eval="16"/>
<field name="arch" type="xml">
<tree string="Projektuebersicht" editable="bottom" multi_edit="1" edit="1" default_order="projectid">
<tree string="Projektuebersicht" create="false" editable="bottom" multi_edit="1" edit="1" default_order="projectid">
<!-- <field name="grundsystemicon5050" widget="image"/> -->
<field name="projectid"/>
<field name="projektname"/>
@ -388,7 +396,7 @@
</search>
</field>
</record>
<record id="action_dss_view" model="ir.actions.act_window">
<field name="name">DigitalSignage Projekte</field>
<field name="type">ir.actions.act_window</field>
@ -426,4 +434,83 @@
<field name="code">action = records.jumpcloud()</field>
</record>
<record id="dss_project_new_wizard_form" model="ir.ui.view">
<field name="name">dss.projects.new.wizard.form</field>
<field name="model">dss.projects.new.wizard</field>
<field name="mode">primary</field>
<field name="arch" type="xml">
<form>
<sheet>
<group name="configurebase" attrs="{'readonly': [('state', '!=', 'start')]}">
<h1>
<field name="projektname" class="oe_inline" placeholder="Projektname"/>
</h1>
</group>
<group name="configure" attrs="{'readonly': [('state', '!=', 'start')]}">
<group>
<field name="name" class="oe_inline"/>
<field name="aktstatus" class="oe_inline"/>
<field name="projectid"/>
<field name="grundsystemname"/>
</group>
</group>
<hr></hr>
<group name="configure3" attrs="{'readonly': [('state', '!=', 'configure')]}">
<span class="o_field_label">Bitte beschreiben Sie das Projekt für den Kunden in einer kurzen Form</span>
<group>
<field name="kundenbeschreibung"/>
</group>
</group>
<hr></hr>
<group name="configureOrt" attrs="{'readonly': [('state', '!=', 'custom')]}">
<span class="o_field_label">Bitte geben Sie den Standort des Projektes an. Bei Displays und Geräten ist eine Beschreibung des Standortes von Vorteil.</span>
<group>
<field name="standort"/>
<field name="standort_strasse"/>
<field name="standort_plz"/>
<field name="standort_ort"/>
<field name="standort_bundesland"/>
<field name="standort_land"/>
</group>
</group>
<hr></hr>
<group name="configure3T" attrs="{'readonly': [('state', '!=', 'configure')]}">
<span class="col-5 o_field_label">Trigger sollten automatisch aktiviert sein, um automatische Vorgänge zu ermöglichen. Hier können dise aber deaktiviert werden.</span>
<group>
<field name="run_uni_trigger"/>
</group>
</group>
<hr></hr>
<group name="configure2" attrs="{'readonly': [('state', '!=', 'custom')]}">
<span class="o_field_label">Es werden die Ordner in der Cloud so angelegt wie der Musterordner im Grundsystem hinterlegt wurde. Sollten Abweichungen gewünscht werden, kann dies hier eingestellt werden.</span>
<group>
<field name="cloudgenerate" widget="boolean_toggle"/>
<field name="isdifferendcouldstructure" widget="boolean_toggle" attrs="{'invisible': [('cloudgenerate', '!=', True)]}"/>
<field name="differendcouldstructurefolder" attrs="{'invisible': [('isdifferendcouldstructure', '!=', True)]}"/>
</group>
</group>
<hr></hr>
<group name="configurev" attrs="{'readonly': [('state', '!=', 'custom')]}">
<group>
<field name="vertragsschreiber"/>
<field name="standortpartner"/>
<field name="project_grafiker"/>
<field name="vertriebspartner" widget="many2many"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
<record id="new_wizard_action" model="ir.actions.act_window">
<field name="name">Neues Projekt einrichten</field>
<field name="res_model">dss.projects.new.wizard</field>
<field name="view_mode">form</field>
<field name="view_id" ref="dss_project_new_wizard_form"/>
<field name="target">new</field>
</record>
</odoo>

View File

@ -41,12 +41,22 @@
<field name="icon_5050" widget="image"/>
<field name="order" widget="Reihenfolge"/>
</group>
<group name="mailtemplates" string="Standard EMail">
<field name="email_template_welcome"/>
<field name="email_template_zuarbeit"/>
<field name="email_template_abzug"/>
<field name="email_template_start"/>
</group>
<notebook>
<page name="mailsettings" string="Mailvorlagen/Settings">
<group name="mailtemplates" string="Standard EMail">
<field name="email_template_welcome"/>
<field name="email_template_zuarbeit"/>
<field name="email_template_abzug"/>
<field name="email_template_start"/>
</group>
</page>
<page name="cloudsettings" string="Cloudvorlagen">
<group name="mailtemplates" string="Cloudpfad - Muster">
<field name="default_cloud_structure_project" widget="cloudFolderViewer"/>
<field name="default_cloud_structure_contract" widget="cloudFolderViewerShort"/>
</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"/>

View File

@ -128,6 +128,7 @@
<field name="runtime_t" string="Laufzeit Tage" attrs="{'invisible': [('runtimesystem','!=','T')]}"/>
<field name="runtime_events" string="Spieltage" attrs="{'invisible': [('runtimesystem','!=','E')]}"/>
<field name="runtime_divers" string="Laufzeit Spezial" attrs="{'invisible': [('runtimesystem','!=','S')]}"/>
<field name="paymentinterval" string="Abrechnungsinterval"/>
</group>
<div class="row">
<div class="col-5">
@ -143,13 +144,15 @@
</div>
</div>
<group>
<field name="ads_count_perYear" string="Einblendungen/Jahr"/>
<field name="ads_count_perYear2" string="Einblendungen/Jahr"/>
<field name="contract_auto_extend" string="Automatische Vertragsverlängerung" widget="boolean_toggle"/>
<field name="tv_reach_PLZ" string="Reichweite PLZ"/>
<field name="ads_radius_PLZ" string="Umkreis PLZ in Km"/>
<field name="ads_topics" string="Thema/Affinität" widget="many2many_tags"/>
<field name="contract_date" string="Vertragsdatum"/>
<field name="grafik_zuarbeitBis" string="Grafik Zuarbeit bis"/>
<field name="grafikerstellung" string="Grafikerstellung inkl. Boarding" widget="boolean_toggle"/>
<field name="boarding" string="Boarding" widget="boolean_toggle"/>
<field name="date_start_planed" string="geplantes Startdatum"/>
<field name="date_remove_planed" string="geplantes Enddatum"/>
<field name="remark" string="Bemerkungen"/>