//globale Variable var maint = false; // Wartung?? var ajaxURL="php/sofueDB.php"; var beos = []; // 0 1 2 3 (4) (5) var stati = ['neu', 'offen', 'zugesagt', 'abgesagt', 'erledigt','statistik']; var allWettN = ['ja','nein']; var gridID = 'Table'; var pagerID = 'Pager'; var now = moment(); var privilege = false; let showdbasename = false; const hellgruen='#C8FFC8'; moment.locale('de'); function checkFuehrung(was) { privilege = was=="Gut"?true:false; } //Übersicht über alle Stati //Jeweils nur 5 Einträge, kein Pager function uebersicht() { for (var i=0; i< stati.length; i++) { buildGrid(''+(i+1),15,false); $('#gbox_Table'+(i+1)).css({ "margin":"0 auto 20px auto"}); } $('#gbox_Table'+(stati.length)).css({ "margin":"0 auto 0px auto"}); } //Beim Umschalten der Tabs die richtigen Grids aufrufen function setFocus() { var tab = $('#tabs').tabs('option','active'); if(tab == 0) { uebersicht(); // tab0 -> die Übersicht darstellen } else { buildGrid('0'+(tab),20,true); // alle anderen: 20 Zeilen der entsprechende } // Listen mit mit Pager anzeigen } //Daten eines Datenbank-Eintrages per Ajax holen und //dann die Dialog-Box mit den Daten befüllen function buildEntryScreen(id) { console.log("Entry with ID:", id); var arr = {cmd:'GET_ONE',id:id}; doAjaxCall_arr(ajaxURL,arr,fillInDetails) } // Übergenen Zeit testen, ob sie mit 1900 oder 0000 startet function check1900(termin) { if (termin.startsWith("1900") || termin.startsWith("0000")) { return true; } return false; } function getsunandmoon(timestr, htmlfield) { // get sunset and moonphase from https://api.met.no/weatherapi/sunrise/2.0/ const lat = 48.8741; const lon = 9.59611; const dt = moment(timestr).format('YYYY-MM-DD'); let tz = '+01:00'; if(moment(timestr).isDST()) { tz = '+02:00'; } let su const urls = 'https://api.met.no/weatherapi/sunrise/3.0/sun?lat=' + lat + '&lon=' + lon + '&date=' + dt + '&offset=' + tz; const urlm = 'https://api.met.no/weatherapi/sunrise/3.0/moon?lat=' + lat + '&lon=' + lon + '&date=' + dt + '&offset=' + tz; $.ajax({ type: "get", // wir machen eine POST - Abfrage url: urls, // an diese Seite auf dem Server success : function(erg) { // wenn Erfolg, dann console.log(">" + JSON.stringify(erg, null, 2) + "<"); su = erg.properties.sunset.time.substr(11,5) || "--"; $.ajax({ // AJAX-Call type: "get", // wir machen eine POST - Abfrage url: urlm, // an diese Seite auf dem Server success : function(erg) { // wenn Erfolg, dann console.log(">" + JSON.stringify(erg, null, 2) + "<"); let ma, mu; if ((erg.properties.moonrise.time) == null) { ma = "--"; } else { ma = erg.properties.moonrise.time.substr(11,5); } if ((erg.properties.moonset.time) == null) { mu = "--"; } else { mu = erg.properties.moonset.time.substr(11,5); } let mp = erg.properties.moonphase.toFixed(0); // recalc 'mp' so, that full moon is 100% and add a (abnehmend) or z (zunehmend) let MP; let az = ""; if (mp <= 180) { MP = mp * 100 / 180; az = 'z'; } else { MP = (360 - mp) * 100 / 180; az = 'a'; } MP = Math.round(MP); console.log(`SU:${su} MA:${ma} MP:${mp}-${MP}${az} MU:${mu}`); let anz = $(htmlfield).html(); $(htmlfield).html(anz + `SU:${su}  MA:${ma}  MP:${MP}%${az}  MU:${mu}`); }, error: function(xh,t) { // wenn Error, dann eine Alertbox hinmalen console.log("xh=" + JSON.stringify(xh) + " t=" + t + xh.getAllResponseHeaders() + "\na) " + xh.responseText + "\nb) " + xh.statusText); }, }) }, error: function(xh,t) { // wenn Error, dann eine Alertbox hinmalen console.log("xh=" + JSON.stringify(xh) + " t=" + t + xh.getAllResponseHeaders() + "\na) " + xh.responseText + "\nb) " + xh.statusText); }, }) } //Die Detail-Dialog-Box mit den Daten füllen function fillInDetails(detail) { console.log(detail); if(detail.stattgefunden != 1) { $('.stattgefunden').css('display','none'); } $('#d_name').html(detail.vorname+' '+detail.name); $('#d_verein').html(detail.verein); $('#d_adresse').html(detail.strasse + ', ' + detail.plz + ' ' + detail.ort); $('#d_anmeldung').html(detail.anmelde_datum); $('#d_anzahl').html(detail.anzahl); $('#d_telefon').html(detail.telefon); $('#d_email').html(detail.email); let wt = '' + moment(detail.wtermin).format('dd YYYY-MM-DD HH:mm') + '
'; $('#d_wtermin').html(wt); getsunandmoon(detail.wtermin, '#d_wtermin'); if(check1900(detail.atermin)) { $('#d_atermin').html("--"); } else { let at = '' + moment(detail.atermin).format('dd YYYY-MM-DD HH:mm') + '
'; $('#d_atermin').html(at); getsunandmoon(detail.atermin, '#d_atermin'); } $('#d_spende').html(detail.spende) $('#d_zusage').html(stati[detail.status]); $('#d_beos').html(detail.mitarbeiter); var ed = detail.erledigt_datum; if(check1900(ed)) { ed = "--" }; $('#d_wann').html(ed); if (detail.status == 2) { $('#d_zusage').css('background',hellgruen); } else if (detail.status==3) { $('#d_zusage').css('background','#FE2E2E'); } $('#d_bemerkung').html(detail.bemerkung); if (detail.status < 2) { // Wenn zu- oder abgesagt $('.zuab').css('display','none') } var mit = detail.mitteilung.replace(/\r\n|\r|\n/g, '
'); $('#d_mitt').html(mit); if((privilege == true) &&(detail.stattgefunden != 1)) { addEditbox(detail); } else { $('#divEnter').css('display','none'); $('#div_detail').siblings('.ui-dialog-buttonpane').find('button').eq(0).hide(); $('#div_detail').siblings('.ui-dialog-buttonpane').find('button').eq(1).hide(); $('#div_detail').siblings('.ui-dialog-buttonpane').find('button').eq(2).html('Schließen'); } $('#statt_anzahl').html(detail.anzahl_echt); $('#statt_spende').html(detail.bezahlt); $('#statt_remarks').html(detail.remarks); $('.stattgefunden').css('background',hellgruen); } function addEditbox(detail) { var stat = detail.status; // 0,1,2,3 var radio = ""; for (var i=0; i"; } else { radio += ">"; } radio += "
"; } $('#d_status').append(radio); // Zwei InputFelder für die Termine // Zuagesagt-Termin inputTermine = "Wunsch-Termin
" ; inputTermine += ""; inputTermine += "Ausweich-Termin
" ; if(check1900(detail.atermin)) { inputTermine += ""; } else { inputTermine += ""; } $('#d_zutermin').append(inputTermine); $('#curmar').val(''); if (stat == 2) { $('#curmar').val(detail.mitarbeiter+', '); buildBeosComplete(); } $('#txbem').val(detail.bemerkung); // Picker für den WunschTermin $('#chgwtermin').datetimepicker( // Initialisierung des datetimepickers { showOn: 'focus' , // onFocus wird der Picker angezeigt defaultDate: detail.wtermin, hour: moment(detail.wtermin).format("HH"), timeFormat: 'HH:mm', showMinute: true, stepMinute: 15, showSecond: false, showMillisec: false, showMicrosec: false, showTimezone: false, hourMin: 13, dateFormat: "yy-mm-dd", // angezeigt wird in diesem Format minDate: "+1d", // min Datum: morgen closeText: "OK", // erst wenn OK geklickt wird, dann gehts weiter timeText: "Uhrzeit", // Texte dazu hourText: "Stunde", onClose: function (dateText, inst) { // was passiert, wenn OK gedrückt wird: if(dateText != "") { var dt = moment(dateText).format('dd YYYY-MM-DD HH:mm'); $("#chgwtermin").html(dt); $("#d_wtermin").html(dt); } } }); // Picker für den Ausweichtermin $('#chgatermin').datetimepicker( // Initialisierung des datetimepickers { showOn: 'focus' , // onFocus wird der Picker angezeigt defaultDate: detail.atermin, hour: check1900(detail.atermin) ? "13" : moment(detail.atermin).format("HH"), timeFormat: 'HH:mm', showMinute: true, stepMinute: 15, showSecond: false, showMillisec: false, showMicrosec: false, showTimezone: false, hourMin: 13, dateFormat: "yy-mm-dd", // angezeigt wird in diesem Format minDate: "+1d", // min Datum: morgen closeText: "OK", // erst wenn OK geklickt wird, dann gehts weiter timeText: "Uhrzeit", // Texte dazu hourText: "Stunde", onClose: function (dateText, inst) { // was passiert, wenn OK gedrückt wird: if(dateText != "") { var dt = moment(dateText).format('dd YYYY-MM-DD HH:mm'); $("#chgatermin").html(dt); $("#d_atermin").html(dt); } } }); $('#d_status').change(function() { var s = $('input[name="stati"]:checked').val(); console.log("Status: ",s); $('#curmar').val(''); if (s==2) { // zugesagt $('#curmar').val(detail.mitarbeiter); buildBeosComplete(); } }); } //bei der Eingabe der BEOs eine Autovervollständigung durchführen function buildBeosComplete() { function split( val ) { return val.split( /,\s*/ ); } function extractLast( term ) { return split( term ).pop(); } $( "#curmar" ) // don't navigate away from the field on tab when selecting an item .on( "keydown", function( event ) { if ( event.keyCode === $.ui.keyCode.TAB && $( this ).autocomplete( "instance" ).menu.active ) { event.preventDefault(); } }) .autocomplete({ minLength: 0, source: function( request, response ) { // delegate back to autocomplete, but extract the last term response( $.ui.autocomplete.filter( beos, extractLast( request.term ) ) ); }, focus: function() { // prevent value inserted on focus return false; }, select: function( event, ui ) { var terms = split( this.value ); // remove the current input terms.pop(); // add the selected item terms.push( ui.item.value ); // add placeholder to get the comma-and-space at the end terms.push( "" ); this.value = terms.join( ", " ); return false; } }); }; function formatTermin(rob, how, what ) { var t = rob.wtermin; if(how == 0) { return moment(t).format("dd"); } else if (how == 1) { return moment(t).format("YYYY-MM-DD"); } else if (how == 2) { return moment(t).format("HH:mm"); } else { return("1900"); } } //Grid erzeugen. function buildGrid(what,count,dopager) { // Einstellungen für die Grids var lastsel; var grid = gridID+what; var pgr = dopager ? pagerID+what : ''; what = parseInt(what)-1; var te = dopager ? 'all' : 'neu'; // var te = 'all'; var pData = {cmd:"GET_MANY",status:what,termin:te}; var rNm = count; var titl = stati[what].replace(/\b\w/g, l => l.toUpperCase()); if(what == 4){ titl += " - stattgefunden"; } var rowID; var thegrid = $('#'+grid); var mdat = "angemeldet am"; var adat = "anmelde_datum"; var term = 'wtermin'; if (what == 2) { mdat = "zugesagt am"; } else if (what == 3) { mdat = "abgesagt am"; } if(what >=2 ) { adat='erledigt_datum'; } // cn = ['Wtg','Datum','Zeit','Wer','Verein','Anzahl','Bemerkungen','AllW',mdat]; cn = ['Wtg','Datum','Zeit','Wer','Verein','Anzahl','Bemerkungen',mdat]; if(what == 2) { // cn = ['Wtg','Datum','Zeit','Wer','Verein','Anzahl','Bemerkungen','AllW',mdat,'Beo(s)']; cn = ['Wtg','Datum','Zeit','Wer','Verein','Anzahl','Bemerkungen',mdat,'Beo(s)']; } if(what == 4) { cn = ['Wtg','Datum','Zeit','Wer','Verein','Anzahl','Bemerkungen','Spende','Beo(s)']; } cm = [ { name:'wt', width:30, align:'center', formatter: function(cellvalue,option,rowObject) { return formatTermin(rowObject,0,what); } }, { name:'dat', width:95, align:'center', formatter: function(cellvalue,option,rowObject) { return formatTermin(rowObject,1,what); } }, { name: term, width:50, formatter: function(cellvalue,option,rowObject) { return formatTermin(rowObject,2,what); } }, { name: 'name', width:150, formatter: function(cv, opt, row) { return row.vorname+' '+row.name; }, cellattr: function (rowId, tv, rawObject, cm, rdata) { return 'style="white-space: normal;"' } }, { name: 'verein', width:208, cellattr: function (rowId, tv, rawObject, cm, rdata) { return 'style="white-space: normal;"' } }, ]; if(what != 4) { cm.push( { name: 'anzahl', width:50, align:'center'}, { name: 'bemerkung', width:235, cellattr: function (rowId, tv, rawObject, cm, rdata) { return 'style="white-space: normal;"' } }, // { name: 'allwetter', width:35, align:'center', formatter: function(cv, opt,row) { // return (row.allwett=='ja')? "X":""; // } // }, { name: adat, width:100, formatter: function(cellvalue) { if (check1900(cellvalue)) { return "--"; } else { return moment(cellvalue).format(" YYYY-MM-DD "); } ; } }); } if(what == 2) { cm.push( { name: 'mitarbeiter', width:100, cellattr: function (rowId, tv, rawObject, cm, rdata) { return 'style="white-space: normal;"' }}); // cm[1].width = 125; cm[2].width = 50; cm[3].width = 155; cm[4].width = 152; cm[6].width = 180; } if(what == 4) { cm.push( { name: 'anzahl_echt', width:50, align:'center'}, { name: 'remarks', width:200, cellattr: function (rowId, tv, rawObject, cm, rdata) { return 'style="white-space: normal;"' } }, { name: 'bezahlt', width: 80, align: 'center', formatter: (cellvalue)=>{ if (!isNaN(parseInt(cellvalue,10))) { cellvalue += " €"; } return cellvalue }}, { name: 'mitarbeiter', width:100, cellattr: function (rowId, tv, rawObject, cm, rdata) { return 'style="white-space: normal;"' }}); // cm[1].width = 120; cm[2].width = 50; cm[3].width = 150; cm[4].width = 180; cm[6].width = 183; } // Grid nun aufbauen thegrid.jqGrid({ url: ajaxURL, datatype: "json", mtype:"POST", postData: pData, colNames: cn, colModel: cm, editurl: ajaxURL, // autowidth: true, rowNum: count, height:'100%', // scrollOffset:0, // scroll: 1, hidegrid: false, // hoverrows: false, // shrinkToFit: false, pager: pgr, viewrecords:true, caption: titl, onSelectRow: function(id,status) { $("#"+grid).resetSelection(); // row wieder delesecten -> kein Einfärben mehr $('#div_detail').data('id',id).dialog("open"); // dafür Detail-Box öffnen }, gridview: true, rowattr: function (rd,co,ri) { if (moment(rd.wtermin) >= now) { return {"class": "extraRowClass allRowClass"}; } if((what == 2) && (co.stattgefunden == 1)) { return {"class": "greenRowClass allRowClass"}; } }, loadComplete: function(data) { console.log(data); } }); // $(thegrid[0].grid.cDiv).click(function() { // alert("Clicked on Caption-.Bar"); // }); thegrid.jqGrid('destroyGroupHeader'); let termin = 'Wunsch-Termin'; if (what==2) { termin = 'zugesagter Termin'; } if (what == 4) { termin = 'Termin'; } thegrid.jqGrid('setGroupHeaders', { useColSpanStyle: true, groupHeaders:[ {startColumnName: 'wt', numberOfColumns: 3, titleText: termin}, // {startColumnName: 'allwetter', numberOfColumns: 1, titleText: (what==2)?'All-' : ''}, ] }); } //zur Darstellung des Namens Vor- und Nachname aneinander hängen function nameFormatter(cv, opt, row) { return row.vorname+' '+row.name; } //die Werte nun in die Datenbank eintragen function saveSettings() { const id = $('#div_detail').data('id'); const status = $('input[name="stati"]:checked').val(); let edate = $('#d_wann').text(); if ((edate == "")||(edate == "--")) { edate = "1900-01-01"; } if ((status >= 2) && (check1900(edate))) { edate = moment().format('YYYY-MM-DD'); } let marb = $('#curmar').val().trim(); if (marb.substr(-1,1) == ',') { marb = marb.substr(0,marb.length-1); } let atim = $('#d_atermin').text().substr(3, 16); if((atim == "") || (atim == "--")) { atim = "1900-01-01 00:00:00"; } let aw = $('input[name="awett"]:checked').val(); let termin = $('#d_wtermin').text().substr(3,16); // Status, Mitarbeiter und Bemerkungen übergeben const cmd = { status: status, mitarbeiter: status == 2 ? marb : "", bemerkung: $('#txbem').val(), id: id, wtermin: termin, atermin: atim, allwett:aw==0?"ja":"nein", cmd: 'UPDATE', erledigt_datum: edate } console.log(cmd); // await fetch(ajaxURL, { // method: 'POST', // body: JSON.stringify(cmd), // headers: { // 'Content-Type': 'application/json' // } // }) doAjaxCall_arr(ajaxURL,cmd,showajaxerg); if(status == 1) { // offen -> mail an Liste sendmail2liste(id); } if (status == 2) { sendmail2beo(id, marb, termin) sendmailzusage(id, marb, termin); } } //den selektierten Eintrag aus der Datenbank löschen function deletEntry() { var cmd = { cmd: 'DELETE', // cmd: 'TSTMAIL', mitarbeiter: $('#curmar').val(), id: $('#div_detail').data('id') } console.log(cmd); doAjaxCall_arr(ajaxURL,cmd,showajaxerg); } function showajaxerg(erg) { console.log("AjaxErg: ", erg); location.reload(true); } function readBeos() { // Einlesen der BEOs vom Server var cmd = { cmd: 'GET_BEOS', what: 'name', cond: 'gruppe <> empty' } doAjaxCall_arr(ajaxURL,cmd, function(erg) { beos = erg; console.log(beos); }); } function showdbase(val) { $('#showDB').html(val); } // Status wurde auf 'offen' gesetzt -> nun eine Mail an die Liste mit der Anfrage senden function sendmail2liste(id) { const liste = 'sternwarte@planetariumsgesellschaft.de'; const cmd = {cmd: 'SENDMAIL2LISTE', id: id, to: liste} console.log("Sende mail to Liste"); doAjaxCall_arr(ajaxURL,cmd,showajaxerg); console.log("Mail gesendet"); } // Status wurde auf 'zugesgat' gesetzt -> nun eine Mail an den BEO senden function sendmail2beo(id, beo, termin) { let cmd = {cmd: 'SENDMAIL2BEO', ma: beo, termin: termin} console.log("Sende mail to " + beo); doAjaxCall_arr(ajaxURL,cmd,showajaxerg); console.log("Mail gesendet"); // und in den Kalender eintragen cmd = {cmd: 'PUT2KALENDER', id: id, termin: termin, mitarbeiter: beo} doAjaxCall_arr(ajaxURL,cmd,showajaxerg); } function sendmailzusage(id, beo, termin) { let cmd = {cmd: 'SENDMAILZUSAGE', id: id, mitarbeiter: beo, termin: termin} console.log("Sende Zusage"); doAjaxCall_arr(ajaxURL,cmd,showajaxerg); console.log("ZUSAGE gesendet"); } //Beim Start, wenn das Dokument komplett geladen ist, dann //- Eventhandler registrieren //- Tabs aufrufen //- weitere allgmeine Optionen setzen $(document).ready(function() { // **** diverse DIVs vorbelegen /* $('#div_detail').load('detail.html'); $('#anleitung').load('anleitung.html'); */ $("#tabNr-0").load("tab0.html", function() { uebersicht(); }); $("#tabNr-1").load("tab1.html", function() { }); $("#tabNr-2").load("tab2.html", function() { }); $("#tabNr-3").load("tab3.html", function() { }); $("#tabNr-4").load("tab4.html", function() { }); $("#tabNr-5").load("tab5.html", function() { }); $("#tabNr-6").load("tab6.html", function() { }); $('#versn').html("Version: " + VERSION + ' vom ' + VDATE); if(showdbasename) { doAjaxCall_arr(ajaxURL,{cmd:'SHOWDB'}, function(erg) { console.log(erg); showdbase(erg); }); } // **** Funktionen gleich ausführen: // BEOS aus der Datenbank lesen readBeos(); // **** Events festlegen $("#tabs") // tabs startet mit TAB0 seletiert .tabs({ active : 0 }).on("tabsactivate", function(e, u) { // beim Tabwechsel Event abfangen setFocus(); }); // Klick auf den Anleitungs-Button $('#manual').click(function() { $("#anleitung").dialog('open'); }); // **** Dialoge festlegen // 1. Dialog zun Anzeigen und Editieren eines Eintrages $('#div_detail').dialog({ autoOpen: false, width: 930, position: { my: 'top', at: 'top' , of: '#tabs'}, title: 'Details', open: function() { var id = $('#div_detail').data('id'); $(this).load('detail.html', function() { buildEntryScreen(id) $('#beo').change(function() { // Beo ausgewählt var m = $(this).val(); // Name(n) holen var mstr = ''; m.forEach(function(n) { // Namen in den String 'mstr' mstr += n + ', '; // reinbaseln (mit Komma dazwischen) }) mstr = mstr.substr(0,mstr.length-2); // letztes Komma entfernen $('#curmar').html(mstr); // und anzeigen }); }); }, buttons: [ { text: "Sichern", class: "ui-button-left btnOK", click: function () { saveSettings(); }, style: "margin-left:20px;", width: 150, },{ text: "Löschen", class: "btnOK ui-button-left", click: function() { $('#div_loesch').dialog("open"); }, style: "margin-left:40px;", width: 150, },{ text: "Abbrechen", click : function() { $(this).dialog("close"); }, width: 150, }], modal: true, close: function() { }, }); // 2. Dialog zun Löschen bestätigen $('#div_loesch').dialog({ autoOpen: false, width: 400, modal: true, title: 'Löschen', buttons: [ { text: "Löschen", class: "btnOK ui-button-left", click: function() { deletEntry(); $(this).dialog("close"); }, style: "margin-left:40px;", width: 150, },{ text: "Abbrechen", click : function() { $(this).dialog("close"); }, width: 150, } ], }); // 3. Dialog für die Anleitung // Dieser hat KEINEN Button (wird über das Schließkreuz beendet) und // eine etwas kleinere Schrift $("#anleitung").dialog({ autoOpen: false, width: 900, modal: true, position: {my: 'top', at: 'top', of: window }, title: 'Anleitung', open: function() { $(this).load('anleitung.html'); }, buttons: [ { text: "Abbrechen", click : function() { $(this).dialog("close"); }, width: 150, } ], }); // 4. Dialog für die Wartungs-Meldung // Wird nur aufgerufen, wenn das Flag WARTUNG gesetzt ist // Kann NICHT beendet werden $('#maint').dialog({ autoOpen: false, modal : true, width : 400, title: 'Wartung', open: function(event,ui) { $(this).load('maintenance.html'); $(".ui-dialog-titlebar-close", ui.dialog).hide(); } }); // Datepicker auf Deutsch einstellen $.datepicker.regional['de'] = { closeText: '', prevText: '<', nextText: '>', currentText: '', monthNames: ['Januar','Februar','März','April','Mai','Juni', 'Juli','August','September','Oktober','November','Dezember'], monthNamesShort: ['Jan','Feb','Mar','Apr','Mai','Jun', 'Jul','Aug','Sep','Okt','Nov','Dez'], dayNames: ['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'], dayNamesShort: ['SON','MON','DIE','MIT','DON','FRE','SAM'], dayNamesMin: ['So','Mo','Di','Mi','Do','Fr','Sa'], weekHeader: 'KW', dateFormat: 'yyyy-mm-dd', firstDay: 1, isRTL: false, showMonthAfterYear: false, yearSuffix: '' }; $.datepicker.setDefaults($.datepicker.regional['de']); // diese Einstellung nun übernehmen if(maint == true) { $('#maint').dialog('open'); } });