From b67f39496c0d0e8008eac4078f0c71bd0f4b8781 Mon Sep 17 00:00:00 2001 From: "a.schindlbeck" <a.schindlbeck@adito.de> Date: Mon, 10 Sep 2018 11:07:20 +0200 Subject: [PATCH] Calendar Setup --- .../_____SYSTEM_APPLICATION.aod | 18 + .../_____SYSTEM_APPLICATION_NEON.aod | 2 + .../company/iconProcess.js | 0 .../_____SYSTEM_CALENDAR_RIBBON.aod | 14 + .../_____SYSTEM_CALENDAR_RIBBON_NEON.aod | 3 + .../_____SYSTEM_INDEXSEARCH_RIBBON.aod | 14 + .../Appointment_entity/Appointment_entity.aod | 49 +++ entity/Appointment_entity/contentProcess.js | 58 +++ .../entityfields/summary/valueProcess.js | 5 + entity/Appointment_entity/onDelete.js | 17 + entity/Appointment_entity/onInsert.js | 359 +++++++++++++++++ entity/Appointment_entity/onUpdate.js | 368 ++++++++++++++++++ .../Appointment_context.aod | 22 ++ neonContext/Org_context/Org_context.aod | 1 + neonContext/Org_context/iconProcess.js | 0 .../AppointmentEdit_view.aod | 24 ++ .../AppointmentPreview_view.aod | 22 ++ .../_____PREFERENCES_PROJECT.aod | 2 +- .../openCalendarProzess.aod | 6 + process/openCalendarProzess/process.js | 8 + 20 files changed, 991 insertions(+), 1 deletion(-) create mode 100644 application/_____SYSTEM_APPLICATION/_____SYSTEM_APPLICATION.aod create mode 100644 application/_____SYSTEM_APPLICATION_NEON/company/iconProcess.js create mode 100644 application/_____SYSTEM_CALENDAR_RIBBON/_____SYSTEM_CALENDAR_RIBBON.aod create mode 100644 application/_____SYSTEM_INDEXSEARCH_RIBBON/_____SYSTEM_INDEXSEARCH_RIBBON.aod create mode 100644 entity/Appointment_entity/Appointment_entity.aod create mode 100644 entity/Appointment_entity/contentProcess.js create mode 100644 entity/Appointment_entity/entityfields/summary/valueProcess.js create mode 100644 entity/Appointment_entity/onDelete.js create mode 100644 entity/Appointment_entity/onInsert.js create mode 100644 entity/Appointment_entity/onUpdate.js create mode 100644 neonContext/Appointment_context/Appointment_context.aod create mode 100644 neonContext/Org_context/iconProcess.js create mode 100644 neonView/AppointmentEdit_view/AppointmentEdit_view.aod create mode 100644 neonView/AppointmentPreview_view/AppointmentPreview_view.aod create mode 100644 process/openCalendarProzess/openCalendarProzess.aod create mode 100644 process/openCalendarProzess/process.js diff --git a/application/_____SYSTEM_APPLICATION/_____SYSTEM_APPLICATION.aod b/application/_____SYSTEM_APPLICATION/_____SYSTEM_APPLICATION.aod new file mode 100644 index 00000000000..dc4b0517fc5 --- /dev/null +++ b/application/_____SYSTEM_APPLICATION/_____SYSTEM_APPLICATION.aod @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<application xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.8" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/application/1.1.8"> + <name>_____SYSTEM_APPLICATION</name> + <majorModelMode>DISTRIBUTED</majorModelMode> + <entityNode name="_____SYSTEM_COMPANY" kind="200"> + <node name="Group" kind="123" title=""> + <node name="Group2" kind="123" title=""> + <node name="openCalendarProzess" kind="103" /> + <node name="Util_lib" kind="103" /> + <node name="INTERNAL_ADMINISTRATOR" kind="159" /> + </node> + </node> + </entityNode> + <company> + <name>company</name> + <backgroundColor v="0xff83cbd8" /> + </company> +</application> diff --git a/application/_____SYSTEM_APPLICATION_NEON/_____SYSTEM_APPLICATION_NEON.aod b/application/_____SYSTEM_APPLICATION_NEON/_____SYSTEM_APPLICATION_NEON.aod index 27b4cde697b..5a9a2413668 100644 --- a/application/_____SYSTEM_APPLICATION_NEON/_____SYSTEM_APPLICATION_NEON.aod +++ b/application/_____SYSTEM_APPLICATION_NEON/_____SYSTEM_APPLICATION_NEON.aod @@ -7,6 +7,7 @@ <icon>VAADIN:STAR</icon> <node name="Group1" kind="123" title=""> <node name="Vertriebsdashboard" kind="10090" /> + <node name="Calendar_context" kind="10077" /> <node name="Org_context" kind="10077" /> <node name="Pers_context" kind="10077" /> <node name="History_context" kind="10077" /> @@ -16,5 +17,6 @@ </entityNode> <company> <name>company</name> + <iconProcess>%aditoprj%/application/_____SYSTEM_APPLICATION_NEON/company/iconProcess.js</iconProcess> </company> </application> diff --git a/application/_____SYSTEM_APPLICATION_NEON/company/iconProcess.js b/application/_____SYSTEM_APPLICATION_NEON/company/iconProcess.js new file mode 100644 index 00000000000..e69de29bb2d diff --git a/application/_____SYSTEM_CALENDAR_RIBBON/_____SYSTEM_CALENDAR_RIBBON.aod b/application/_____SYSTEM_CALENDAR_RIBBON/_____SYSTEM_CALENDAR_RIBBON.aod new file mode 100644 index 00000000000..59f4edfc613 --- /dev/null +++ b/application/_____SYSTEM_CALENDAR_RIBBON/_____SYSTEM_CALENDAR_RIBBON.aod @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<application xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.8" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/application/1.1.8"> + <name>_____SYSTEM_CALENDAR_RIBBON</name> + <majorModelMode>DISTRIBUTED</majorModelMode> + <entityNode name="_____SYSTEM_COMPANY" kind="200" /> + <calendarRibbon> + <name>calendarRibbon</name> + <ribbonTasks> + <ribbonTask> + <name>TASK_CALENDAR</name> + </ribbonTask> + </ribbonTasks> + </calendarRibbon> +</application> diff --git a/application/_____SYSTEM_CALENDAR_RIBBON_NEON/_____SYSTEM_CALENDAR_RIBBON_NEON.aod b/application/_____SYSTEM_CALENDAR_RIBBON_NEON/_____SYSTEM_CALENDAR_RIBBON_NEON.aod index 216dd1b6553..430c1600fa5 100644 --- a/application/_____SYSTEM_CALENDAR_RIBBON_NEON/_____SYSTEM_CALENDAR_RIBBON_NEON.aod +++ b/application/_____SYSTEM_CALENDAR_RIBBON_NEON/_____SYSTEM_CALENDAR_RIBBON_NEON.aod @@ -5,5 +5,8 @@ <entityNode name="_____SYSTEM_COMPANY" kind="200" /> <neonCalendarRibbon> <name>neonCalendarRibbon</name> + <entity> + <name>entity</name> + </entity> </neonCalendarRibbon> </application> diff --git a/application/_____SYSTEM_INDEXSEARCH_RIBBON/_____SYSTEM_INDEXSEARCH_RIBBON.aod b/application/_____SYSTEM_INDEXSEARCH_RIBBON/_____SYSTEM_INDEXSEARCH_RIBBON.aod new file mode 100644 index 00000000000..6e55b830c5b --- /dev/null +++ b/application/_____SYSTEM_INDEXSEARCH_RIBBON/_____SYSTEM_INDEXSEARCH_RIBBON.aod @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<application xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.8" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/application/1.1.8"> + <name>_____SYSTEM_INDEXSEARCH_RIBBON</name> + <majorModelMode>DISTRIBUTED</majorModelMode> + <entityNode name="_____SYSTEM_COMPANY" kind="200" /> + <indexSearchRibbon> + <name>indexSearchRibbon</name> + <ribbonTasks> + <ribbonTask> + <name>TASK_INDEXSEARCH</name> + </ribbonTask> + </ribbonTasks> + </indexSearchRibbon> +</application> diff --git a/entity/Appointment_entity/Appointment_entity.aod b/entity/Appointment_entity/Appointment_entity.aod new file mode 100644 index 00000000000..bd143b765e1 --- /dev/null +++ b/entity/Appointment_entity/Appointment_entity.aod @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8"?> +<entity xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.0.3" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/entity/1.0.3"> + <name>Appointment_entity</name> + <title>Termin</title> + <majorModelMode>DISTRIBUTED</majorModelMode> + <alias>Data_alias</alias> + <jDitoRecordAlias>Data_alias</jDitoRecordAlias> + <fields> + <element>UID</element> + <element>BACKGROUNDCOLOR</element> + <element>FONTCOLOR</element> + <element>ATTENDEESLENGTH</element> + <element>STARTDATE</element> + <element>ENDDATE</element> + <element>SUBJECT</element> + <element>ORGANIZER</element> + <element>ATTENDEES</element> + <element>STATUS</element> + <element>LINKS</element> + <element>DESCRIPTION</element> + <element>LOCATION</element> + <element>ICON</element> + </fields> + <contentProcess>%aditoprj%/entity/Appointment_entity/contentProcess.js</contentProcess> + <onInsert>%aditoprj%/entity/Appointment_entity/onInsert.js</onInsert> + <onUpdate>%aditoprj%/entity/Appointment_entity/onUpdate.js</onUpdate> + <onDelete>%aditoprj%/entity/Appointment_entity/onDelete.js</onDelete> + <recordContainerType>JDITO</recordContainerType> + <caption>Termin</caption> + <entityFields> + <entityField> + <name>SUMMARY</name> + <fieldName>SUBJECT</fieldName> + <valueProcess>%aditoprj%/entity/Appointment_entity/entityfields/summary/valueProcess.js</valueProcess> + </entityField> + <entityParameter> + <name>entry</name> + <expose v="true" /> + <description>PARAMETER</description> + </entityParameter> + <entityField> + <name>DESCRIPTION</name> + <fieldName>DESCRIPTION</fieldName> + </entityField> + <entityField> + <name>STARTEND</name> + </entityField> + </entityFields> +</entity> diff --git a/entity/Appointment_entity/contentProcess.js b/entity/Appointment_entity/contentProcess.js new file mode 100644 index 00000000000..6457081b568 --- /dev/null +++ b/entity/Appointment_entity/contentProcess.js @@ -0,0 +1,58 @@ +import("system.result"); +import("system.vars"); +import("system.calendars"); +import("system.datetime"); +import("system.eMath"); + +if(vars.exists("$image.entry")) +{ + var entry = vars.get("$image.entry"); + + var uid = entry[calendars.ID]; + var summary = entry[calendars.SUMMARY]; + var affectedusers = entry[calendars.AFFECTEDUSERS]; + var attendees = entry[calendars.ATTENDEES]; + var startdate = entry[calendars.DTSTART]; + var enddate = entry[calendars.DTEND]; + var links = entry[calendars.LINKS]; + var description = entry[calendars.DESCRIPTION]; + var organizer = entry[calendars.ORGANIZER2]; + var status = entry[calendars.STATUS]; + var location = entry[calendars.LOCATION]; + var reminder = entry[calendars.REMINDER]; + var remindercheck = entry[calendars.HASREMINDER] + + //@TODO Icon + + result.object([ + [uid, '', '', attendees.length, startdate, enddate, summary, organizer, attendees, status, links, description, location, ''] //, location, reminder, remindercheck + ]); +} +else +{ + + + var filter = ( vars.exists("$param.p_filter") + && vars.get("$param.p_filter") != null + && vars.get("$param.p_filter") != undefined) ? vars.get("$param.p_filter") : ""; + + //For the Tableview in Task_Date + //var events = getEvents(filter); + var cond = { + TYPE_1: calendars.VEVENT + ,USER_1: vars.get("$sys.user") + ,COUNT: "1" + }; + var entries = calendars.getExpandedEntries(cond, new Long(datetime.date()), new Long(eMath.addInt(datetime.date(), datetime.ONE_DAY * 7))); + + for (i = 0; i < events.length; i++) + { + events[i].push([""]) + var count = events[i][3]; + var iconInfo = (count > 1 ? "gruppentermin" : "einzeltermin"); + var icon = (getIcon("termine_aufgaben", iconInfo)); + events[i] = events[i].concat(icon); + } + result.object(events); + +} \ No newline at end of file diff --git a/entity/Appointment_entity/entityfields/summary/valueProcess.js b/entity/Appointment_entity/entityfields/summary/valueProcess.js new file mode 100644 index 00000000000..e8dc52cb185 --- /dev/null +++ b/entity/Appointment_entity/entityfields/summary/valueProcess.js @@ -0,0 +1,5 @@ +import("system.result"); +import("system.vars"); + +var sum = vars.getString("$field.SUMMARY"); +result.string(sum); \ No newline at end of file diff --git a/entity/Appointment_entity/onDelete.js b/entity/Appointment_entity/onDelete.js new file mode 100644 index 00000000000..21038088ed6 --- /dev/null +++ b/entity/Appointment_entity/onDelete.js @@ -0,0 +1,17 @@ +import("system.neon"); +import("system.calendars"); +import("system.vars"); + +if (vars.exists("$image.entry")) +{ + var entry = vars.get("$image.entry"); + var reccurenceid = entry[calendars.RECURRENCEID]; + if (reccurenceid == undefined) reccurenceid = null; + calendars.removeEntryByUID(calendars.VEVENT, vars.get("$sys.user"), entry[calendars.ID], reccurenceid) +} + +if(vars.exists("$sys.ancestorimageuid") && vars.get("$sys.ancestorimageuid") != null) +{ + neon.closeImage(vars.getString("$sys.currentimage"), true); + neon.refresh(vars.get("$sys.ancestorimageuid")); +} \ No newline at end of file diff --git a/entity/Appointment_entity/onInsert.js b/entity/Appointment_entity/onInsert.js new file mode 100644 index 00000000000..0dd49954c32 --- /dev/null +++ b/entity/Appointment_entity/onInsert.js @@ -0,0 +1,359 @@ +import("system.neon"); +import("system.calendars"); +import("system.vars"); +import("system.question"); +import("system.translate"); +import("system.text"); +import("system.datetime"); +import("system.db"); +import("system.result"); +import("system.tools"); + +// Dieser Prozess speichert die im Frame angezeigten Daten +// Je nach Modus (INSERT, EDIT) wird ein neuer Datensatz angelegt oder der alte editiert +var event = vars.get("$image.entry"); + +var ok = false; + +event[calendars.TYPE] = calendars.VEVENT; +event[calendars.STATUS] = vars.getString("$field.STATUS"); +event[calendars.SUMMARY] = vars.getString("$field.SUBJECT"); +event[calendars.LOCATION] = vars.get("$field.LOCATION"); +event[calendars.DESCRIPTION] = vars.get("$field.DESCRIPTION"); +event[calendars.DTSTART] = vars.get("$field.STARTDATE"); +event[calendars.DTEND] = vars.get("$field.ENDDATE"); +event[calendars.HASREMINDER] = "false"; +var hasReminder = vars.get("$field.REMINDER_CHECK"); +if (hasReminder == "true") +{ + // Absolut nur, wenn auch gesetzt. Default ist relativ + if ( event[calendars.REMINDER_ABSOLUT] == "true") + { + var reminder_date = vars.get("$field.REMINDER"); + if ( reminder_date != "" ) + { + event[calendars.HASREMINDER] = "true"; + event[calendars.REMINDER_DATE] = reminder_date; + } + } +// else +// { +// var reminder_duration = vars.getString("$field.reminder_duration"); +// if ( reminder_duration != "") +// { +// event[calendars.HASREMINDER] = "true"; +// event[calendars.REMINDER_DURATION] = reminder_duration; +// } +// } +} +event[calendars.CLASSIFICATION] = vars.get("$field.CLASSIFICATION"); +// event[calendars.TRANSPARENCY] = vars.get("$field.transparency"); +event[calendars.AFFECTEDUSERS] = getAffectedUsers( event ); +// event[calendars.CATEGORIES] = vars.get("$field.categories"); +//calcrecurrence(event); +//if (event[calendars.RRULE] != undefined) recurrencend(event); +// Links updaten +// swing.saveTableEdit("$field.links"); +// Entweder jetzt neu anlegen oder nur updaten +event[calendars.ID] = calendars.insert([event])[0]; +vars.set("$image.editmode", calendars.MODE_UPDATE); +ok = true; + +////Zwischenspeichern +//if(vars.exists("$image.dontClose") && vars.get("$image.dontClose") ) ok = false; //Maske offen lassen +//vars.set("$image.dontClose", false); // zurücksetzen, damit Klick auf Speichern noch funktioniert + +if(vars.exists("$sys.ancestorimageuid") && vars.get("$sys.ancestorimageuid") != null) +{ + neon.closeImage(vars.getString("$sys.currentimage"), true); + neon.refresh(vars.get("$sys.ancestorimageuid")); +} + + +// Liefert die AffectedUsers +function getAffectedUsers( pEvent ) +{ + var affectedusers = vars.get("$image.affectedusers"); + var attendess = pEvent[calendars.ATTENDEES] + var calendarusers = []; + for ( var i = 0; i < affectedusers.length; i++) + { + var insert = true; + for ( var y = 0; y < attendess.length; y++) + { + // Teilnehmer schon vorhanden + if ( text.encodeMS( [attendess[y]["paramvalue"], "CN:" + attendess[y]["cn"]] ) == affectedusers[i][0] ) + { + var userparts = [attendess[y]["paramvalue"]]; + if ( affectedusers[i][1] != "" && affectedusers[i][1] != "UNKNOWN" ) attendess[y]["partstat"] = affectedusers[i][1]; + for ( var part in attendess[y] ) if ( part != "paramvalue") userparts.push(part + ":" + attendess[y][part] ) + calendarusers.push( text.encodeMS(userparts) ); + insert = false; + break; + } + } + if ( insert ) // Teilnehmer noch nicht im Termin vorhanden + { + var resource = db.cell("select THEME from THEME where THEMEID = '" + affectedusers[i][0] + "'"); + if( resource != "" && tools.existUsers(resource) ) + calendarusers.push(text.encodeMS(text.decodeMS(calendars.getCalendarUser(resource)).concat("CUTYPE:RESOURCE"))); + else calendarusers.push(affectedusers[i][0]); + } + } + // a.showMessage(calendarusers.join("\n")) + return text.encodeMS( calendarusers ); +} + +// Liefert die Benutzer zurück, auf die keine Schreibrechte bestehen +function getReadOnlyUser() +{ + var writeable = calendars.getFullCalendarUsers(calendars.RIGHT_WRITE); + var affectedusers = vars.get("$image.affectedusers"); + var readonly = new Array(); + + for ( i = 0; i < affectedusers.length; i++) + { + var user = affectedusers[i][0]; + if (!isWriteable(user, writeable)) + readonly.push(affectedusers[i][3]); + } + return readonly; +} + +// Liefert TRUE, wenn der Benutzer bei denen mit Schreibberechtigungen enthalten ist +function isWriteable(user, writeable) +{ + for (var i = 0; i < writeable.length; i++) + { + if (writeable[i][0] == calendars.getCalendarUser(user)) + return true; + } + return false; +} + +// Berechnet das Ende der Recurrence +function recurrencend(event) +{ + var rec_end = vars.getString("$field.rec_end"); + + // Automatische Erkennung, was gewollt ist + if (rec_end == "") + { + if (vars.get("$field.rec_end_count") != "") + rec_end = "Endet nach Anzahl Terminen"; + else if (vars.get("$field.rec_end_date") != "") + rec_end = "Endet am"; + } + + if (rec_end == "" || rec_end == "Kein Enddatum") + { + // Nichts + } + else if (rec_end == "Endet nach Anzahl Terminen") + { + event[calendars.RRULE][0] += (";COUNT=" + vars.get("$field.rec_end_count")); + } + else if (rec_end == "Endet am") + { + var dat = vars.get("$field.rec_end_date"); + var start = vars.get("$field.start_date"); + var localTime = datetime.toDate(dat, translate.text("yyyyMMdd")) + datetime.toDate(start, "HHmmss"); + var utcTime = datetime.toLong(localTime, "yyyyMMddHHmmss"); + event[calendars.RRULE][0] += (";UNTIL=" + datetime.toDate(utcTime, "yyyyMMdd\'T\'HHmmss\'Z\'", "UTC")); + } +} + +/** + * Berechnet die Wiederholung + * + * @param event Das fertige Event. Hier die Reccurrence speichern + */ +function calcrecurrence(event) +{ + var rec_type = vars.get("$field.rec_type"); + + if (rec_type == "") + { + // Nichts + } + else if (rec_type == "Keine") + { + } + else if (rec_type == "Täglich") + { + rec_daily(event); + } + else if (rec_type == "Wöchentlich") + { + rec_weekly(event); + } + else if (rec_type == "Monatlich") + { + rec_monthly(event); + } + else if (rec_type == "Jährlich") + { + rec_yearly(event); + } + else + { + question.showMessage("Internal (1) " + rec_type); + } +} +/***********************/ +function rec_yearly(event) +{ + var rec_year = vars.get("$field.rec_yearly"); + var rec_yearly_month = vars.get("$field.rec_yearly_month"); + var rec_yearly_day = vars.get("$field.rec_yearly_day"); + var month; + var day; + + if (rec_year == "") + { + if (rec_yearly_month != "" && rec_yearly_day != "") + rec_year = "Jeden # #"; + else if (rec_yearly_month != "" && vars.get("$field.rec_yearly_day2") != "" && vars.get("$field.rec_yearly_number2") != "") + rec_year = "Am #. # im #"; + } + + if (rec_year == "" || (rec_yearly_month == "" && rec_yearly_day == "" )) + { + question.showMessage(translate.text("Jährliche Serie nicht genauer spezifiziert. Ignoriere Serie.")); + } + else if (rec_year == "Jeden # #") + { + month = rec_yearly_month; + day = rec_yearly_day; + event[calendars.RRULE] = new Array("FREQ=YEARLY;BYMONTHDAY="+day+";BYMONTH="+month); + } + else if (rec_year == "Am #. # im #") + { + month = vars.get("$field.rec_yearly_month2"); + day = vars.get("$field.rec_yearly_day2"); + var number = vars.get("$field.rec_yearly_number2"); + event[calendars.RRULE] = new Array("FREQ=YEARLY;BYMONTH="+month+";BYDAY="+number+day); + } +} +/***********************/ +function rec_monthly(event) +{ + var rec_month = vars.get("$field.rec_month"); + var rec_monthly_day = vars.get("$field.rec_monthly_day"); + var rec_monthly_interval = vars.get("$field.rec_monthly_interval"); + var day; + var interval; + + if (rec_month == "") + + { + if (rec_monthly_day != "" && rec_monthly_interval != "") + rec_month = "Am #. jedes #. Monat"; + else if (vars.get("$field.rec_monthly_day2") != "" && vars.get("$field.rec_monthly_interval2") != "" && vars.get("$field.rec_monthly_weekday2") != "") + rec_month = "Am #. # jeden #. Monat"; + } + + if (rec_month == "" || (rec_monthly_day == "" && rec_monthly_interval != "")) + { + question.showMessage(translate.text("Monatliche Serie nicht genauer spezifiziert. Ignoriere Serie.")); + } + else if (rec_month == "Am #. jedes #. Monat") + { + day = rec_monthly_day; + interval = rec_monthly_interval; + event[calendars.RRULE] = new Array("FREQ=MONTHLY;INTERVAL=" + interval + ";BYMONTHDAY=" + day); + } + else if(rec_month == "Am #. # jeden #. Monat") + { + day = vars.get("$field.rec_monthly_day2"); + interval = vars.get("$field.rec_monthly_interval2"); + var weekday = vars.get("$field.rec_monthly_weekday2"); + event[calendars.RRULE] = new Array("FREQ=MONTHLY;INTERVAL=" + interval + ";BYDAY=" + day + weekday); + } +} +/***********************/ +function rec_weekly(event) +{ + + var rec_weekly_intervall = vars.get("$field.rec_weekly_intervall"); + if (rec_weekly_intervall == "") + rec_weekly_intervall = "1"; + + var days = new Array(); + var count = 0; + if (vars.get("$field.rec_weekly_mo") == "true") + { + days[count] = "MO"; + count++; + } + if (vars.get("$field.rec_weekly_di") == "true") + { + days[count] = "TU"; + count++; + } + if (vars.get("$field.rec_weekly_mi") == "true") + { + days[count] = "WE"; + count++; + } + if (vars.get("$field.rec_weekly_do") == "true") + { + days[count] = "TH"; + count++; + } + if (vars.get("$field.rec_weekly_fr") == "true") + { + days[count] = "FR"; + count++; + } + if (vars.get("$field.rec_weekly_sa") == "true") + { + days[count] = "SA"; + count++; + } + if (vars.get("$field.rec_weekly_so") == "true") + { + days[count] = "SU"; + count++; + } + if (count > 0) + { + event[calendars.RRULE] = new Array("FREQ=WEEKLY;INTERVAL=" + rec_weekly_intervall + ";WKST=MO;BYDAY="); + for (var i = 0; i < count; i++) + { + event[calendars.RRULE][0] += days[i]; + if (i+1 < count) + { + event[calendars.RRULE][0] += ","; + } + } + } +} +/***********************/ +function rec_daily(event) +{ + var rec_dailytype = vars.get("$field.rec_dailytype"); + var rec_dailydays = vars.get("$field.rec_daily_days"); + if (rec_dailytype == "") + { + if (rec_dailydays != "") + rec_dailytype = "Alle # Tage"; + } + + if (rec_dailytype == "" || rec_dailydays == "") + { + question.showMessage(translate.text("Tägliche Serie nicht genauer spezifiziert. Ignoriere Serie.")); + } + else if (rec_dailytype == "Alle # Tage") + { + event[calendars.RRULE] = new Array("FREQ=DAILY;INTERVAL=" + rec_dailydays); + } + else if (rec_dailytype == "Jeden Arbeitstag") + { + event[calendars.RRULE][0] = new Array("FREQ=WEEKLY;WKST=MO;BYDAY=MO,TU,WE,TH,FR"); + } + else + { + question.showMessage(translate.text("Internal (2)") + " " + rec_dailytype); + } +} \ No newline at end of file diff --git a/entity/Appointment_entity/onUpdate.js b/entity/Appointment_entity/onUpdate.js new file mode 100644 index 00000000000..77ab68ffa79 --- /dev/null +++ b/entity/Appointment_entity/onUpdate.js @@ -0,0 +1,368 @@ +import("system.neon"); +import("system.calendars"); +import("system.vars"); +import("system.question"); +import("system.translate"); +import("system.text"); +import("system.swing"); +import("system.datetime"); +import("system.db"); +import("system.result"); +import("system.tools"); + +// Dieser Prozess speichert die im Frame angezeigten Daten +// Je nach Modus (INSERT, EDIT) wird ein neuer Datensatz angelegt oder der alte editiert +if(vars.exists("$image.entry")) +{ + var event = vars.get("$image.entry"); + + var ok = false; + if ( calendars.getBackendType() == calendars.BACKEND_EXCHANGEWS && event[calendars.ORGANIZER2]["cn"] != event[calendars.USER2]["cn"]) + { + question.showMessage(translate.text("Ein Gruppentermin kann nur durch den Organisator bearbeitet werden.")); + ok = true; + } + else + { + event[calendars.TYPE] = calendars.VEVENT; + event[calendars.STATUS] = vars.getString("$field.STATUS"); + event[calendars.SUMMARY] = vars.getString("$field.SUBJECT"); + event[calendars.LOCATION] = vars.get("$field.LOCATION"); + event[calendars.DESCRIPTION] = vars.get("$field.DESCRIPTION"); + event[calendars.DTSTART] = vars.get("$field.STARTDATE"); + event[calendars.DTEND] = vars.get("$field.ENDDATE"); + event[calendars.HASREMINDER] = "false"; + var hasReminder = vars.get("$field.REMINDER_CHECK"); + if (hasReminder == "true") + { + // Absolut nur, wenn auch gesetzt. Default ist relativ + if ( event[calendars.REMINDER_ABSOLUT] == "true") + { + var reminder_date = vars.get("$field.REMINDER"); + if ( reminder_date != "" ) + { + event[calendars.HASREMINDER] = "true"; + event[calendars.REMINDER_DATE] = reminder_date; + } + } + // else + // { + // var reminder_duration = vars.getString("$comp.reminder_duration"); + // if ( reminder_duration != "") + // { + // event[calendars.HASREMINDER] = "true"; + // event[calendars.REMINDER_DURATION] = reminder_duration; + // } + // } + } + event[calendars.CLASSIFICATION] = vars.get("$field.CLASSIFICATION"); + // event[calendars.TRANSPARENCY] = vars.get("$comp.transparency"); + //event[calendars.AFFECTEDUSERS] = getAffectedUsers( event ); + // event[calendars.CATEGORIES] = vars.get("$comp.categories"); + // calcrecurrence(event); + // if (event[calendars.RRULE] != undefined) recurrencend(event); + // Links updaten + //swing.saveTableEdit("$comp.links"); + // Entweder jetzt neu anlegen oder nur updaten + + calendars.updateEntry(event); + + ok = true; + } + // //Zwischenspeichern + // if(vars.exists("$image.dontClose") && vars.get("$image.dontClose") ) ok = false; //Maske offen lassen + // vars.set("$image.dontClose", false); // zurücksetzen, damit Klick auf Speichern noch funktioniert + + + if(vars.exists("$sys.ancestorimageuid") && vars.get("$sys.ancestorimageuid") != null) + { + neon.closeImage(vars.getString("$sys.currentimage"), true); + neon.refresh(vars.get("$sys.ancestorimageuid")); + } +} +// Liefert die AffectedUsers +function getAffectedUsers( pEvent ) +{ + var affectedusers = vars.get("$image.affectedusers"); + var attendess = pEvent[calendars.ATTENDEES] + var calendarusers = []; + for ( var i = 0; i < affectedusers.length; i++) + { + var insert = true; + for ( var y = 0; y < attendess.length; y++) + { + // Teilnehmer schon vorhanden + if ( text.encodeMS( [attendess[y]["paramvalue"], "CN:" + attendess[y]["cn"]] ) == affectedusers[i][0] ) + { + var userparts = [attendess[y]["paramvalue"]]; + if ( affectedusers[i][1] != "" && affectedusers[i][1] != "UNKNOWN" ) attendess[y]["partstat"] = affectedusers[i][1]; + for ( var part in attendess[y] ) if ( part != "paramvalue") userparts.push(part + ":" + attendess[y][part] ) + calendarusers.push( text.encodeMS(userparts) ); + insert = false; + break; + } + } + if ( insert ) // Teilnehmer noch nicht im Termin vorhanden + { + var resource = db.cell("select THEME from THEME where THEMEID = '" + affectedusers[i][0] + "'"); + if( resource != "" && tools.existUsers(resource) ) + calendarusers.push(text.encodeMS(text.decodeMS(calendars.getCalendarUser(resource)).concat("CUTYPE:RESOURCE"))); + else calendarusers.push(affectedusers[i][0]); + } + } + return text.encodeMS( calendarusers ); + } + +// Liefert die Benutzer zurück, auf die keine Schreibrechte bestehen +function getReadOnlyUser() +{ + var writeable = calendars.getFullCalendarUsers(calendars.RIGHT_WRITE); + var affectedusers = vars.get("$image.affectedusers"); + var readonly = new Array(); + + for ( i = 0; i < affectedusers.length; i++) + { + var user = affectedusers[i][0]; + if (!isWriteable(user, writeable)) + readonly.push(affectedusers[i][3]); + } + return readonly; +} + +// Liefert TRUE, wenn der Benutzer bei denen mit Schreibberechtigungen enthalten ist +function isWriteable(user, writeable) +{ + for (var i = 0; i < writeable.length; i++) + { + if (writeable[i][0] == calendars.getCalendarUser(user)) + return true; + } + return false; +} + +// Berechnet das Ende der Recurrence +function recurrencend(event) +{ + var rec_end = vars.getString("$comp.rec_end"); + + // Automatische Erkennung, was gewollt ist + if (rec_end == "") + { + if (vars.get("$comp.rec_end_count") != "") + rec_end = "Endet nach Anzahl Terminen"; + else if (vars.get("$comp.rec_end_date") != "") + rec_end = "Endet am"; + } + + if (rec_end == "" || rec_end == "Kein Enddatum") + { + // Nichts + } + else if (rec_end == "Endet nach Anzahl Terminen") + { + event[calendars.RRULE][0] += (";COUNT=" + vars.get("$comp.rec_end_count")); + } + else if (rec_end == "Endet am") + { + var dat = vars.get("$comp.rec_end_date"); + var start = vars.get("$comp.start_date"); + var localTime = datetime.toDate(dat, translate.text("yyyyMMdd")) + datetime.toDate(start, "HHmmss"); + var utcTime = datetime.toLong(localTime, "yyyyMMddHHmmss"); + event[calendars.RRULE][0] += (";UNTIL=" + datetime.toDate(utcTime, "yyyyMMdd\'T\'HHmmss\'Z\'", "UTC")); + } +} + +/** + * Berechnet die Wiederholung + * + * @param event Das fertige Event. Hier die Reccurrence speichern + */ +function calcrecurrence(event) +{ + var rec_type = vars.get("$comp.rec_type"); + + if (rec_type == "") + { + // Nichts + } + else if (rec_type == "Keine") + { + } + else if (rec_type == "Täglich") + { + rec_daily(event); + } + else if (rec_type == "Wöchentlich") + { + rec_weekly(event); + } + else if (rec_type == "Monatlich") + { + rec_monthly(event); + } + else if (rec_type == "Jährlich") + { + rec_yearly(event); + } + else + { + question.showMessage("Internal (1) " + rec_type); + } +} +/***********************/ +function rec_yearly(event) +{ + var rec_year = vars.get("$comp.rec_yearly"); + var rec_yearly_month = vars.get("$comp.rec_yearly_month"); + var rec_yearly_day = vars.get("$comp.rec_yearly_day"); + var month; + var day; + + if (rec_year == "") + { + if (rec_yearly_month != "" && rec_yearly_day != "") + rec_year = "Jeden # #"; + else if (rec_yearly_month != "" && vars.get("$comp.rec_yearly_day2") != "" && vars.get("$comp.rec_yearly_number2") != "") + rec_year = "Am #. # im #"; + } + + if (rec_year == "" || (rec_yearly_month == "" && rec_yearly_day == "" )) + { + question.showMessage(translate.text("Jährliche Serie nicht genauer spezifiziert. Ignoriere Serie.")); + } + else if (rec_year == "Jeden # #") + { + month = rec_yearly_month; + day = rec_yearly_day; + event[calendars.RRULE] = new Array("FREQ=YEARLY;BYMONTHDAY="+day+";BYMONTH="+month); + } + else if (rec_year == "Am #. # im #") + { + month = vars.get("$comp.rec_yearly_month2"); + day = vars.get("$comp.rec_yearly_day2"); + var number = vars.get("$comp.rec_yearly_number2"); + event[calendars.RRULE] = new Array("FREQ=YEARLY;BYMONTH="+month+";BYDAY="+number+day); + } +} +/***********************/ +function rec_monthly(event) +{ + var rec_month = vars.get("$comp.rec_month"); + var rec_monthly_day = vars.get("$comp.rec_monthly_day"); + var rec_monthly_interval = vars.get("$comp.rec_monthly_interval"); + var day; + var interval; + + if (rec_month == "") + + { + if (rec_monthly_day != "" && rec_monthly_interval != "") + rec_month = "Am #. jedes #. Monat"; + else if (vars.get("$comp.rec_monthly_day2") != "" && vars.get("$comp.rec_monthly_interval2") != "" && vars.get("$comp.rec_monthly_weekday2") != "") + rec_month = "Am #. # jeden #. Monat"; + } + + if (rec_month == "" || (rec_monthly_day == "" && rec_monthly_interval != "")) + { + question.showMessage(translate.text("Monatliche Serie nicht genauer spezifiziert. Ignoriere Serie.")); + } + else if (rec_month == "Am #. jedes #. Monat") + { + day = rec_monthly_day; + interval = rec_monthly_interval; + event[calendars.RRULE] = new Array("FREQ=MONTHLY;INTERVAL=" + interval + ";BYMONTHDAY=" + day); + } + else if(rec_month == "Am #. # jeden #. Monat") + { + day = vars.get("$comp.rec_monthly_day2"); + interval = vars.get("$comp.rec_monthly_interval2"); + var weekday = vars.get("$comp.rec_monthly_weekday2"); + event[calendars.RRULE] = new Array("FREQ=MONTHLY;INTERVAL=" + interval + ";BYDAY=" + day + weekday); + } +} +/***********************/ +function rec_weekly(event) +{ + + var rec_weekly_intervall = vars.get("$comp.rec_weekly_intervall"); + if (rec_weekly_intervall == "") + rec_weekly_intervall = "1"; + + var days = new Array(); + var count = 0; + if (vars.get("$comp.rec_weekly_mo") == "true") + { + days[count] = "MO"; + count++; + } + if (vars.get("$comp.rec_weekly_di") == "true") + { + days[count] = "TU"; + count++; + } + if (vars.get("$comp.rec_weekly_mi") == "true") + { + days[count] = "WE"; + count++; + } + if (vars.get("$comp.rec_weekly_do") == "true") + { + days[count] = "TH"; + count++; + } + if (vars.get("$comp.rec_weekly_fr") == "true") + { + days[count] = "FR"; + count++; + } + if (vars.get("$comp.rec_weekly_sa") == "true") + { + days[count] = "SA"; + count++; + } + if (vars.get("$comp.rec_weekly_so") == "true") + { + days[count] = "SU"; + count++; + } + if (count > 0) + { + event[calendars.RRULE] = new Array("FREQ=WEEKLY;INTERVAL=" + rec_weekly_intervall + ";WKST=MO;BYDAY="); + for (var i = 0; i < count; i++) + { + event[calendars.RRULE][0] += days[i]; + if (i+1 < count) + { + event[calendars.RRULE][0] += ","; + } + } + } +} +/***********************/ +function rec_daily(event) +{ + var rec_dailytype = vars.get("$comp.rec_dailytype"); + var rec_dailydays = vars.get("$comp.rec_daily_days"); + if (rec_dailytype == "") + { + if (rec_dailydays != "") + rec_dailytype = "Alle # Tage"; + } + + if (rec_dailytype == "" || rec_dailydays == "") + { + question.showMessage(translate.text("Tägliche Serie nicht genauer spezifiziert. Ignoriere Serie.")); + } + else if (rec_dailytype == "Alle # Tage") + { + event[calendars.RRULE] = new Array("FREQ=DAILY;INTERVAL=" + rec_dailydays); + } + else if (rec_dailytype == "Jeden Arbeitstag") + { + event[calendars.RRULE][0] = new Array("FREQ=WEEKLY;WKST=MO;BYDAY=MO,TU,WE,TH,FR"); + } + else + { + question.showMessage(translate.text("Internal (2)") + " " + rec_dailytype); + } +} \ No newline at end of file diff --git a/neonContext/Appointment_context/Appointment_context.aod b/neonContext/Appointment_context/Appointment_context.aod new file mode 100644 index 00000000000..96cb8c162a3 --- /dev/null +++ b/neonContext/Appointment_context/Appointment_context.aod @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<neonContext xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.0.0" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonContext/1.0.0"> + <name>Appointment_context</name> + <title>Termin</title> + <majorModelMode>DISTRIBUTED</majorModelMode> + <icon>VAADIN:CALENDAR</icon> + <mainview>AppointmentEdit_view</mainview> + <filterview>AppointmentPreview_view</filterview> + <editview>AppointmentEdit_view</editview> + <preview>AppointmentPreview_view</preview> + <entity>Appointment_entity</entity> + <references> + <neonViewReference> + <name>90fe74fe-9bc6-4f63-9c06-52e1b0ccfcb3</name> + <view>AppointmentEdit_view</view> + </neonViewReference> + <neonViewReference> + <name>9cf48e57-ca02-4cee-911c-20b09e36637d</name> + <view>AppointmentPreview_view</view> + </neonViewReference> + </references> +</neonContext> diff --git a/neonContext/Org_context/Org_context.aod b/neonContext/Org_context/Org_context.aod index cb19560598e..c9a5b204f3b 100644 --- a/neonContext/Org_context/Org_context.aod +++ b/neonContext/Org_context/Org_context.aod @@ -4,6 +4,7 @@ <title>Company</title> <majorModelMode>DISTRIBUTED</majorModelMode> <icon>VAADIN:BUILDING</icon> + <iconProcess>%aditoprj%/neonContext/Org_context/iconProcess.js</iconProcess> <mainview>OrgMain_view</mainview> <filterview>OrgFilter_view</filterview> <editview>OrgEdit_view</editview> diff --git a/neonContext/Org_context/iconProcess.js b/neonContext/Org_context/iconProcess.js new file mode 100644 index 00000000000..e69de29bb2d diff --git a/neonView/AppointmentEdit_view/AppointmentEdit_view.aod b/neonView/AppointmentEdit_view/AppointmentEdit_view.aod new file mode 100644 index 00000000000..8bb02c87b7b --- /dev/null +++ b/neonView/AppointmentEdit_view/AppointmentEdit_view.aod @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.0.0" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.0.0"> + <name>AppointmentEdit_view</name> + <majorModelMode>DISTRIBUTED</majorModelMode> + <layout> + <boxLayout> + <name>layout</name> + </boxLayout> + </layout> + <children> + <appointmentEditViewTemplate> + <name>AppointmentEditTemplate</name> + <summaryField>SUMMARY</summaryField> + <beginField>SUMMARY</beginField> + <endField>SUMMARY</endField> + <affectedUsersField>SUMMARY</affectedUsersField> + <attendeesField>SUMMARY</attendeesField> + <privateField>SUMMARY</privateField> + <statusField>SUMMARY</statusField> + <locationField>SUMMARY</locationField> + <entityField>#ENTITY</entityField> + </appointmentEditViewTemplate> + </children> +</neonView> diff --git a/neonView/AppointmentPreview_view/AppointmentPreview_view.aod b/neonView/AppointmentPreview_view/AppointmentPreview_view.aod new file mode 100644 index 00000000000..2d360e85afc --- /dev/null +++ b/neonView/AppointmentPreview_view/AppointmentPreview_view.aod @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<neonView xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.0.0" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonView/1.0.0"> + <name>AppointmentPreview_view</name> + <majorModelMode>DISTRIBUTED</majorModelMode> + <layout> + <boxLayout> + <name>layout</name> + </boxLayout> + </layout> + <children> + <appointmentPreviewViewTemplate> + <name>AppointmentPreviewTemplate</name> + <summaryField>SUMMARY</summaryField> + <periodField>SUMMARY</periodField> + <affectedUsersField>SUMMARY</affectedUsersField> + <attendeesField>SUMMARY</attendeesField> + <privateField>SUMMARY</privateField> + <statusField>SUMMARY</statusField> + <entityField>#ENTITY</entityField> + </appointmentPreviewViewTemplate> + </children> +</neonView> diff --git a/preferences/_____PREFERENCES_PROJECT/_____PREFERENCES_PROJECT.aod b/preferences/_____PREFERENCES_PROJECT/_____PREFERENCES_PROJECT.aod index 0b8e255da51..2e9d98b454f 100644 --- a/preferences/_____PREFERENCES_PROJECT/_____PREFERENCES_PROJECT.aod +++ b/preferences/_____PREFERENCES_PROJECT/_____PREFERENCES_PROJECT.aod @@ -2,7 +2,7 @@ <preferences xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="3.0.1" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/preferences/3.0.1"> <name>_____PREFERENCES_PROJECT</name> <majorModelMode>DISTRIBUTED</majorModelMode> - <projectName>xRM-Basic-5</projectName> + <projectName>xRM-Basic 5</projectName> <jditoMaxContentSize v="57671680" /> <clientSearchOptimizedForSpeed v="true" /> <clientSearchExcludeForIgnorecase v="true" /> diff --git a/process/openCalendarProzess/openCalendarProzess.aod b/process/openCalendarProzess/openCalendarProzess.aod new file mode 100644 index 00000000000..fe47bdfc013 --- /dev/null +++ b/process/openCalendarProzess/openCalendarProzess.aod @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<process xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.7" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/process/1.1.7"> + <name>openCalendarProzess</name> + <majorModelMode>DISTRIBUTED</majorModelMode> + <process>%aditoprj%/process/openCalendarProzess/process.js</process> +</process> diff --git a/process/openCalendarProzess/process.js b/process/openCalendarProzess/process.js new file mode 100644 index 00000000000..806b2cf096d --- /dev/null +++ b/process/openCalendarProzess/process.js @@ -0,0 +1,8 @@ +import("system.swing"); +import("system.calendars"); + +var windowmode;//value of this variable is defined by the ADITO-kernel automatically; +if (windowmode == undefined) + windowmode = swing.WINDOW_CURRENT; + +swing.openCalendar(windowmode, calendars.SHOW_CAL | calendars.SHOW_DATE | calendars.SHOW_USER, calendars.VIEWMODE_DEFAULT, false , [], [], true); \ No newline at end of file -- GitLab