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
Executable
+5
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)
*/
+11 -1
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
##
+1
View File
@@ -4,3 +4,4 @@
from . import main
from . import dss_screendesigner_controller
from . import dss_screenview_controller
from . import dss_nextcloudwidget
BIN
View File
Binary file not shown.
Binary file not shown.
View File
Binary file not shown.
+136
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
+3 -1
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!'}
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
+1 -1
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
+2
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)
+229 -15
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
+9 -1
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:
+147 -9
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
+24 -1
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):
+3 -1
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)
+7 -3
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,
+1
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
+448
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);
+251
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);
@@ -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')
+27 -46
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 };
View File
+101 -17
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;
}
}
+31 -16
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 **/
+32 -98
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
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);
}
})
+21
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", {
+276
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;
}
+34 -1
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;
}
+122
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>
+7
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>
+4 -2
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>
+19 -2
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>
+4 -8
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>
-8
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
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>
Executable
View File
+234
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
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 MiB

+45 -6
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>
@@ -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"/>
+81 -18
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>
+93 -6
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>
+16 -6
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"/>
+4 -1
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"/>