Merge branch 'master' into fronkdev
This commit is contained in:
@@ -37,6 +37,7 @@ endforeach;
|
||||
|
||||
<script type="text/javascript"
|
||||
src="<?= self::getResourcePath() ?>assets/js/calendar/rrule/rrule.min.js?<?= $git_merge_ts ?>"></script>
|
||||
|
||||
<script type="text/javascript"
|
||||
src="<?= self::getResourcePath() ?>assets/js/calendar/moment/moment.min.js?<?= $git_merge_ts ?>"></script>
|
||||
<script type="text/javascript"
|
||||
@@ -57,6 +58,7 @@ endforeach;
|
||||
src="<?= self::getResourcePath() ?>assets/js/calendar/eventsource.min.js?<?= $git_merge_ts ?>"></script>
|
||||
<link href="<?= self::getResourcePath() ?>assets/css/datatables-std.css?<?= $git_merge_ts ?>" rel="stylesheet"
|
||||
type="text/css"/>
|
||||
|
||||
<!-- start page title -->
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
@@ -102,6 +104,7 @@ endforeach;
|
||||
class="btn btn-light btn-light-search top-search-filter"><i
|
||||
class="fa-duotone fa-solid fa-phone-volume fa-calendar-call fa-calendar-call-search"></i>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<?php if (!$rights) : ?>
|
||||
@@ -109,7 +112,14 @@ endforeach;
|
||||
<span class="font-18 font-weight-500">Du wurdest nicht für den Kalender frei geschalten.</span>
|
||||
</div>
|
||||
<?php die(); endif; ?>
|
||||
<div class="d-inline-block mr-1">
|
||||
|
||||
<button title="Excel Export"
|
||||
class="btn btn-light btn-xls-calendar">
|
||||
<i class="fa-duotone fa-solid fa-file-xls fa-xls-calendar"></i>
|
||||
|
||||
</div>
|
||||
</button>
|
||||
<div class="d-inline-block w-50 search-div" style="margin-top: -7px;">
|
||||
<select id="jumpevent" class="jumpevent"></select>
|
||||
</div>
|
||||
@@ -349,129 +359,219 @@ endforeach;
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal fade" id="EventModal" aria-labelledby="EventModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title font-18 ml-2" id="EventModalLabel"><i
|
||||
class="fa-duotone fa-solid fa-calendar-symbol"></i> <span>neuer Termin</span></h1>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row justify-content-center">
|
||||
|
||||
<div class="col-1">
|
||||
<label for="name" class="col-form-label fw-medium ">Betreff</label>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="mb-2">
|
||||
<input type="text" class="form-control is-require eventmodal-input" id="name">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="input-group mb-2">
|
||||
<span title="Erinnerung" class="input-group-text spanwidht">Typ</span>
|
||||
<select class="form-control form-select select-2" aria-label="Default select" id="type">
|
||||
<option value="1">Termin</option>
|
||||
<option value="2">IBN Xinon</option>
|
||||
<option value="3">IBN ESTMK</option>
|
||||
<option value="4">IBN SNOPP</option>
|
||||
<option value="5">Störung</option>
|
||||
<option value="6">Support Gespräch</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1 text-center">
|
||||
<i title="Normal" class="fa-duotone privacy-click fa-regular fa-unlock mt-1"></i>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="EventModal" aria-labelledby="EventModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title font-18 ml-2" id="EventModalLabel"><i
|
||||
class="fa-duotone fa-solid fa-calendar-symbol"></i> <span>neuer Termin</span></h1>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-1">
|
||||
<label for="location" class="col-form-label fw-medium ">Ort</label>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="mb-2">
|
||||
<input type="text" class="form-control eventmodal-input" id="location">
|
||||
<div class="modal-body">
|
||||
<div class="row justify-content-center">
|
||||
|
||||
<div class="col-1">
|
||||
<label for="name" class="col-form-label fw-medium ">Betreff</label>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="mb-2">
|
||||
<input type="text" class="form-control is-require eventmodal-input" id="name">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="input-group mb-2">
|
||||
<span title="Erinnerung" class="input-group-text spanwidht">Typ</span>
|
||||
<select class="form-control form-select select-2" aria-label="Default select" id="type">
|
||||
<option value="1">Termin</option>
|
||||
<option value="2">IBN Xinon</option>
|
||||
<option value="3">IBN ESTMK</option>
|
||||
<option value="4">IBN SNOPP</option>
|
||||
<option value="5">Störung</option>
|
||||
<option value="6">Support Gespräch</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1 text-center">
|
||||
<i title="Normal" class="fa-duotone privacy-click fa-regular fa-unlock mt-1"></i>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<div class="input-group mb-2">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-1">
|
||||
<label for="location" class="col-form-label fw-medium ">Ort</label>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="mb-2">
|
||||
<input type="text" class="form-control eventmodal-input" id="location">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<div class="input-group mb-2">
|
||||
<span title="Erinnerung" class="input-group-text spanwidht"><i
|
||||
class="fa-regular fa-eye"></i></span>
|
||||
<select class="form-control form-select" aria-label="Default select" id="busy">
|
||||
<option value="1">gebucht</option>
|
||||
<option value="0">frei</option>
|
||||
<option value="2">mit Vorbehalt</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row justify-content-center">
|
||||
|
||||
<div class="col-4">
|
||||
<div class="input-group mb-2">
|
||||
<span class="input-group-text spanwidht">Start</span>
|
||||
<input id="start-date" type="date" class="form-control is-require eventmodal-input"
|
||||
placeholder="Datum"
|
||||
aria-label="Datum"
|
||||
aria-describedby="Datum">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<input id="start-time" type="time" class="form-control is-require eventmodal-input"
|
||||
placeholder="Uhrzeit"
|
||||
aria-label="Uhrzeit"
|
||||
aria-describedby="Uhrzeit">
|
||||
</div>
|
||||
<div class="col-3 text-center">
|
||||
<div class="form-check" style="margin-top: 7px;">
|
||||
|
||||
<input class="form-check-input eventmodal-checkbox" type="checkbox" value=""
|
||||
id="allday"> <label class="form-check-label fw-medium checkbox-label" for="allday">
|
||||
Ganztägig
|
||||
</label>
|
||||
|
||||
<select class="form-control form-select" aria-label="Default select" id="busy">
|
||||
<option value="1">gebucht</option>
|
||||
<option value="0">frei</option>
|
||||
<option value="2">mit Vorbehalt</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="row justify-content-center">
|
||||
<div class="row justify-content-center">
|
||||
|
||||
<div class="col-4">
|
||||
<div class="input-group mb-2">
|
||||
<span class="input-group-text spanwidht">Ende</span>
|
||||
<input id="end-date" type="date" class="form-control is-require eventmodal-input"
|
||||
placeholder="Datum"
|
||||
aria-label="Datum"
|
||||
aria-describedby="Datum">
|
||||
<div class="col-4">
|
||||
<div class="input-group mb-2">
|
||||
<span class="input-group-text spanwidht">Start</span>
|
||||
<input id="start-date" type="date" class="form-control is-require eventmodal-input"
|
||||
placeholder="Datum"
|
||||
aria-label="Datum"
|
||||
aria-describedby="Datum">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<input id="start-time" type="time" class="form-control is-require eventmodal-input"
|
||||
placeholder="Uhrzeit"
|
||||
aria-label="Uhrzeit"
|
||||
aria-describedby="Uhrzeit">
|
||||
</div>
|
||||
<div class="col-2 text-center">
|
||||
<div class="form-check" style="margin-top: 7px;">
|
||||
|
||||
<input class="form-check-input eventmodal-checkbox" type="checkbox" value=""
|
||||
id="allday"> <label class="form-check-label fw-medium checkbox-label"
|
||||
for="allday">
|
||||
Ganztägig
|
||||
</label>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-2 text-right">
|
||||
<div class="form-check" style="margin-top: 7px;">
|
||||
<input class="form-check-input eventmodal-checkbox" type="checkbox" value=""
|
||||
id="recurringCheck">
|
||||
<label class="form-check-label fw-medium checkbox-label" for="recurringCheck">
|
||||
Serientermin
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<input id="end-time" type="time" class="form-control is-require eventmodal-input"
|
||||
placeholder="Uhrzeit"
|
||||
aria-label="Uhrzeit"
|
||||
aria-describedby="Uhrzeit">
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="input-group mb-2">
|
||||
<div class="row justify-content-center">
|
||||
|
||||
<div class="col-4">
|
||||
<div class="input-group mb-2">
|
||||
<span class="input-group-text spanwidht">Ende</span>
|
||||
<input id="end-date" type="date" class="form-control is-require eventmodal-input"
|
||||
placeholder="Datum"
|
||||
aria-label="Datum"
|
||||
aria-describedby="Datum">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<input id="end-time" type="time" class="form-control is-require eventmodal-input"
|
||||
placeholder="Uhrzeit"
|
||||
aria-label="Uhrzeit"
|
||||
aria-describedby="Uhrzeit">
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<div class="input-group mb-2">
|
||||
<span title="Erinnerung" class="input-group-text spanwidht"><i
|
||||
class="fa-regular fa-bell"></i></span>
|
||||
<select class="form-control form-select select2" aria-label="Default select" id="reminder">
|
||||
<option value="NULL">Keine</option>
|
||||
<option value="0">Zum Termin</option>
|
||||
<option value="300">5 Minuten</option>
|
||||
<option value="600">10 Minuten</option>
|
||||
<option value="900">15 Minuten</option>
|
||||
<option value="1800">30 Minuten</option>
|
||||
<option value="3600">1 Stunde</option>
|
||||
<option value="86400">1 Tag</option>
|
||||
<option value="604800">1 Woche</option>
|
||||
<select class="form-control form-select select2" aria-label="Default select"
|
||||
id="reminder">
|
||||
<option value="NULL">Keine</option>
|
||||
<option value="0">Zum Termin</option>
|
||||
<option value="300">5 Minuten</option>
|
||||
<option value="600">10 Minuten</option>
|
||||
<option value="900">15 Minuten</option>
|
||||
<option value="1800">30 Minuten</option>
|
||||
<option value="3600">1 Stunde</option>
|
||||
<option value="86400">1 Tag</option>
|
||||
<option value="604800">1 Woche</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Serientermin-Checkbox und zugehörige RRule-Optionen -->
|
||||
<div class="row" id="recurring-settings" style="display:none;">
|
||||
<div class="col-1"></div>
|
||||
<div class="col-3"
|
||||
">
|
||||
<!-- Frequenz: Täglich / Wöchentlich / Monatlich / Jährlich -->
|
||||
<div class="mb-2">
|
||||
<label for="rrule-frequency" class="col-form-label fw-medium">Wiederholungstyp</label>
|
||||
<select class="form-control" id="rrule-frequency">
|
||||
<option value="">Bitte wählen</option>
|
||||
<option value="DAILY">Täglich</option>
|
||||
<option value="WEEKLY">Wöchentlich</option>
|
||||
<option value="MONTHLY">Monatlich</option>
|
||||
<option value="YEARLY">Jährlich</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label for="rrule-count" class="col-form-label fw-medium">Wiederhol. (optional)</label>
|
||||
<input type="number" min="1" class="form-control" id="rrule-count" placeholder="z.B. 10">
|
||||
</div>
|
||||
|
||||
<!-- Enddatum der Serie (optional) -->
|
||||
<div class="mb-2">
|
||||
<label for="rrule-until" class="col-form-label fw-medium">Ende (optional)</label>
|
||||
<input type="date" class="form-control" id="rrule-until">
|
||||
</div>
|
||||
</div>
|
||||
<!-- Wöchentliche Optionen (z.B. jeden Dienstag, jeden Freitag + Montag) -->
|
||||
<div class="col-7">
|
||||
<div class="mb-2" id="weekly-options" style="display:none;">
|
||||
<label for="rrule-byweekday" class="col-form-label fw-medium">Wochentag(e)</label>
|
||||
<select class="form-control" id="rrule-byweekday" multiple>
|
||||
<option value="MO">Montag</option>
|
||||
<option value="TU">Dienstag</option>
|
||||
<option value="WE">Mittwoch</option>
|
||||
<option value="TH">Donnerstag</option>
|
||||
<option value="FR">Freitag</option>
|
||||
<option value="SA">Samstag</option>
|
||||
<option value="SU">Sonntag</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-2" id="monthly-options" style="display:none;">
|
||||
<label class="col-form-label fw-medium">Monatliches Muster</label>
|
||||
<select class="form-control" id="monthly-type">
|
||||
<option value="BYMONTHDAY">Jeden X. Tag des Monats</option>
|
||||
<option value="BYSETPOS">Jeden X. [Wochentag] im Monat</option>
|
||||
</select>
|
||||
<div class=" mt-2 row" id="monthly-day-select">
|
||||
<label class="mr-2 col-form-label fw-medium col-2">Tag:</label>
|
||||
<select class="form-control w-auto col-3" id="rrule-bymonthday">
|
||||
<!-- Auswahl 1–31 -->
|
||||
<?php for ($i = 1; $i <= 31; $i++): ?>
|
||||
<option value="<?= $i ?>"><?= $i ?></option>
|
||||
<?php endfor; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mt-2 row" id="monthly-setpos-select" style="display:none;">
|
||||
<label class="mr-2 col-2 col-form-label fw-medium">Position:</label>
|
||||
<select class="form-control col-3 w-auto" id="rrule-setpos">
|
||||
<option value="1">Erster</option>
|
||||
<option value="2">Zweiter</option>
|
||||
<option value="3">Dritter</option>
|
||||
<option value="4">Vierter</option>
|
||||
<option value="-1">Letzter</option>
|
||||
</select>
|
||||
<label class="mr-2 col-2 ml-3 col-form-label fw-medium text-center">Tag:</label>
|
||||
<select class="form-control col-3 w-auto" id="rrule-bynweekday">
|
||||
<option value="MO">Montag</option>
|
||||
<option value="TU">Dienstag</option>
|
||||
<option value="WE">Mittwoch</option>
|
||||
<option value="TH">Donnerstag</option>
|
||||
<option value="FR">Freitag</option>
|
||||
<option value="SA">Samstag</option>
|
||||
<option value="SU">Sonntag</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -570,6 +670,7 @@ endforeach;
|
||||
</div>
|
||||
<div class="d-inline-block" id="customer-info-check-info"></div>
|
||||
</div>
|
||||
|
||||
<div id="relContainer2" style="position:relative">
|
||||
<select id="customer" class="jumpevent"></select>
|
||||
</div>
|
||||
@@ -651,13 +752,16 @@ endforeach;
|
||||
</div>
|
||||
|
||||
<div id="output"></div>
|
||||
<script type="text/javascript" src="<?= self::getResourcePath() ?>plugins/select2/js/i18n/de.js?<?= $git_merge_ts ?>"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>plugins/tinymce/tinymce.min.js?<?= $git_merge_ts ?>"></script>
|
||||
<script type="text/javascript"
|
||||
src="<?= self::getResourcePath() ?>plugins/select2/js/i18n/de.js?<?= $git_merge_ts ?>"></script>
|
||||
<script type="text/javascript"
|
||||
src="<?= self::getResourcePath() ?>plugins/tinymce/tinymce.min.js?<?= $git_merge_ts ?>"></script>
|
||||
|
||||
<script>
|
||||
let requestUrl = "<?= self::getUrl("Calendar", "api", ['do' => 'getCalendarEvents']) ?>";
|
||||
let requestEventUrl = "<?= self::getUrl("Calendar", "api", ['do' => 'getCalendarEvent']) ?>";
|
||||
let requestEventSearchURL = "<?= self::getUrl("Calendar", "api", ['do' => 'searchCalendarEvents']) ?>";
|
||||
let requestgenerateEventsxlsx = "<?= self::getUrl("Calendar", "api", ['do' => 'generateCalendarEventsXlsx']) ?>";
|
||||
let requestEventAttachmentUrl = "<?= self::getUrl("Calendar", "api", ['do' => 'getCalendarEventAttachment']) ?>";
|
||||
let requestEventAttachmentTmpUrl = "<?= self::getUrl("Calendar", "api", ['do' => 'getCalendarEventAttachmentTmp']) ?>";
|
||||
let requestEventAttachmentTmpDeleteUrl = "<?= self::getUrl("Calendar", "api", ['do' => 'deleteCalendarEventAttachmentTmp']) ?>";
|
||||
@@ -728,7 +832,6 @@ endforeach;
|
||||
endforeach; ?>
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/javascript"
|
||||
src="<?= self::getResourcePath() ?>js/pages/Calendar/View.js?<?= $git_merge_ts ?>"></script>
|
||||
|
||||
|
||||
@@ -184,7 +184,7 @@ $pagination_entity_name = "Zustimmungserklärungen";
|
||||
'key' => 'inspection_planner',
|
||||
'header' => 'Begehung Planer durchgeführt',
|
||||
'icon' => 'fas fa-clipboard-check',
|
||||
'denominator' => $stats['building'] + $stats['street'],
|
||||
'denominator' => $stats['building'],
|
||||
'color' => '#28a745'
|
||||
],
|
||||
[
|
||||
@@ -198,7 +198,7 @@ $pagination_entity_name = "Zustimmungserklärungen";
|
||||
'key' => 'conduit_installed_ftu',
|
||||
'header' => 'Leerrohr bis HAK',
|
||||
'icon' => 'fas fa-road',
|
||||
'denominator' => $stats['street'],
|
||||
'denominator' => $stats['building'],
|
||||
'color' => '#f5b902'
|
||||
],
|
||||
[
|
||||
|
||||
@@ -142,6 +142,12 @@
|
||||
$('body').on('click', '#bmd-export-nlz', function () {
|
||||
window.open('<?= self::getUrl("TimerecordingBilling", "api", ['do' => 'generatebmdexportnlz']) ?>&month=' + $('#month').data('month'), '_blank');
|
||||
});
|
||||
$('body').on('click', '#open-workdays', function () {
|
||||
window.open('<?= self::getUrl("TimerecordingBilling", "api", ['do' => 'generateopenworkdays']) ?>&month=' + $('#month').data('month'), '_blank');
|
||||
});
|
||||
|
||||
|
||||
|
||||
$('body').on('click', '#month-complete', function () {
|
||||
if (confirm('Monat ' + $('#month').data('month') + ' wirklich abschließen?')) {
|
||||
$('#datatable_wrapper').hide();
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if($me->is(["Admin", "netowner", "salespartner"]) && ($me->is("employee") || $me->can(["Fibu", "Billing", "Preorderpricing", "Preorderbilling"]) || $me->address_id == 2187)): ?>
|
||||
<?php if($me->is(["Admin", "netowner", "salespartner"]) && ($me->is("employee") || $me->can(["Fibu", "Billing", "Preorderpricing", "Preorderbilling"])) || in_array($me->address_id, [1,209,5908,2187])): ?>
|
||||
<li class="has-submenu mobile-hide">
|
||||
<a href="#">
|
||||
<i class="fas fa-fw fa-money-from-bracket"></i> Backoffice <div class="arrow-down"></div>
|
||||
|
||||
@@ -75,13 +75,13 @@ class ADBHausnummer extends mfBaseModel {
|
||||
}
|
||||
|
||||
public function getBuildingType() {
|
||||
$rimo_type = strtolower($this->rimo_type);
|
||||
$rimo_type = $this->rimo_type === NULL ? '' : strtolower($this->rimo_type);
|
||||
|
||||
if(array_key_exists($this->rimo_type, TT_ADB_GDA_TYPES)) {
|
||||
return TT_ADB_GDA_TYPES[$this->rimo_type];
|
||||
}
|
||||
|
||||
$gdaeigenschaft = strtolower($this->gdaeigenschaft);
|
||||
$gdaeigenschaft = $this->gdaeigenschaft === NULL ? '' : strtolower($this->gdaeigenschaft);
|
||||
if(array_key_exists($gdaeigenschaft, TT_ADB_GDA_TYPES)) {
|
||||
return TT_ADB_GDA_TYPES[$gdaeigenschaft];
|
||||
}
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
<?php
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Alignment;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Border;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Color;
|
||||
use PhpOffice\PhpSpreadsheet\Helper\Html;
|
||||
|
||||
class CalendarController extends mfBaseController
|
||||
{
|
||||
|
||||
@@ -45,6 +52,11 @@ class CalendarController extends mfBaseController
|
||||
$calendarEvents = CalendarModel::searchCalendarEvents($r);
|
||||
return $calendarEvents;
|
||||
die();
|
||||
case "generateCalendarEventsXlsx" :
|
||||
$r = $this->request;
|
||||
$this->generateXlsx($r);
|
||||
return $calendarEvents;
|
||||
die();
|
||||
case "getCalendarEventAttachment" :
|
||||
$r = $this->request;
|
||||
$id = ($r->id);
|
||||
@@ -109,7 +121,10 @@ class CalendarController extends mfBaseController
|
||||
die();
|
||||
case "insertCalendarEvent":
|
||||
$r = $this->request;
|
||||
$calendarEvents = CalendarModel::insertCalendarEvent($r, $this->me);
|
||||
if ($r->rruleData) {
|
||||
$rrules = json_encode($this->generateGraphRecurrence($r->rruleData, $r->start));
|
||||
}
|
||||
$calendarEvents = CalendarModel::insertCalendarEvent($r, $this->me, $rrules);
|
||||
if ($r->customer_info_check) {
|
||||
if ($r->customer_info_type == 1) {
|
||||
$body = $r->customer_info_text;
|
||||
@@ -389,6 +404,186 @@ class CalendarController extends mfBaseController
|
||||
die();
|
||||
}
|
||||
|
||||
private function generateGraphRecurrence($data, $startDate)
|
||||
{
|
||||
$graph = [
|
||||
'pattern' => [],
|
||||
'range' => []
|
||||
];
|
||||
$freq = strtoupper($data['rrule_frequency']);
|
||||
switch ($freq) {
|
||||
case 'DAILY':
|
||||
$graph['pattern']['type'] = 'daily';
|
||||
break;
|
||||
case 'WEEKLY':
|
||||
$graph['pattern']['type'] = 'weekly';
|
||||
break;
|
||||
case 'MONTHLY':
|
||||
if (!empty($data['monthly_type']) && $data['monthly_type'] === 'BYMONTHDAY') {
|
||||
$graph['pattern']['type'] = 'absoluteMonthly';
|
||||
$graph['pattern']['dayOfMonth'] = intval($data['rrule_bymonthday']);
|
||||
} elseif (!empty($data['monthly_type']) && $data['monthly_type'] === 'BYSETPOS') {
|
||||
$graph['pattern']['type'] = 'relativeMonthly';
|
||||
// Mapping: 1 => first, 2 => second, 3 => third, 4 => fourth, -1 => last
|
||||
$setpos = intval($data['rrule_setpos']);
|
||||
$indexMapping = [
|
||||
1 => 'first',
|
||||
2 => 'second',
|
||||
3 => 'third',
|
||||
4 => 'fourth',
|
||||
-1 => 'last'
|
||||
];
|
||||
$graph['pattern']['index'] = isset($indexMapping[$setpos]) ? $indexMapping[$setpos] : 'first';
|
||||
if (!empty($data['rrule_bynweekday'])) {
|
||||
$graph['pattern']['daysOfWeek'] = [$this->convertDayToGraph(strtoupper($data['rrule_bynweekday']))];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'YEARLY':
|
||||
$graph['pattern']['type'] = 'absoluteYearly';
|
||||
break;
|
||||
default:
|
||||
$graph['pattern']['type'] = 'daily';
|
||||
}
|
||||
|
||||
$graph['pattern']['interval'] = 1;
|
||||
|
||||
if ($freq === 'WEEKLY' && !empty($data['rrule-byweekday'])) {
|
||||
$days = is_array($data['rrule-byweekday']) ? $data['rrule-byweekday'] : [$data['rrule-byweekday']];
|
||||
$graphDays = [];
|
||||
foreach ($days as $day) {
|
||||
$graphDays[] = $this->convertDayToGraph(strtoupper($day));
|
||||
}
|
||||
$graph['pattern']['daysOfWeek'] = $graphDays;
|
||||
}
|
||||
|
||||
|
||||
$graph['range']['startDate'] = $startDate;
|
||||
if (!empty($data['rrule_until'])) {
|
||||
$graph['range']['endDate'] = $data['rrule_until'];
|
||||
$graph['range']['type'] = 'endDate';
|
||||
} elseif (!empty($data['rrule_count'])) {
|
||||
$graph['range']['numberOfOccurrences'] = intval($data['rrule_count']);
|
||||
$graph['range']['type'] = 'numbered';
|
||||
} else {
|
||||
$graph['range']['type'] = 'noEnd';
|
||||
}
|
||||
return $graph;
|
||||
}
|
||||
|
||||
|
||||
private function convertDayToGraph($dayAbbrev)
|
||||
{
|
||||
$mapping = [
|
||||
'MO' => 'monday',
|
||||
'TU' => 'tuesday',
|
||||
'WE' => 'wednesday',
|
||||
'TH' => 'thursday',
|
||||
'FR' => 'friday',
|
||||
'SA' => 'saturday',
|
||||
'SU' => 'sunday'
|
||||
];
|
||||
return isset($mapping[$dayAbbrev]) ? $mapping[$dayAbbrev] : $dayAbbrev;
|
||||
}
|
||||
|
||||
private function generateXlsx($r)
|
||||
{
|
||||
$calendarEvents = json_decode(CalendarModel::getCalendarEvents($this->me->id, 0, $r, true), true);
|
||||
$eventTypes = CalendarModel::$eventTypes;
|
||||
$xls = new Spreadsheet();
|
||||
$sheet = $xls->getActiveSheet();
|
||||
$writer = new Xlsx($xls);
|
||||
$sheet->getStyle('A1:AN1')->getFont()->setBold(true);
|
||||
$sheet->getStyle('A:E')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
|
||||
$sheet->getStyle('I:L')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
|
||||
$sheet->getColumnDimension('A')->setWidth(25);
|
||||
$sheet->getColumnDimension('B')->setWidth(15);
|
||||
$sheet->getColumnDimension('C')->setWidth(10);
|
||||
$sheet->getColumnDimension('D')->setWidth(15);
|
||||
$sheet->getColumnDimension('E')->setWidth(10);
|
||||
$sheet->getColumnDimension('F')->setWidth(40);
|
||||
$sheet->getColumnDimension('G')->setWidth(40);
|
||||
$sheet->getColumnDimension('H')->setWidth(20);
|
||||
$sheet->getColumnDimension('I')->setWidth(10);
|
||||
$sheet->getColumnDimension('J')->setWidth(10);
|
||||
$sheet->getColumnDimension('K')->setWidth(15);
|
||||
$sheet->getColumnDimension('L')->setWidth(15);
|
||||
|
||||
|
||||
$sheet->setCellValue([1, 1], 'Kalender')
|
||||
->setCellValue([2, 1], 'Startdatum')
|
||||
->setCellValue([3, 1], 'Startzeit')
|
||||
->setCellValue([4, 1], 'Enddatum')
|
||||
->setCellValue([5, 1], 'Endzeit')
|
||||
->setCellValue([6, 1], 'Betreff')
|
||||
->setCellValue([7, 1], 'Ort')
|
||||
->setCellValue([8, 1], 'Beschreibung')
|
||||
->setCellValue([9, 1], 'Termintyp')
|
||||
->setCellValue([10, 1], 'Privat')
|
||||
->setCellValue([11, 1], 'Sichtbarkeit')
|
||||
->setCellValue([12, 1], 'Organisator')
|
||||
|
||||
;
|
||||
$counter = 2;
|
||||
foreach ($calendarEvents['data'] as $event) {
|
||||
if ($event['privateflag']['privateflag']) {
|
||||
$event['privateflag']['privateflag'] = "Ja";
|
||||
} else {
|
||||
$event['privateflag']['privateflag'] = "Nein";
|
||||
}
|
||||
if ($event['isorganizer']['isorganizer']) {
|
||||
$event['isorganizer']['isorganizer'] = "Ja";
|
||||
} else {
|
||||
$event['isorganizer']['isorganizer'] = "Nein";
|
||||
}
|
||||
if ($event['busy']['busy'] == 1) {
|
||||
$event['busy']['busy'] = "gebucht";
|
||||
} else if ($event['busy']['busy'] == 2) {
|
||||
$event['busy']['busy'] = "mit Vorbehalt";
|
||||
} else {
|
||||
$event['busy']['busy'] = "frei";
|
||||
}
|
||||
|
||||
if ($event['allDay']['allDay'] == 0) {
|
||||
$starttime = date("H:i", strtotime($event['cstart']['cstart']));
|
||||
$endtime = date("H:i", strtotime($event['cend']['cend']));
|
||||
$startdate = date("d.m.Y", strtotime($event['cstart']['cstart']));
|
||||
$enddate = date("d.m.Y", strtotime($event['cend']['cend']));
|
||||
} else {
|
||||
$starttime = "";
|
||||
$startdate = date("d.m.Y", strtotime($event['cstart']['cstart']));
|
||||
$endtime = "";
|
||||
$enddate = date("d.m.Y", strtotime($event['cend']['cend']) - 7500);
|
||||
}
|
||||
if ($event['event_type']['event_type'] != "") {
|
||||
$helper = new Html();
|
||||
$richText = $helper->toRichTextObject($event['description']['description']);
|
||||
$calendarType = $eventTypes[$event['event_type']['event_type']];
|
||||
$sheet->setCellValue([1, $counter], $event['calendar_name']['calendar_name'])
|
||||
->setCellValue([2, $counter], $startdate)
|
||||
->setCellValue([3, $counter], $starttime)
|
||||
->setCellValue([4, $counter], $enddate)
|
||||
->setCellValue([5, $counter], $endtime)
|
||||
->setCellValue([6, $counter], $event['ccategory']['ccategory'])
|
||||
->setCellValue([7, $counter], $event['location']['location'])
|
||||
->setCellValue([8, $counter], $richText)
|
||||
->setCellValue([9, $counter], $calendarType)
|
||||
->setCellValue([10, $counter], $event['privateflag']['privateflag'])
|
||||
->setCellValue([11, $counter], $event['busy']['busy'])
|
||||
->setCellValue([12, $counter], $event['isorganizer']['isorganizer'])
|
||||
;
|
||||
$counter++;
|
||||
}
|
||||
}
|
||||
header("Content-type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||
|
||||
header('Content-disposition: attachment; filename="Kalender-' . date('Y-m-d_H-i-s') . '-' . uniqid() . '.xlsx"');
|
||||
$writer->save('php://output');
|
||||
exit;
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected function indexAction()
|
||||
{
|
||||
$this->layout()->setTemplate("Calendar/Index");
|
||||
|
||||
@@ -32,6 +32,15 @@ class CalendarModel
|
||||
'690', // Spusu
|
||||
'699' // 3 (Drei)
|
||||
);
|
||||
|
||||
public static $eventTypes = array(
|
||||
1 => 'Termin',
|
||||
2 => 'IBN Xinon',
|
||||
3 => 'IBN ESTMK',
|
||||
4 => 'IBN Snopp',
|
||||
5 => 'Störung',
|
||||
6 => 'Support Gespräch'
|
||||
);
|
||||
public static $standardCalendarColors = [
|
||||
'#b3d5f3', '#d0e2c0', '#bac2d4', '#c6d4c0', '#e3e3e3',
|
||||
'#acdce5', '#cdb6c0', '#aae0e1', '#d9d9d9', '#d9e5d5',
|
||||
@@ -75,9 +84,13 @@ class CalendarModel
|
||||
{
|
||||
$unicode_map = [
|
||||
'\u00f6' => 'ö',
|
||||
'u00f6' => 'ö',
|
||||
'\u00fc' => 'ü',
|
||||
'u00fc' => 'ü',
|
||||
'\u00e4' => 'ä',
|
||||
'u00e4' => 'ä',
|
||||
'\u00df' => 'ß',
|
||||
'u00df' => 'ß',
|
||||
'\u00e9' => 'é',
|
||||
'\u00e0' => 'à',
|
||||
'\u00f3' => 'ó',
|
||||
@@ -145,7 +158,7 @@ class CalendarModel
|
||||
die();
|
||||
}
|
||||
|
||||
public static function getCalendarEvents($me, $id = 0, $r = 0)
|
||||
public static function getCalendarEvents($me, $id = 0, $r = 0, $returnvalues = false)
|
||||
{
|
||||
$rrulefreq = array('daily' => 'DAILY', 'weekly' => 'WEEKLY', 'relativeMonthly' => 'MONTHLY', 'yearly' => 'YEARLY', 'absoluteMonthly' => 'absoluteMonthly');
|
||||
$calendar = self::search(array("user_id" => $me));
|
||||
@@ -192,7 +205,7 @@ class CalendarModel
|
||||
}
|
||||
|
||||
|
||||
$sql = "SELECT `cal_events`.id,`cal_events`.categories, uuid, calendar_id, `cal_events`.user_id, start_time, end_time, timezone, all_day_event, `cal_events`.name,`cal_calendars`.name calendar_name, description, location, repeat_end_time, reminder, ctime,cname, mtime,mname, muser_id, busy, status, resource_event_id, private, rrule, `cal_events`.background, `cal_events`.files_folder_id, read_only, category_id, exception_for_event_id, recurrence_id, is_organizer,event_type,busy,recurrence,rrule_events FROM cal_events INNER JOIN `cal_calendars` ON (`cal_calendars`.`id`=`cal_events`.`calendar_id`) WHERE 1=1 $where ";
|
||||
$sql = "SELECT `cal_events`.id,`cal_events`.categories, uuid, calendar_id, `cal_events`.user_id, start_time, end_time, timezone, all_day_event, `cal_events`.name,`cal_calendars`.name calendar_name, description, location, repeat_end_time, reminder, ctime,cname, mtime,mname, muser_id, busy, status, resource_event_id, private, rrule, `cal_events`.background, `cal_events`.files_folder_id, read_only, category_id, exception_for_event_id, recurrence_id, is_organizer,event_type,busy,recurrence,rrule_events FROM cal_events INNER JOIN `cal_calendars` ON (`cal_calendars`.`id`=`cal_events`.`calendar_id`) WHERE 1=1 $where ORDER BY start_time DESC";
|
||||
|
||||
$res = $dbcal->query($sql);
|
||||
if ($dbcal->num_rows($res)) {
|
||||
@@ -380,7 +393,7 @@ WHERE `TimerecordingCategory`.`hourday`!='1' AND `TimerecordingCategory`.`hourda
|
||||
|
||||
|
||||
$json = json_encode($json);
|
||||
if ($id == 0) {
|
||||
if ($id == 0 && $returnvalues == false) {
|
||||
echo trim($json);
|
||||
die();
|
||||
} else {
|
||||
@@ -445,13 +458,15 @@ WHERE `TimerecordingCategory`.`hourday`!='1' AND `TimerecordingCategory`.`hourda
|
||||
}
|
||||
$Allcalendar['Daniel Whoknows'] = 2;
|
||||
$Allcalendar['Stefan Plaschg'] = 26;
|
||||
$res = $dbcal->select("cal_events", "id, uuid, calendar_id, user_id, start_time, end_time, timezone, all_day_event, name, description, location, repeat_end_time, reminder, ctime, mtime, muser_id, busy, status, resource_event_id, private, rrule, background, files_folder_id, read_only, category_id, exception_for_event_id, recurrence_id, is_organizer,event_type,customer,customer_info,customer_info_send,customer_info_reminder,busy,attendees,organizer,is_organizer,accepted", "1=1 AND id='" . $id . "' ORDER BY id");
|
||||
$res = $dbcal->select("cal_events", "id, uuid, calendar_id, user_id, start_time, end_time, timezone, all_day_event, name, description, location, repeat_end_time, reminder, ctime, mtime, muser_id, busy, status, resource_event_id, private, rrule, background, files_folder_id, read_only, category_id, exception_for_event_id, recurrence_id, recurrence, is_organizer,event_type,customer,customer_info,customer_info_send,customer_info_reminder,busy,attendees,organizer,is_organizer,accepted", "1=1 AND id='" . $id . "' ORDER BY id");
|
||||
if ($dbcal->num_rows($res)) {
|
||||
$data = $dbcal->fetch_array($res);
|
||||
|
||||
|
||||
if ($data['recurrence']) {
|
||||
$recurrence = self::generateDataRecurrence(json_decode($data['recurrence'], true));
|
||||
} else {
|
||||
$recurrence = false;
|
||||
}
|
||||
$attachment = 0;
|
||||
|
||||
if ($data['all_day_event'] == 1) {
|
||||
$starttime = date("Y-m-d", $data['start_time']);
|
||||
$endtime = date("Y-m-d", $data['end_time']);
|
||||
@@ -517,6 +532,7 @@ WHERE `TimerecordingCategory`.`hourday`!='1' AND `TimerecordingCategory`.`hourda
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$data['accepted'] && $data['busy'] == 1) {
|
||||
$data['accepted']['ok'] = 1;
|
||||
$data['accepted'] = json_encode($data['accepted']);
|
||||
@@ -541,8 +557,9 @@ WHERE `TimerecordingCategory`.`hourday`!='1' AND `TimerecordingCategory`.`hourda
|
||||
'privateflag' => array('privateflag' => $data['private'], 'order' => $data['private']),
|
||||
'isorganizer' => array('isorganizer' => $data['is_organizer']),
|
||||
'attendees' => array('attendees' => json_encode($AttendeeArray)),
|
||||
'organizer' => array('organizer' => $data['organizer']),
|
||||
'organizer' => array('organizer' => self::replace_unicode_sequences($data['organizer'])),
|
||||
'accepted' => array('accepted' => $data['accepted']),
|
||||
'recurrence' => array('recurrence' => $recurrence),
|
||||
'attachment' => array('attachment' => $attachment, 'order' => $attachment),
|
||||
'attachments' => array('attachments' => $attachments, 'order' => $attachments)
|
||||
);
|
||||
@@ -814,7 +831,7 @@ WHERE `TimerecordingCategory`.`hourday`!='1' AND `TimerecordingCategory`.`hourda
|
||||
$db->insert("TheTool_CalendarQueue", $data);
|
||||
}
|
||||
|
||||
public static function insertCalendarEvent($r, $me)
|
||||
public static function insertCalendarEvent($r, $me, $rrules = "")
|
||||
{
|
||||
$description = ($r->description);
|
||||
$attachments = ($r->attachments);
|
||||
@@ -844,7 +861,10 @@ WHERE `TimerecordingCategory`.`hourday`!='1' AND `TimerecordingCategory`.`hourda
|
||||
$microsoft_user_id = $result->ms_user_id;
|
||||
|
||||
}
|
||||
|
||||
if (!$allday)
|
||||
{
|
||||
$allday=0;
|
||||
}
|
||||
if ($reminder == 'NULL') {
|
||||
$reminder = NULL;
|
||||
}
|
||||
@@ -877,7 +897,7 @@ WHERE `TimerecordingCategory`.`hourday`!='1' AND `TimerecordingCategory`.`hourda
|
||||
$customer_info_send = NULL;
|
||||
}
|
||||
|
||||
$dataarray = array("start_time" => $start, 'end_time' => $end, 'name' => $title, 'description' => $description, 'location' => $location, 'calendar_id' => $user_id, 'uuid' => "a5eb79b3-fca7-5378-a09e-" . rand(100000000000, 999999999999), 'user_id' => 1, 'timezone' => 'Europe/Amsterdam', 'all_day_event' => 0, 'repeat_end_time' => 0, 'reminder' => $reminder, 'ctime' => time(), 'cname' => $me->name, 'mtime' => time(), 'mname' => $me->name, 'user_id' => 1, 'busy' => $busy, 'status' => 'CONFIRMED', 'resource_event_id' => 0, 'private' => $privateflag, 'rrule' => '', 'background' => 'EBF1E2', 'files_folder_id' => 0, 'read_only' => 0,'categories'=>$categories, 'exception_for_event_id' => 0, 'recurrence_id' => 0, 'is_organizer' => 1, 'event_type' => $type, 'customer' => $customer, 'customer_info' => $customer_info, 'customer_info_send' => $customer_info_send, 'customer_info_reminder' => $customer_info_reminder_check);
|
||||
$dataarray = array("start_time" => $start, 'end_time' => $end, 'name' => $title, 'description' => $description, 'location' => $location, 'calendar_id' => $user_id, 'uuid' => "a5eb79b3-fca7-5378-a09e-" . rand(100000000000, 999999999999), 'user_id' => 1, 'timezone' => 'Europe/Amsterdam', 'all_day_event' => $allday, 'repeat_end_time' => 0, 'reminder' => $reminder, 'ctime' => time(), 'cname' => $me->name, 'mtime' => time(), 'mname' => $me->name, 'user_id' => 1, 'busy' => $busy, 'status' => 'CONFIRMED', 'resource_event_id' => 0, 'private' => $privateflag, 'rrule' => '', 'background' => 'EBF1E2', 'files_folder_id' => 0, 'read_only' => 0, 'categories' => $categories, 'exception_for_event_id' => 0, 'recurrence_id' => 0, 'is_organizer' => 1, 'event_type' => $type, 'customer' => $customer, 'customer_info' => $customer_info, 'customer_info_send' => $customer_info_send, 'customer_info_reminder' => $customer_info_reminder_check);
|
||||
|
||||
$db->insert("cal_events", $dataarray);
|
||||
$event_id = $dataarray['uuid'];
|
||||
@@ -898,6 +918,9 @@ WHERE `TimerecordingCategory`.`hourday`!='1' AND `TimerecordingCategory`.`hourda
|
||||
if ($attendees)
|
||||
$dataarray['attendees'] = $attendees;
|
||||
$dataarray['attachments'] = $attachments;
|
||||
if ($rrules) {
|
||||
$dataarray['rrule'] = $rrules;
|
||||
}
|
||||
$json_data = json_encode($dataarray);
|
||||
|
||||
$data = [];
|
||||
@@ -972,6 +995,87 @@ WHERE `TimerecordingCategory`.`hourday`!='1' AND `TimerecordingCategory`.`hourda
|
||||
die();
|
||||
}
|
||||
|
||||
public static function generateDataRecurrence($graph)
|
||||
{
|
||||
$data = [];
|
||||
switch ($graph['pattern']['type']) {
|
||||
case 'daily':
|
||||
$data['rrule_frequency'] = 'DAILY';
|
||||
break;
|
||||
case 'weekly':
|
||||
$data['rrule_frequency'] = 'WEEKLY';
|
||||
if (!empty($graph['pattern']['daysOfWeek'])) {
|
||||
$data['rrule_byweekday'] = array_map(function ($day) {
|
||||
return self::convertGraphToDay($day);
|
||||
}, $graph['pattern']['daysOfWeek']);
|
||||
}
|
||||
break;
|
||||
case 'absoluteMonthly':
|
||||
$data['rrule_frequency'] = 'MONTHLY';
|
||||
$data['monthly_type'] = 'BYMONTHDAY';
|
||||
$data['rrule_bymonthday'] = intval($graph['pattern']['dayOfMonth']);
|
||||
break;
|
||||
case 'relativeMonthly':
|
||||
$data['rrule_frequency'] = 'MONTHLY';
|
||||
$data['monthly_type'] = 'BYSETPOS';
|
||||
$indexMapping = [
|
||||
'first' => 1,
|
||||
'second' => 2,
|
||||
'third' => 3,
|
||||
'fourth' => 4,
|
||||
'last' => -1
|
||||
];
|
||||
$index = isset($graph['pattern']['index']) ? $graph['pattern']['index'] : 'first';
|
||||
$data['rrule_setpos'] = isset($indexMapping[$index]) ? $indexMapping[$index] : 1;
|
||||
if (!empty($graph['pattern']['daysOfWeek'])) {
|
||||
$data['rrule_bynweekday'] = self::convertGraphToDay($graph['pattern']['daysOfWeek'][0]);
|
||||
}
|
||||
break;
|
||||
case 'absoluteYearly':
|
||||
$data['rrule_frequency'] = 'YEARLY';
|
||||
break;
|
||||
default:
|
||||
$data['rrule_frequency'] = 'DAILY';
|
||||
}
|
||||
|
||||
// Falls benötigt, kann der Start-Datum-Wert übernommen werden.
|
||||
if (!empty($graph['range']['startDate'])) {
|
||||
$data['startDate'] = $graph['range']['startDate'];
|
||||
}
|
||||
|
||||
// Wiederherstellen des Endbereichs
|
||||
if (!empty($graph['range']['type'])) {
|
||||
switch ($graph['range']['type']) {
|
||||
case 'endDate':
|
||||
$data['rrule_until'] = $graph['range']['endDate'];
|
||||
break;
|
||||
case 'numbered':
|
||||
$data['rrule_count'] = intval($graph['range']['numberOfOccurrences']);
|
||||
break;
|
||||
case 'noEnd':
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public static function convertGraphToDay($graphDay)
|
||||
{
|
||||
$mapping = [
|
||||
'MONDAY' => 'MO',
|
||||
'TUESDAY' => 'TU',
|
||||
'WEDNESDAY' => 'WE',
|
||||
'THURSDAY' => 'TH',
|
||||
'FRIDAY' => 'FR',
|
||||
'SATURDAY' => 'SA',
|
||||
'SUNDAY' => 'SU'
|
||||
];
|
||||
|
||||
$graphDay = strtoupper($graphDay);
|
||||
return isset($mapping[$graphDay]) ? $mapping[$graphDay] : $graphDay;
|
||||
}
|
||||
|
||||
public static function create(array $data)
|
||||
{
|
||||
$model = new Calendar();
|
||||
|
||||
@@ -968,39 +968,24 @@ class ConstructionConsentController extends mfBaseController {
|
||||
return ["message" => "ConstructionConsent saved successfully"];
|
||||
}
|
||||
|
||||
private function generateStats($baseFilter = array()) {
|
||||
private function generateStats($baseFilter = array()): array {
|
||||
function getFilteredCount($wantedFilter, $filterValue, $baseFilter) {
|
||||
if (!empty($baseFilter[$wantedFilter]) && $baseFilter[$wantedFilter] != $filterValue) {
|
||||
return 0;
|
||||
} else {
|
||||
return ConstructionConsent::count(array_merge($baseFilter, [$wantedFilter => $filterValue]));
|
||||
}
|
||||
if (!empty($baseFilter[$wantedFilter]) && $baseFilter[$wantedFilter] != $filterValue) return 0;
|
||||
return ConstructionConsent::count(array_merge($baseFilter, [$wantedFilter => $filterValue]));
|
||||
}
|
||||
|
||||
$allCount = ConstructionConsent::count($baseFilter);
|
||||
$streetCount = getFilteredCount("object_type", "street", $baseFilter);
|
||||
$buildingCount = getFilteredCount("object_type", "building", $baseFilter);
|
||||
$inspection_planner = getFilteredCount("inspection_planner", "!NULL", $baseFilter);
|
||||
$conduit_installed_building = getFilteredCount("conduit_installed_building", "!NULL", $baseFilter);
|
||||
$conduit_installed_ftu = getFilteredCount("conduit_installed_ftu", "!NULL", $baseFilter);
|
||||
$inhouse_cabling = getFilteredCount("inhouse_cabling", "!NULL", $baseFilter);
|
||||
$status_light_blue = getFilteredCount("status_light", "blue", $baseFilter);
|
||||
$status_light_red = getFilteredCount("status_light", "red", $baseFilter);
|
||||
$status_light_yellow = getFilteredCount("status_light", "yellow", $baseFilter);
|
||||
$status_light_green = getFilteredCount("status_light", "green", $baseFilter);
|
||||
|
||||
return array(
|
||||
"all" => $allCount,
|
||||
"street" => $streetCount,
|
||||
"building" => $buildingCount,
|
||||
"inspection_planner" => $inspection_planner,
|
||||
"conduit_installed_building" => $conduit_installed_building,
|
||||
"conduit_installed_ftu" => $conduit_installed_ftu,
|
||||
"inhouse_cabling" => $inhouse_cabling,
|
||||
"status_light_blue" => $status_light_blue,
|
||||
"status_light_red" => $status_light_red,
|
||||
"status_light_yellow" => $status_light_yellow,
|
||||
"status_light_green" => $status_light_green
|
||||
);
|
||||
return [
|
||||
"all" => ConstructionConsent::count($baseFilter),
|
||||
"street" => getFilteredCount("object_type", "street", $baseFilter),
|
||||
"building" => getFilteredCount("object_type", "building", $baseFilter),
|
||||
"inspection_planner" => getFilteredCount("inspection_planner", "!NULL", $baseFilter),
|
||||
"conduit_installed_building" => getFilteredCount("conduit_installed_building", "!NULL", $baseFilter),
|
||||
"conduit_installed_ftu" => getFilteredCount("conduit_installed_ftu", "!NULL", $baseFilter),
|
||||
"inhouse_cabling" => getFilteredCount("inhouse_cabling", "!NULL", $baseFilter),
|
||||
"status_light_blue" => getFilteredCount("status_light", "blue", $baseFilter),
|
||||
"status_light_red" => getFilteredCount("status_light", "red", $baseFilter),
|
||||
"status_light_yellow" => getFilteredCount("status_light", "yellow", $baseFilter),
|
||||
"status_light_green" => getFilteredCount("status_light", "green", $baseFilter)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -927,11 +927,72 @@ class PreorderModel
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static function countHistoryStatus($filter = [], $status_code = null)
|
||||
{
|
||||
if ($status_code === null) {
|
||||
die("Please select a status code");
|
||||
public static function countActivePreorder($preorderCampaignId = null) {
|
||||
$db = FronkDB::singleton();
|
||||
|
||||
$where = "1=1 ";
|
||||
if ($preorderCampaignId) {
|
||||
$where .= " AND p.preordercampaign_id = $preorderCampaignId";
|
||||
}
|
||||
|
||||
$sql = "SELECT
|
||||
COALESCE(SUM(CASE
|
||||
WHEN LOWER(vh.gdaeigenschaft) IN ('multi dwelling', 'mehrparteienhaus', 'gebaeude mit 2 oder mehr wohnungen', 'gebäude mit 2 oder mehr wohnungen', 'wohngebaeude fuer gemeinschaften', 'wohngebäude für gemeinschaften', 'hotels und aehnliche gebaeude', 'hotels und ähnliche gebäude', 'wohngebäude mit 2 und mehr wohnungen')
|
||||
OR LOWER(vh.rimo_type) IN ('multi dwelling', 'mehrparteienhaus', 'gebaeude mit 2 oder mehr wohnungen', 'gebäude mit 2 oder mehr wohnungen', 'wohngebaeude fuer gemeinschaften', 'wohngebäude für gemeinschaften', 'hotels und aehnliche gebaeude', 'hotels und ähnliche gebäude', 'wohngebäude mit 2 und mehr wohnungen')
|
||||
THEN COALESCE(p.connection_count, 1)
|
||||
ELSE 0
|
||||
END), 0) AS md_count,
|
||||
COALESCE(SUM(COALESCE(p.connection_count, 1)), 0) AS total_count
|
||||
|
||||
FROM
|
||||
`".FRONKDB_DBNAME."`.Preorder p
|
||||
LEFT JOIN `".ADDRESSDB_DBNAME."`.view_hausnummer vh ON p.adb_hausnummer_id = vh.hausnummer_id
|
||||
LEFT JOIN `".FRONKDB_DBNAME."`.Preorderstatus tt_preorderstatus ON p.status_id = tt_preorderstatus.id
|
||||
WHERE p.deleted = 0 AND tt_preorderstatus.code < 899";
|
||||
|
||||
$queryStart = microtime(true);
|
||||
$res = $db->query($sql . $where);
|
||||
mfLoghandler::singleton()->debug("[Query took: ".(microtime(true) - $queryStart)." seconds] " . $sql);
|
||||
if ($db->num_rows($res)) {
|
||||
$data = $db->fetch_object($res);
|
||||
return ['md_count' => $data->md_count, 'sd_count' => $data->total_count - $data->md_count, 'total_count' => $data->total_count];
|
||||
}
|
||||
return ['md_count' => 0, 'sd_count' => 0, 'total_count' => 0];
|
||||
}
|
||||
|
||||
public static function countTotalUnits($preorderCampaignId = null) {
|
||||
$db = FronkDB::singleton();
|
||||
|
||||
$where = "1=1 ";
|
||||
if ($preorderCampaignId) {
|
||||
$where .= " AND pc.id = $preorderCampaignId";
|
||||
}
|
||||
|
||||
$sql = "SELECT
|
||||
pc.id AS campaign_id,
|
||||
COALESCE(SUM(n.unit_count), 0) AS total_unit_count,
|
||||
COALESCE(SUM(n.unit_count_sd), 0) AS total_unit_count_sd,
|
||||
COALESCE(SUM(n.unit_count_md), 0) AS total_unit_count_md
|
||||
FROM Preordercampaign pc
|
||||
LEFT JOIN `".FRONKDB_DBNAME."`.PreordercampaignSalescluster pcs ON pc.id = pcs.preordercampaign_id
|
||||
LEFT JOIN `".ADDRESSDB_DBNAME."`.Netzgebiet n ON pcs.salescluster_id = n.id
|
||||
WHERE $where
|
||||
GROUP BY pc.id";
|
||||
|
||||
$queryStart = microtime(true);
|
||||
$res = $db->query($sql);
|
||||
mfLoghandler::singleton()->debug("[Query took: ".(microtime(true) - $queryStart)." seconds] " . $sql);
|
||||
if ($db->num_rows($res)) {
|
||||
$data = $db->fetch_object($res);
|
||||
return ['total_unit_count' => $data->total_unit_count, 'total_unit_count_sd' => $data->total_unit_count_sd, 'total_unit_count_md' => $data->total_unit_count_md];
|
||||
}
|
||||
return ['total_unit_count' => 0, 'total_unit_count_sd' => 0, 'total_unit_count_md' => 0];
|
||||
}
|
||||
|
||||
public static function countHistoryStatus($filter = [], $status_code = null) {
|
||||
if ($status_code === null) {
|
||||
die("Please select a status code");
|
||||
}
|
||||
|
||||
if (!is_array($filter)) return false;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -263,7 +263,7 @@ class TimerecordingController extends mfBaseController
|
||||
{
|
||||
$r = $this->request;
|
||||
$id = $r->id;
|
||||
$oldbpseconds=0;
|
||||
$oldbpseconds = 0;
|
||||
$enddate = $r->enddate;
|
||||
$hourday = $r->hourday;
|
||||
|
||||
@@ -530,7 +530,7 @@ class TimerecordingController extends mfBaseController
|
||||
}
|
||||
$workinghourshistory = TimerecordingEmployeeWorkingHourHistoryModel::search(['user_id' => $userid]);
|
||||
if ($workinghourshistory) {
|
||||
$workingHoursHistory[2147483500]=$workingHours;
|
||||
$workingHoursHistory[2147483500] = $workingHours;
|
||||
foreach ($workinghourshistory as $workinghourhistory) {
|
||||
$whenddate = $workinghourhistory->enddate;
|
||||
$workinghourhistoryhours = json_decode($workinghourhistory->workinghours, true);
|
||||
@@ -547,13 +547,11 @@ class TimerecordingController extends mfBaseController
|
||||
}
|
||||
//check if holiday is already in the list
|
||||
foreach ($holidayDays as $key => $holidayDay) {
|
||||
if ($workingHoursHistory)
|
||||
{
|
||||
if ($workingHoursHistory) {
|
||||
foreach ($workingHoursHistory as $whkey => $whdata) {
|
||||
$whtimestamp = strtotime(date('Y-m-d 23:59:59', $whkey));
|
||||
$timestamp = strtotime($key);
|
||||
if ($whtimestamp >= $timestamp)
|
||||
{
|
||||
if ($whtimestamp >= $timestamp) {
|
||||
$workingHours = $whdata;
|
||||
}
|
||||
}
|
||||
@@ -672,7 +670,7 @@ class TimerecordingController extends mfBaseController
|
||||
}
|
||||
}
|
||||
|
||||
protected function getTimerecordingsApi($datatype, $dataweek, $datamonth, $datayear, $startime = null, $endtime = null, $userid = null)
|
||||
public function getTimerecordingsApi($datatype, $dataweek, $datamonth, $datayear, $startime = null, $endtime = null, $userid = null, $ajax = 1)
|
||||
{
|
||||
$holidayrows = [];
|
||||
$mustSeconds = 0;
|
||||
@@ -680,7 +678,7 @@ class TimerecordingController extends mfBaseController
|
||||
$holiDays = 0;
|
||||
$plusHours = 0;
|
||||
$startdate = time();
|
||||
$allhours=0;
|
||||
$allhours = 0;
|
||||
if (!$userid) {
|
||||
$userid = $this->me->id;
|
||||
}
|
||||
@@ -699,8 +697,8 @@ class TimerecordingController extends mfBaseController
|
||||
|
||||
$overtime = $employee[0]->overtime_now;
|
||||
if ($employee[0]->only_admin) {
|
||||
$getAllHours=TimerecordingModel::getAllHours($userid);
|
||||
$getAllHours=$getAllHours[0]->gesamt_summe;
|
||||
$getAllHours = TimerecordingModel::getAllHours($userid);
|
||||
$getAllHours = $getAllHours[0]->gesamt_summe;
|
||||
}
|
||||
}
|
||||
$workinghours = TimerecordingEmployeeWorkingHourModel::search(['user_id' => $userid]);
|
||||
@@ -718,7 +716,7 @@ class TimerecordingController extends mfBaseController
|
||||
|
||||
$workinghourshistory = TimerecordingEmployeeWorkingHourHistoryModel::search(['user_id' => $userid]);
|
||||
if ($workinghourshistory) {
|
||||
$workingHoursHistory[2147483500]=$workingHours;
|
||||
$workingHoursHistory[2147483500] = $workingHours;
|
||||
foreach ($workinghourshistory as $workinghourhistory) {
|
||||
$whenddate = $workinghourhistory->enddate;
|
||||
$workinghourhistoryhours = json_decode($workinghourhistory->workinghours, true);
|
||||
@@ -757,12 +755,10 @@ class TimerecordingController extends mfBaseController
|
||||
}
|
||||
$dDate = date('Y-m-d', $timestamp + $WintertimeCompensation);
|
||||
$dDay = date('w', $timestamp + $WintertimeCompensation);
|
||||
if ($workingHoursHistory)
|
||||
{
|
||||
if ($workingHoursHistory) {
|
||||
foreach ($workingHoursHistory as $whkey => $whdata) {
|
||||
$whtimestamp = strtotime(date('Y-m-d 23:59:59', $whkey));
|
||||
if ($whtimestamp >= $timestamp)
|
||||
{
|
||||
if ($whtimestamp >= $timestamp) {
|
||||
unset($workingHours);
|
||||
$workingHours = $whdata;
|
||||
}
|
||||
@@ -792,12 +788,10 @@ class TimerecordingController extends mfBaseController
|
||||
}
|
||||
$dDate = date('Y-m-d', $timestamp + $WintertimeCompensation);
|
||||
$dDay = date('w', $timestamp + $WintertimeCompensation);
|
||||
if ($workingHoursHistory)
|
||||
{
|
||||
if ($workingHoursHistory) {
|
||||
foreach ($workingHoursHistory as $whkey => $whdata) {
|
||||
$whtimestamp = strtotime(date('Y-m-d 23:59:59', $whkey));
|
||||
if ($whtimestamp >= $timestamp)
|
||||
{
|
||||
if ($whtimestamp >= $timestamp) {
|
||||
unset($workingHours);
|
||||
$workingHours = $whdata;
|
||||
}
|
||||
@@ -826,12 +820,10 @@ class TimerecordingController extends mfBaseController
|
||||
}
|
||||
$dDate = date('Y-m-d', $timestamp + $WintertimeCompensation);
|
||||
$dDay = date('w', $timestamp + $WintertimeCompensation);
|
||||
if ($workingHoursHistory)
|
||||
{
|
||||
if ($workingHoursHistory) {
|
||||
foreach ($workingHoursHistory as $whkey => $whdata) {
|
||||
$whtimestamp = strtotime(date('Y-m-d 23:59:59', $whkey));
|
||||
if ($whtimestamp >= $timestamp)
|
||||
{
|
||||
if ($whtimestamp >= $timestamp) {
|
||||
unset($workingHours);
|
||||
$workingHours = $whdata;
|
||||
}
|
||||
@@ -859,12 +851,10 @@ class TimerecordingController extends mfBaseController
|
||||
if (date('I', $timestamp) == 0) {
|
||||
$WintertimeCompensation = 3600;
|
||||
}
|
||||
if ($workingHoursHistory)
|
||||
{
|
||||
if ($workingHoursHistory) {
|
||||
foreach ($workingHoursHistory as $whkey => $whdata) {
|
||||
$whtimestamp = strtotime(date('Y-m-d 23:59:59', $whkey));
|
||||
if ($whtimestamp >= $timestamp)
|
||||
{
|
||||
if ($whtimestamp >= $timestamp) {
|
||||
unset($workingHours);
|
||||
$workingHours = $whdata;
|
||||
// echo date('Y-m-d 23:59:59', $whkey).PHP_EOL;
|
||||
@@ -908,6 +898,9 @@ class TimerecordingController extends mfBaseController
|
||||
$sum = sprintf("%02d", $hours) . ":" . sprintf("%02d", $minutes);
|
||||
$day = $daysgerm[date("w", $timerecording->start)];
|
||||
$isSeconds = $isSeconds + $seconds;
|
||||
if ($ajax == 0) {
|
||||
$workdaycheck[] = $datadate;
|
||||
}
|
||||
} else if ($timerecording->timerecordingCategory->hourday == 2 || ($timerecording->timerecordingCategory->hourday == 3 && $timerecording->end)) {
|
||||
|
||||
$date = date("d.m.", $timerecording->start) . " - " . $daysgerm[date("w", $timerecording->end)] . " " . date("d.m.Y", $timerecording->end);
|
||||
@@ -931,12 +924,10 @@ class TimerecordingController extends mfBaseController
|
||||
$savecounter = 0;
|
||||
$sumdays = 0;
|
||||
for ($i = $starttimecalc; $i <= $endtimecalc; $i = $i + 86400) {
|
||||
if ($workingHoursHistory)
|
||||
{
|
||||
if ($workingHoursHistory) {
|
||||
foreach ($workingHoursHistory as $whkey => $whdata) {
|
||||
$whtimestamp = strtotime(date('Y-m-d 23:59:59', $whkey));
|
||||
if ($whtimestamp >= $i)
|
||||
{
|
||||
if ($whtimestamp >= $i) {
|
||||
unset($workingHours);
|
||||
$workingHours = $whdata;
|
||||
}
|
||||
@@ -944,6 +935,10 @@ class TimerecordingController extends mfBaseController
|
||||
}
|
||||
$holidaycounter = $workingHours[date("w", $i)];
|
||||
$daycheck = date("Y-m-d", $i);
|
||||
if ($ajax == 0) {
|
||||
$workdaycheck[] = $daycheck;
|
||||
}
|
||||
|
||||
if (!$holiDay[$daycheck]) {
|
||||
if ($holidaycounter) {
|
||||
$isSeconds = $isSeconds + $holidaycounter;
|
||||
@@ -991,17 +986,19 @@ class TimerecordingController extends mfBaseController
|
||||
$savecounter = 0;
|
||||
// echo $starttimecalc."<br>";
|
||||
for ($i = $starttimecalc; $i <= $endtimecalc; $i = $i + 86400) {
|
||||
if ($workingHoursHistory)
|
||||
{
|
||||
if ($workingHoursHistory) {
|
||||
foreach ($workingHoursHistory as $whkey => $whdata) {
|
||||
$whtimestamp = strtotime(date('Y-m-d 23:59:59', $whkey));
|
||||
if ($whtimestamp >= $i)
|
||||
{
|
||||
if ($whtimestamp >= $i) {
|
||||
unset($workingHours);
|
||||
$workingHours = $whdata;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($ajax == 0) {
|
||||
$daycheck = date("Y-m-d", $i);
|
||||
$workdaycheck[] = $daycheck;
|
||||
}
|
||||
$holidaycounter = $workingHours[$timerecording->user_id][date("w", $i)];
|
||||
$daycheck = date("Y-m-d", $i);
|
||||
if (!$holiDay[$daycheck]) {
|
||||
@@ -1049,6 +1046,10 @@ class TimerecordingController extends mfBaseController
|
||||
$sum = "-" . sprintf("%02d", $hours) . ":" . sprintf("%02d", $minutes);
|
||||
$day = $daysgerm[date("w", $timerecording->start)];
|
||||
$isSeconds = $isSeconds + $seconds;
|
||||
if ($ajax == 0) {
|
||||
$workdaycheck[] = $datadate;
|
||||
}
|
||||
|
||||
} else if ($timerecording->timerecordingCategory->hourday == 7) {
|
||||
$date = date("d.m.Y", $timerecording->start);
|
||||
$datadate = date("Y-m-d", $timerecording->start);
|
||||
@@ -1164,9 +1165,15 @@ class TimerecordingController extends mfBaseController
|
||||
$json['data'] = $rows;
|
||||
$json['recordsFiltered'] = $responsecount;
|
||||
$json['recordsTotal'] = $responsecount;
|
||||
$json = json_encode($json);
|
||||
echo trim($json);
|
||||
die();
|
||||
|
||||
if ($ajax == 1) {
|
||||
$json = json_encode($json);
|
||||
echo trim($json);
|
||||
die();
|
||||
} else {
|
||||
$json['workcheck'] = $workdaycheck;
|
||||
return $json;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -107,6 +107,9 @@ class TimerecordingBillingController extends mfBaseController
|
||||
case "generatebmdexportnlz":
|
||||
$return = $this->generateBmdExport($month, 1);
|
||||
break;
|
||||
case "generateopenworkdays":
|
||||
$return = $this->generateopenworkdays($month);
|
||||
break;
|
||||
case "generatebmdexportclosed":
|
||||
$return = $this->generateBmdExportClosed($month);
|
||||
break;
|
||||
@@ -383,6 +386,37 @@ class TimerecordingBillingController extends mfBaseController
|
||||
exit;
|
||||
}
|
||||
|
||||
protected function generateopenworkdays($month)
|
||||
{
|
||||
$filename = "open_workdays_" . $month . ".csv";
|
||||
$file = fopen("php://output", 'w');
|
||||
header('Content-Type: text/csv; charset=utf-8');
|
||||
header('Content-Disposition: attachment; filename=' . $filename);
|
||||
$headerarray = ["Monat", "Mitarbeiter", "Tag"];
|
||||
fputcsv($file, $headerarray, ";");
|
||||
$month = strtotime("01." . $month);
|
||||
//last of month
|
||||
$monthend = date("Y-m-d", strtotime("last day of this month", $month));
|
||||
$monthend = strtotime($monthend . " 23:59:59");
|
||||
$monthbmd = date("n", $month);
|
||||
$timerecordingsEmolyees = TimerecordingEmployeeModel::getAll();
|
||||
foreach ($timerecordingsEmolyees as $timerecordingsEmolyee) {
|
||||
unset($bodyarray);
|
||||
if ($timerecordingsEmolyee->bmd_active == 0 || $timerecordingsEmolyee->startdate > $monthend || ($timerecordingsEmolyee->enddate && $timerecordingsEmolyee->enddate < $month)) continue;
|
||||
$user = new User($timerecordingsEmolyee->user_id);
|
||||
$employee_number = (string)$user->getFlag('employee_number');
|
||||
|
||||
$WorkingDays = $this->checkWorkingDays($user->id, $month, $timerecordingsEmolyee);
|
||||
foreach ($WorkingDays as $WorkingDay) {
|
||||
$bodyarray = [date("m-Y", $month), mb_convert_encoding($user->name, 'ISO-8859-1', 'UTF-8'), date("d.m.Y", strtotime($WorkingDay))];
|
||||
fputcsv($file, $bodyarray, ";");
|
||||
}
|
||||
}
|
||||
|
||||
fclose($file);
|
||||
exit;
|
||||
}
|
||||
|
||||
protected function generateBmdExport($month, $nlz = 0, $export = 1)
|
||||
{
|
||||
//create and download csv file
|
||||
@@ -606,8 +640,8 @@ class TimerecordingBillingController extends mfBaseController
|
||||
}
|
||||
if ($timerecording['daysum']) {
|
||||
$data['nlz'] = $timerecording['daysum'];
|
||||
if (strpos($data['nlz'],"Urlaub aufbuchen") !== false) {
|
||||
$holidays=$this->getholidays($timerecording['user_id'], $enddate);
|
||||
if (strpos($data['nlz'], "Urlaub aufbuchen") !== false) {
|
||||
$holidays = $this->getholidays($timerecording['user_id'], $enddate);
|
||||
$data['holidays'] = $holidays;
|
||||
}
|
||||
}
|
||||
@@ -879,4 +913,94 @@ class TimerecordingBillingController extends mfBaseController
|
||||
|
||||
return $holidays_now;
|
||||
}
|
||||
|
||||
protected function checkWorkingDays($user_id, $month, $employee)
|
||||
{
|
||||
$holidays = TimerecordingHolidayModel::getAll();
|
||||
$datamonth = $month;
|
||||
$firstdate = strtotime(date("Y-m-01", $datamonth));
|
||||
$lastdate = strtotime(date("Y-m-t", $datamonth));
|
||||
$daycount = date("t", $datamonth);
|
||||
$lastdate = strtotime(date("Y-m-d", $lastdate) . ' 23:59:59');
|
||||
|
||||
$startdate = $employee->startdate;
|
||||
if ($employee->enddate) {
|
||||
$enddate = strtotime(date('Y-m-d', $employee->enddate) . " 23:59:59");
|
||||
} else {
|
||||
$enddate = 2208985200;
|
||||
}
|
||||
$bpahours = $employee->bpahours;
|
||||
|
||||
$workinghours = TimerecordingEmployeeWorkingHourModel::search(['user_id' => $user_id]);
|
||||
foreach ($workinghours as $workinghour) {
|
||||
|
||||
$whstart = strtotime(date('Y-m-d', time()) . " " . $workinghour->start . ":00");
|
||||
$whend = strtotime(date('Y-m-d', time()) . " " . $workinghour->end . ":00");
|
||||
if (!$workingHours[$workinghour->day]) {
|
||||
$workingHours[$workinghour->day] = $whend - $whstart;
|
||||
} else {
|
||||
$workingHours[$workinghour->day] = $workingHours[$workinghour->day] + $whend - $whstart;
|
||||
}
|
||||
}
|
||||
$workinghourshistory = TimerecordingEmployeeWorkingHourHistoryModel::search(['user_id' => $user_id]);
|
||||
if ($workinghourshistory) {
|
||||
$workingHoursHistory[9732489200] = $workingHours;
|
||||
foreach ($workinghourshistory as $workinghourhistory) {
|
||||
$whenddate = $workinghourhistory->enddate;
|
||||
$workinghourhistoryhours = json_decode($workinghourhistory->workinghours, true);
|
||||
foreach ($workinghourhistoryhours as $workinghourhistoryhour) {
|
||||
$whstart = strtotime(date('Y-m-d', time()) . " " . $workinghourhistoryhour['start'] . ":00");
|
||||
$whend = strtotime(date('Y-m-d', time()) . " " . $workinghourhistoryhour['end'] . ":00");
|
||||
if (!$workingHoursHistory[$whenddate][$workinghourhistoryhour['day']]) {
|
||||
$workingHoursHistory[$whenddate][$workinghourhistoryhour['day']] = $whend - $whstart;
|
||||
} else {
|
||||
$workingHoursHistory[$whenddate][$workinghourhistoryhour['day']] = $workingHoursHistory[$whenddate][$workinghourhistoryhour['day']] + $whend - $whstart;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($holidays as $holiday) {
|
||||
$holiDay[date('Y-m-d', $holiday->timestamp)] = $holiday->timestamp;
|
||||
}
|
||||
|
||||
//Lastdate staticmust deleted
|
||||
// $lastdate = strtotime("2024-03-22 23:59:59");
|
||||
// $daycount=22;
|
||||
|
||||
$searchArray = ['user_id' => $user_id, 'start' => $firstdate, 'end' => $lastdate];
|
||||
$timestamp = $firstdate;
|
||||
for ($i = 1; $i <= $daycount; $i++) {
|
||||
$WintertimeCompensation = 0;
|
||||
if (date('I', $timestamp) == 0) {
|
||||
$WintertimeCompensation = 3600;
|
||||
}
|
||||
$dDate = date('Y-m-d', $timestamp + $WintertimeCompensation);
|
||||
$dDay = date('w', $timestamp + $WintertimeCompensation);
|
||||
if ($workingHoursHistory) {
|
||||
foreach ($workingHoursHistory as $whkey => $whdata) {
|
||||
$whtimestamp = strtotime(date('Y-m-d 23:59:59', $whkey));
|
||||
if ($whtimestamp >= $timestamp) {
|
||||
$workingHours = $whdata;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$holiDay[$dDate] && $dDate >= date('Y-m-d', $startdate) && $dDate <= date('Y-m-d', $enddate)) {
|
||||
$mustSeconds = $mustSeconds + $workingHours[$dDay];
|
||||
if ($workingHours[$dDay]) {
|
||||
$workDays[$dDate] = $dDate;
|
||||
}
|
||||
}
|
||||
|
||||
$timestamp = $timestamp + 86400;
|
||||
}
|
||||
$timerecordingC = new TimerecordingController();
|
||||
$timerecordingC = $timerecordingC->getTimerecordingsApi('2', $month, $month, $month, 0, 0, $user_id, 0);
|
||||
foreach ($timerecordingC['workcheck'] as $key => $value) {
|
||||
unset($workDays[$value]);
|
||||
}
|
||||
|
||||
return $workDays;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php /** @noinspection ALL */
|
||||
declare(strict_types=1);
|
||||
|
||||
use Phinx\Migration\AbstractMigration;
|
||||
|
||||
final class AddPreorderDbImprovements extends AbstractMigration {
|
||||
public function up(): void {
|
||||
if ($this->getEnvironment() == "thetool") {
|
||||
$this->table("PreordercampaignSalescluster")->addIndex(["preordercampaign_id","salescluster_id"])->save();
|
||||
$this->table("RimoWorkorder")->addIndex(["adb_wohneinheit_id"])->save();
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void {
|
||||
if ($this->getEnvironment() == "thetool") {
|
||||
$this->table("PreordercampaignSalescluster")->removeIndex(["preordercampaign_id","salescluster_id"])->save();
|
||||
$this->table("RimoWorkorder")->removeIndex(["adb_wohneinheit_id"])->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,16 @@
|
||||
<?php
|
||||
|
||||
class FronkDB {
|
||||
|
||||
public $link;
|
||||
private $result;
|
||||
private $lastError;
|
||||
private $log;
|
||||
|
||||
public $insert_id;
|
||||
|
||||
private static $instances = [];
|
||||
|
||||
//private static $instance;
|
||||
public $host;
|
||||
public $user;
|
||||
public $pass;
|
||||
public $db;
|
||||
|
||||
public function __construct($host = false, $user = false, $pass = false, $db = false) {
|
||||
$this->host = $host;
|
||||
|
||||
@@ -89,6 +89,7 @@ table = $('#datatable').DataTable({
|
||||
});
|
||||
if (initc === 2) {
|
||||
$('.buttons-excel').closest('div').append('<div ><button id="month-complete" class="btn btn-danger margina">Monats Abschluss</button></div>');
|
||||
$('.buttons-excel').closest('div').append('<div ><button id="open-workdays" class="btn btn-info margina">Offene Arbeitstage</button></div>');
|
||||
$('.buttons-excel').closest('div').append('<div ><button id="bmd-export" class="btn btn-info margina">BMD Import</button></div>');
|
||||
$('.buttons-excel').closest('div').append('<div ><button id="bmd-export-nlz" class="btn btn-info margina">BMD NLZ Import</button></div>');
|
||||
}
|
||||
|
||||
@@ -673,11 +673,12 @@ thead .fc-day-today .fc-scrollgrid-sync-inner .fc-col-header-cell-cushion {
|
||||
margin-left: -28px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
.cursor-alias{
|
||||
|
||||
.cursor-alias {
|
||||
cursor: alias;
|
||||
}
|
||||
.fa-calendar-alert
|
||||
{
|
||||
|
||||
.fa-calendar-alert {
|
||||
font-size: 15px;
|
||||
vertical-align: top;
|
||||
margin-top: -1px;
|
||||
@@ -688,57 +689,65 @@ thead .fc-day-today .fc-scrollgrid-sync-inner .fc-col-header-cell-cushion {
|
||||
color: #ff0000;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.fa-calendar-alert:before {
|
||||
color: #fff;
|
||||
|
||||
}
|
||||
.fa-calendar-alert-search
|
||||
{
|
||||
|
||||
.fa-calendar-alert-search {
|
||||
font-size: 22px;
|
||||
|
||||
}
|
||||
.logo-top-search
|
||||
{
|
||||
|
||||
.logo-top-search {
|
||||
height: 20px;
|
||||
vertical-align: top;
|
||||
cursor: pointer;
|
||||
}
|
||||
.btn-light-search
|
||||
{
|
||||
|
||||
.btn-light-search {
|
||||
border-color: #e5e5e5;
|
||||
padding: 3px 6px;
|
||||
}
|
||||
.top-search-filter
|
||||
{
|
||||
filter:grayscale(100%);
|
||||
|
||||
.top-search-filter {
|
||||
filter: grayscale(100%);
|
||||
}
|
||||
|
||||
.fc-event-time {
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.note-editor .dropdown-item {
|
||||
padding: .15rem 1.2rem;
|
||||
}
|
||||
|
||||
.note-editable p {
|
||||
line-height: 1.2;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.tooltip-description p {
|
||||
margin-bottom: 0;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.note-dropdown-menu {
|
||||
max-height: 250px !important;
|
||||
overflow-y: auto !important;
|
||||
z-index: 99999 !important;
|
||||
}
|
||||
|
||||
.tox-dialog {
|
||||
z-index: 1060 !important; /* oder ein höherer Wert, je nach Bedarf */
|
||||
}
|
||||
|
||||
.tox .tox-tbtn--select {
|
||||
max-width: 95px;
|
||||
}
|
||||
.fa-calendar-call
|
||||
{
|
||||
|
||||
.fa-calendar-call {
|
||||
font-size: 13px;
|
||||
vertical-align: top;
|
||||
margin-top: 0px;
|
||||
@@ -748,12 +757,30 @@ thead .fc-day-today .fc-scrollgrid-sync-inner .fc-col-header-cell-cushion {
|
||||
color: #ff0000;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.fa-calendar-call:before {
|
||||
content: "\f2a0";
|
||||
color: #000000;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.fa-calendar-call-search {
|
||||
font-size: 21px;
|
||||
margin-top: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.fa-xls-calendar {
|
||||
font-size: 24px;
|
||||
padding-top: 2px;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
.btn-xls-calendar {
|
||||
padding: 3px 6px;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.btn-xls-calendar:hover, .btn-xls-calendar:focus, .btn-xls-calendar:active {
|
||||
background-color: #ffffff !important;
|
||||
border-color: #ffffff !important;
|
||||
}
|
||||
|
||||
@@ -554,6 +554,18 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
$('#delete-event').hide();
|
||||
$('#update-event').hide();
|
||||
$('.show-attendee').hide();
|
||||
$('#recurringCheck').prop('checked', true);
|
||||
$('#recurringCheck').change();
|
||||
if (data.data.recurrence) {
|
||||
$('#rrule-frequency').val(data.data.recurrence.recurrence.rrule_frequency);
|
||||
$('#rrule-frequency').trigger('change');
|
||||
$('#rrule-interval').val(data.data.recurrence.recurrence.rrule_interval);
|
||||
$('#rrule-byweekday').val(data.data.recurrence.recurrence.rrule_byweekday);
|
||||
$('#rrule-until').val(data.data.recurrence.recurrence.rrule_until);
|
||||
$('#monthly-type').val(data.data.recurrence.recurrence.monthly_type);
|
||||
$('#monthly-type').trigger('change');
|
||||
$('#rrule-bymonthday').val(data.data.recurrence.recurrence.rrule_bymonthday);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -914,9 +926,11 @@ if (typeof (EventSource) !== 'undefined') {
|
||||
let rruleflag = false;
|
||||
let cursorclass = '';
|
||||
if (event.rrule) {
|
||||
$('.calendar-check').eq(0).trigger('change');
|
||||
rrule = event.rrule;
|
||||
duration = event.duration;
|
||||
rruleflag = true;
|
||||
return;
|
||||
}
|
||||
if (event.calendar_id in calendarRights) {
|
||||
if (calendarRights[event.calendar_id] == 'all') {
|
||||
@@ -1190,7 +1204,15 @@ $(document).ready(function () {
|
||||
$('#EventModal .is-require').each(function (index, value) {
|
||||
$(this).removeClass('required');
|
||||
});
|
||||
|
||||
$('#recurring-settings').hide();
|
||||
$('#weekly-options').hide();
|
||||
$('#monthly-type').val('BYMONTHDAY');
|
||||
$('#rrule-frequency').val('');
|
||||
$('#rrule-count').val('');
|
||||
$('#rrule-until').val('');
|
||||
$('#rrule-byweekday').val('');
|
||||
$('#rrule-bymonthday').val('1');
|
||||
$('#monthly-options').hide();
|
||||
// $('.select2-multiple').select2();
|
||||
$('#calendar-users').prop("disabled", false);
|
||||
$("#calendar-users option").each(function () {
|
||||
@@ -1298,6 +1320,27 @@ $(document).ready(function () {
|
||||
users.push($(this).val());
|
||||
});
|
||||
|
||||
if ($('#recurringCheck').is(':checked') && $('#rrule-frequency').val() !== '') {
|
||||
var rruleData = {};
|
||||
rruleData.rrule_frequency = $('#rrule-frequency').val();
|
||||
|
||||
if (rruleData.rrule_frequency === 'WEEKLY') {
|
||||
// Mehrere Wochentage als Array
|
||||
rruleData['rrule-byweekday'] = $('#rrule-byweekday').val();
|
||||
} else if (rruleData.rrule_frequency === 'MONTHLY') {
|
||||
rruleData.monthly_type = $('#monthly-type').val();
|
||||
if (rruleData.monthly_type === 'BYMONTHDAY') {
|
||||
rruleData.rrule_bymonthday = $('#rrule-bymonthday').val();
|
||||
} else if (rruleData.monthly_type === 'BYSETPOS') {
|
||||
rruleData.rrule_setpos = $('#rrule-setpos').val();
|
||||
rruleData.rrule_bynweekday = $('#rrule-bynweekday').val();
|
||||
}
|
||||
}
|
||||
// Optionale Felder
|
||||
rruleData.rrule_count = $('#rrule-count').val();
|
||||
rruleData.rrule_until = $('#rrule-until').val();
|
||||
}
|
||||
|
||||
|
||||
$.post(requestInsertUrl, {
|
||||
start: start,
|
||||
@@ -1312,6 +1355,7 @@ $(document).ready(function () {
|
||||
attachments: attachments,
|
||||
users: users,
|
||||
privateflag: privateflag,
|
||||
rruleData: rruleData,
|
||||
attendees: $('#calendar-attendees').val(),
|
||||
customer: customer,
|
||||
customer_info_check: customer_info_check,
|
||||
@@ -2049,6 +2093,63 @@ $(document).ready(function () {
|
||||
}
|
||||
});
|
||||
|
||||
$("body").on("click", ".fa-xls-calendar", function (e) {
|
||||
let checkbox = $(".calendar-check");
|
||||
let calendarFilter = $('.btn-light-search');
|
||||
let visibleCalendars = [];
|
||||
let visibleCalendarTypes = [];
|
||||
let mycalendar_id = $('#calendar-id').data('calendarid');
|
||||
visibleCalendars.push(0);
|
||||
checkbox.each(function () {
|
||||
if ($(this).prop('checked')) {
|
||||
visibleCalendars.push($(this).data('calendar_id'));
|
||||
}
|
||||
});
|
||||
calendarFilter.each(function () {
|
||||
if (!$(this).hasClass('top-search-filter')) {
|
||||
visibleCalendarTypes.push($(this).data('ctype'));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
$.ajax({
|
||||
url: requestgenerateEventsxlsx,
|
||||
method: 'POST',
|
||||
data: {
|
||||
visibleCalendars: visibleCalendars,
|
||||
visibleCalendarTypes: visibleCalendarTypes
|
||||
},
|
||||
xhrFields: {
|
||||
responseType: 'blob' // Erwartet binäre Daten als Blob
|
||||
},
|
||||
success: function (data, status, xhr) {
|
||||
// Header auslesen, um den Dateinamen zu erhalten
|
||||
var disposition = xhr.getResponseHeader('Content-Disposition');
|
||||
var filename = "download.xlsx";
|
||||
if (disposition && disposition.indexOf('attachment') !== -1) {
|
||||
var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
|
||||
var matches = filenameRegex.exec(disposition);
|
||||
if (matches != null && matches[1]) {
|
||||
filename = matches[1].replace(/['"]/g, '');
|
||||
}
|
||||
}
|
||||
// Blob in eine URL umwandeln und Download auslösen
|
||||
var url = window.URL.createObjectURL(data);
|
||||
var a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = filename;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
a.remove();
|
||||
window.URL.revokeObjectURL(url);
|
||||
},
|
||||
error: function (jqXHR, status, error) {
|
||||
console.error("Download error:", error);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
$("body").on("blur", ".cal-group-name-input", function (e) {
|
||||
let groupname = $.trim($(this).val());
|
||||
if (groupname.length > 3) {
|
||||
@@ -2417,14 +2518,54 @@ $(document).ready(function () {
|
||||
});
|
||||
}
|
||||
|
||||
// $('.select-2').select2({
|
||||
// containerCssClass : 'meine-custom-dropdown', // Klasse für das Dropdown-Menü
|
||||
// containerCss : "wrap",
|
||||
// selectionCssClass: 'meine-custom-selection'
|
||||
// });
|
||||
$(document).on('focusin', function (e) {
|
||||
if ($(e.target).closest(".tox-tinymce, .tox-tinymce-aux, .moxman-window, .tam-assetmanager-root").length) {
|
||||
e.stopImmediatePropagation();
|
||||
}
|
||||
});
|
||||
$(document).ready(function () {
|
||||
// Checkbox toggelt das RRule-Panel
|
||||
$('#recurringCheck').on('change', function () {
|
||||
if ($(this).is(':checked')) {
|
||||
$('#recurring-settings').show();
|
||||
$('#rrule-until').attr('min', $('#start-date').val());
|
||||
} else {
|
||||
$('#recurring-settings').hide();
|
||||
$('#weekly-options').hide();
|
||||
$('#monthly-options').hide();
|
||||
}
|
||||
});
|
||||
|
||||
// Falls eine Frequenz gewählt wird, passende Felder (weekly/monthly) einblenden
|
||||
$('#rrule-frequency').on('change', function () {
|
||||
var freq = $(this).val();
|
||||
|
||||
// Alles erstmal verstecken
|
||||
$('#weekly-options').hide();
|
||||
$('#monthly-options').hide();
|
||||
|
||||
if (freq === 'WEEKLY') {
|
||||
$('#weekly-options').show();
|
||||
} else if (freq === 'MONTHLY') {
|
||||
$('#monthly-options').show();
|
||||
}
|
||||
});
|
||||
|
||||
// Zeige/Verstecke im monatlichen Bereich "Tag des Monats" oder "X. Wochentag"
|
||||
$('#monthly-type').on('change', function () {
|
||||
var monthlyType = $(this).val();
|
||||
if (monthlyType === 'BYMONTHDAY') {
|
||||
$('#monthly-day-select').show();
|
||||
$('#monthly-setpos-select').hide();
|
||||
} else {
|
||||
$('#monthly-day-select').hide();
|
||||
$('#monthly-setpos-select').show();
|
||||
}
|
||||
});
|
||||
|
||||
// Du kannst bei Klick auf "Hinzufügen" oder "Speichern" dann aus den ausgewählten Werten
|
||||
// dein RRule-String generieren (z.B. mit rrule.js oder manuell).
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -50,9 +50,12 @@ Vue.component('Pop', {
|
||||
defaultPageSize: 25,
|
||||
headers: [
|
||||
{text: 'Name', key: 'name', priority: 10},
|
||||
{text: 'Netzgebiet', key: 'networkArea', class: 'text-center', filter: 'autocomplete',
|
||||
filterOptions: window['TT_CONFIG']['NETWORKS'],
|
||||
priority: 8},
|
||||
{text: 'Netzgebiet', key: 'networkArea', class: 'text-center',
|
||||
// TODO: fix autocomplete Filter
|
||||
// filter: 'autocomplete',
|
||||
// filterOptions: window['TT_CONFIG']['NETWORKS'],
|
||||
// priority: 8
|
||||
},
|
||||
{text: 'Zutritt', key: 'location', class: 'text-center', priority: 1},
|
||||
{text: 'Standort', key: 'gps', class: 'text-center', priority: 2},
|
||||
{text: 'Vlan Public/Nat/ipv6', key: 'vlan', class: 'text-center', priority: 7},
|
||||
|
||||
36
public/js/pages/Preordercampaign/Preordercampaign.css
Normal file
36
public/js/pages/Preordercampaign/Preordercampaign.css
Normal file
@@ -0,0 +1,36 @@
|
||||
.campaign-grid {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
gap: 0.75rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.campaign-icon,
|
||||
.campaign-icon > i{
|
||||
font-size: 24px !important;
|
||||
padding: 0.25rem;
|
||||
}
|
||||
|
||||
.campaign-icon:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.progress-grid {
|
||||
display: grid;
|
||||
grid-template-columns: auto repeat(3, max-content);
|
||||
gap: 0.4rem;
|
||||
}
|
||||
|
||||
.progress-row > *:nth-child(n+2) {
|
||||
text-align: right;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.preorder-campaign-table-actions > a > i {
|
||||
font-size: 17px !important;
|
||||
}
|
||||
|
||||
.preorder-campaign-table-actions {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
103
public/js/pages/Preordercampaign/Preordercampaign.js
Normal file
103
public/js/pages/Preordercampaign/Preordercampaign.js
Normal file
@@ -0,0 +1,103 @@
|
||||
Vue.component('Preordercampaign', {
|
||||
template: `
|
||||
<tt-card>
|
||||
<tt-table :data="window['TT_CONFIG']['CAMPAIGNS']" :config="PreordercampaignTableConfig">
|
||||
<template v-slot:top-buttons>
|
||||
<button v-if="window['TT_CONFIG']['IS_ADMIN'] === '1'" type="button" class="btn btn-primary" @click="window.location = window['TT_CONFIG']['ADD_URL']">
|
||||
<i class="fas fa-plus"></i> Vorbestellung hinzufügen
|
||||
</button>
|
||||
<a v-if="window['TT_CONFIG']['SHOW_MISC_BUTTONS'] === '1'" class="btn btn-purple" :href="window['TT_CONFIG']['PREORDER_DISCOUNT_IMPORT_URL']">
|
||||
<i class="fas fa-tags fa-fw"></i> Gutscheincodes importieren</a>
|
||||
<a v-if="window['TT_CONFIG']['SHOW_MISC_BUTTONS'] === '1'" class="btn btn-purple ml-1" :href="window['TT_CONFIG']['PREORDER_STATUS_UPDATE_IMPORT_URL']">
|
||||
<i class="fas fa-retweet fa-fw"></i> Statusupdates importieren</a>
|
||||
</template>
|
||||
|
||||
<template v-slot:status="{ row: campaign }">
|
||||
<span class="fa-stack" title="Vorbestellkampagne aktiv" v-if="campaign.from <= Date.now()/1000 && campaign.to >= Date.now()/1000">
|
||||
<i class="fas fa-alarm-clock fa-stack-1x text-success" style="z-index:20"></i>
|
||||
<i class="fas fa-circle-check" style="color:Tomato;font-size:.7em"></i>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<template v-slot:add="{ row: campaign }">
|
||||
<a class="btn btn-sm btn-outline-primary" :href="window['TT_CONFIG']['ADD_PREORDER_URL'] + '?preordercampaign_id=' + campaign.id">
|
||||
<i class="fas fa-plus" title="Vorbestellung hinzufügen"></i></a>
|
||||
</template>
|
||||
|
||||
<template v-slot:progress="{ row: campaign }">
|
||||
<div class="campaign-grid">
|
||||
<a :href="window['TT_CONFIG']['VIEW_URL'] + '?filter[preordercampaign_id]=' + campaign.id" class="campaign-icon">
|
||||
<i class="fas fa-list-alt" title="Bestellungen anzeigen"></i></a>
|
||||
<div class="progress-grid">
|
||||
<template v-if="campaign.count_total_units.total_unit_count_sd > 0">
|
||||
<span>EFH:</span><span>{{ campaign.active_preorder_count.sd_count }} /</span>
|
||||
<span>{{ campaign.count_total_units.total_unit_count_sd }}</span>
|
||||
<span>({{ ((campaign.active_preorder_count.sd_count / campaign.count_total_units.total_unit_count_sd) * 100 || 0).toFixed(2) }} %)</span>
|
||||
</template>
|
||||
<template v-if="campaign.count_total_units.total_unit_count_md > 0">
|
||||
<span>MPH:</span><span>{{ campaign.active_preorder_count.md_count }} /</span>
|
||||
<span>{{ campaign.count_total_units.total_unit_count_md }}</span>
|
||||
<span>({{ ((campaign.active_preorder_count.md_count / campaign.count_total_units.total_unit_count_md) * 100 || 0).toFixed(2) }} %)</span>
|
||||
</template>
|
||||
<template v-if="campaign.count_total_units.total_unit_count > 0">
|
||||
<span>Gesamt:</span><span>{{ campaign.active_preorder_count.total_count }} /</span>
|
||||
<span>{{ campaign.count_total_units.total_unit_count * 2 }}</span>
|
||||
<span>({{ ((campaign.active_preorder_count.total_count / (campaign.count_total_units.total_unit_count * 2)) * 100 || 0).toFixed(1) }} %)</span>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-slot:from="{ row: campaign }">{{ formatDate(campaign.from) }}</template>
|
||||
<template v-slot:to="{ row: campaign }">{{ formatDate(campaign.to) }}</template>
|
||||
<template v-slot:rimo_workoders="{ row: campaign }">{{ campaign.rimo_workoders }} / {{ campaign.active_preorder_count.total_count }}</template>
|
||||
|
||||
<template v-slot:actions="{ row: campaign }">
|
||||
<div class="preorder-campaign-table-actions">
|
||||
<a :href="window['TT_CONFIG']['PREORDER_NOTIFICATION_URL'] + '?filter[preordercampaign_id]=' + campaign.id" title="Email Aussendungen"><i class="far fa-envelope"></i></a>
|
||||
<template v-if="window['TT_CONFIG']['IS_ADMIN'] === '1'">
|
||||
<a class="ml-2" :href="window['TT_CONFIG']['EDIT_URL'] + '?id=' + campaign.id"><i class="far fa-edit" title="Bearbeiten"></i></a>
|
||||
<a class="ml-2" :href="window['TT_CONFIG']['ADMIN_URL'] + '?id=' + campaign.id"><i class="far fa-a" title="Adminfunktionen"></i></a>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</tt-table>
|
||||
</tt-card>
|
||||
|
||||
`,
|
||||
|
||||
data() {
|
||||
return {
|
||||
window: window,
|
||||
PreordercampaignTableConfig: {
|
||||
key: 'PreordercampaignTable',
|
||||
tableHeader: 'Vorbestellkampagnen',
|
||||
defaultPageSize: 25,
|
||||
headers: [
|
||||
{text: 'Status', key: 'status', class: 'text-center',sortable: false,filter:false, priority: 20},
|
||||
{text: '', key: 'add', class: 'text-center',filter:false, sortable: false, priority: 18},
|
||||
{text: 'Netzgebiet', key: 'network_name', priority: 19},
|
||||
{text: 'Name', key: 'name', priority: 14},
|
||||
{text: 'Fortschritt', key: 'progress', priority: 17,filter:false,sortable: false},
|
||||
{text: 'Workorders', key: 'rimo_workoders', class: 'text-center', priority: 16,filter:false},
|
||||
{text: 'Von', key: 'from', class: 'text-center', priority: 13,filter:false,sortable: false},
|
||||
{text: 'Bis', key: 'to', class: 'text-center', priority: 12,filter:false,sortable: false},
|
||||
{text: 'Aktionen', key: 'actions', class: 'text-center', sortable: false, priority: 21,filter:false}
|
||||
],
|
||||
customRowClass: (row) => {
|
||||
if (row.from <= Date.now()/1000 && row.to >= Date.now()/1000) {
|
||||
return 'active';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (window.TT_CONFIG.IS_ADMIN === "1") {
|
||||
this.PreordercampaignTableConfig.headers.splice(3, 0, {text: 'Netzbesitzer', key: 'network_owner_name', priority: 4, filter: 'select', filterOptions: window['TT_CONFIG']['NETWORK_OWNER_OPTIONS']});
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
formatDate: date => window.moment(date * 1000).format('DD.MM.YYYY'),
|
||||
}
|
||||
});
|
||||
@@ -83,7 +83,7 @@
|
||||
}
|
||||
|
||||
.tt-table.table-sm > tbody > tr > td * {
|
||||
font-size: 13px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.tt-table.table-sm > tbody > tr {
|
||||
|
||||
@@ -66,8 +66,9 @@ Vue.component('tt-table-crud', {
|
||||
<tt-select v-show="crudModalColumnVisibility[column.key]" v-else-if="column.type === 'select'" v-model="crudModalData[column.key]" :label="column.text" :options="column.items" sm row/>
|
||||
<tt-autocomplete v-show="crudModalColumnVisibility[column.key]" v-else-if="column.type === 'autocomplete'" v-model="crudModalData[column.key]" :label="column.text" :api-url="column.apiUrl" :items="column.items" sm row :return-text="column.returnText" />
|
||||
<tt-date-picker v-show="crudModalColumnVisibility[column.key]" v-else-if="column.type === 'datepicker'" v-model="crudModalData[column.key]" :label="column.text" sm row :date-range="false" :ref="column.key.toLowerCase() + '-modal-input'"/>
|
||||
<tt-icon-select v-show="crudModalColumnVisibility[column.key]" v-else-if="column.type === 'icon-select'" v-model="crudModalData[column.key]" :label="column.text" sm row/>
|
||||
<tt-icon-select v-show="crudModalColumnVisibility[column.key]" v-else-if="column.type === 'icon-select'" v-model="crudModalData[column.key]" :options="column.items" :label="column.text" sm row/>
|
||||
<tt-checkbox v-show="crudModalColumnVisibility[column.key]" v-else-if="column.type === 'checkbox'" v-model="crudModalData[column.key]" :label="column.text" sm row/>
|
||||
<tt-positions-manager v-show="crudModalColumnVisibility[column.key]" v-else-if="column.type === 'positions-manager'" v-model="crudModalData[column.key]" :config="column.config" sm row/>
|
||||
</slot>
|
||||
<!-- @formatter:on -->
|
||||
</template>
|
||||
|
||||
@@ -825,16 +825,16 @@ Vue.component('tt-table', {
|
||||
}
|
||||
})
|
||||
|
||||
Vue.config.errorHandler = function (err, vm, info) {
|
||||
// still log errors to the console
|
||||
console.error(info, err, vm);
|
||||
|
||||
if (typeof vm.config.key === 'string') {
|
||||
// check if document.querySelector table.tt-table exists aswell if it has atleast 3 <tr> elements
|
||||
const table = document.querySelector('table.tt-table');
|
||||
if (!table || !table.querySelectorAll('tr').length > 2) {
|
||||
// localStorage.removeItem(`tt-table-${vm.config.key}`);
|
||||
// window.location.reload();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Vue.config.errorHandler = function (err, vm, info) {
|
||||
// // still log errors to the console
|
||||
// console.error(info, err, vm);
|
||||
//
|
||||
// if (typeof vm.config.key === 'string') {
|
||||
// // check if document.querySelector table.tt-table exists aswell if it has atleast 3 <tr> elements
|
||||
// const table = document.querySelector('table.tt-table');
|
||||
// if (!table || !table.querySelectorAll('tr').length > 2) {
|
||||
// // localStorage.removeItem(`tt-table-${vm.config.key}`);
|
||||
// // window.location.reload();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
Reference in New Issue
Block a user