Merge branch 'feature/conge-auto-full-day' into releases/release-h2f

This commit is contained in:
Narindra ezway 2025-03-27 18:05:13 +03:00
commit de431c0f95
62 changed files with 13664 additions and 6569 deletions

View File

@ -164570,7 +164570,7 @@ module.exports = /*#__PURE__*/JSON.parse('{"compressed":true,"categories":[{"id"
/******/ // This function allow to reference async chunks
/******/ __webpack_require__.u = (chunkId) => {
/******/ // return url for filenames based on template
/******/ return "calendar-" + chunkId + ".js?v=" + {"vendors-node_modules_nextcloud_capabilities_dist_index_js-node_modules_nextcloud_vue-select_d-877981":"7bde6f386631234ba146","vendors-node_modules_vue-material-design-icons_CalendarBlank_vue-node_modules_vue-material-de-e2c1f8":"2e0b0e8bc0e8488c397c","vendors-node_modules_path-browserify_index_js-node_modules_nextcloud_dialogs_dist_chunks_Dial-e0595f":"728c782d2751f8e6150a","node_modules_nextcloud_dialogs_dist_legacy_mjs":"8be838e4c6e9aae56c87","vendors-node_modules_webdav_dist_web_index_js":"454da8f908d41b47c607","vendors-node_modules_nextcloud_dialogs_dist_chunks_FilePicker-8ibBgPg__mjs":"ea54a36450de178d1141"}[chunkId] + "";
/******/ return "calendar-" + chunkId + ".js?v=" + {"vendors-node_modules_nextcloud_capabilities_dist_index_js-node_modules_nextcloud_vue-select_d-877981":"741d92f5ec54d0c1ff41","vendors-node_modules_vue-material-design-icons_CalendarBlank_vue-node_modules_vue-material-de-e2c1f8":"0658eb6db50a09dd2afe","vendors-node_modules_path-browserify_index_js-node_modules_nextcloud_dialogs_dist_chunks_Dial-e0595f":"e0f3178442f3c9eb35e1","node_modules_nextcloud_dialogs_dist_legacy_mjs":"8be838e4c6e9aae56c87","vendors-node_modules_webdav_dist_web_index_js":"454da8f908d41b47c607","vendors-node_modules_nextcloud_dialogs_dist_chunks_FilePicker-8ibBgPg__mjs":"ea54a36450de178d1141"}[chunkId] + "";
/******/ };
/******/ })();
/******/
@ -164827,4 +164827,4 @@ const visitorInfo = (0,_nextcloud_initial_state__WEBPACK_IMPORTED_MODULE_1__.loa
/******/ })()
;
//# sourceMappingURL=calendar-appointments-booking.js.map?v=b7719d864afe6419c183
//# sourceMappingURL=calendar-appointments-booking.js.map?v=312d2cc5b7ca549a9366

File diff suppressed because one or more lines are too long

View File

@ -37516,4 +37516,4 @@ const booking = (0,_nextcloud_initial_state__WEBPACK_IMPORTED_MODULE_1__.loadSta
/******/ })()
;
//# sourceMappingURL=calendar-appointments-confirmation.js.map?v=e09415d738d19b735882
//# sourceMappingURL=calendar-appointments-confirmation.js.map?v=a2ee83495b163cb419ce

File diff suppressed because one or more lines are too long

View File

@ -37552,4 +37552,4 @@ const booking = (0,_nextcloud_initial_state__WEBPACK_IMPORTED_MODULE_1__.loadSta
/******/ })()
;
//# sourceMappingURL=calendar-appointments-conflict.js.map?v=203b5778e2275f51e478
//# sourceMappingURL=calendar-appointments-conflict.js.map?v=b617e2fd0c187cf8a3ef

File diff suppressed because one or more lines are too long

View File

@ -160605,4 +160605,4 @@ vue__WEBPACK_IMPORTED_MODULE_5__["default"].prototype.$n = _nextcloud_l10n__WEBP
/******/ })()
;
//# sourceMappingURL=calendar-appointments-overview.js.map?v=11949b799a3d070cc45a
//# sourceMappingURL=calendar-appointments-overview.js.map?v=f24398268fe4a78a6630

File diff suppressed because one or more lines are too long

View File

@ -500,4 +500,4 @@ if(false) {}
/***/ })
}]);
//# sourceMappingURL=calendar-dashboard-lazy.js.map?v=0dd354a2fd4b9e38ddcf
//# sourceMappingURL=calendar-dashboard-lazy.js.map?v=60b7f707e08fff04c7a1

File diff suppressed because one or more lines are too long

View File

@ -1322,7 +1322,7 @@ function b(n) {
/******/ // This function allow to reference async chunks
/******/ __webpack_require__.u = (chunkId) => {
/******/ // return url for filenames based on template
/******/ return "calendar-" + chunkId + ".js?v=" + {"vendors-node_modules_nextcloud_capabilities_dist_index_js-node_modules_nextcloud_vue-select_d-877981":"7bde6f386631234ba146","vendors-node_modules_vue_dist_vue_runtime_esm_js":"7e3171593bdc0f62040b","vendors-node_modules_nextcloud_cdav-library_dist_dist_js-node_modules_nextcloud_logger_dist_i-36c16b":"c3b3db23da041c717fc1","vendors-node_modules_webdav_dist_web_index_js":"454da8f908d41b47c607","vendors-node_modules_vue-material-design-icons_CalendarBlankOutline_vue-node_modules_nextclou-4adead":"273df538e0dc19672feb","vendors-node_modules_nextcloud_vue-dashboard_dist_vue-dashboard_js-node_modules_css-loader_di-9e6f3d":"86eaa619747854c0da61","src_models_rfcProps_js-src_services_caldavService_js-src_services_talkService_js-src_services-8a2790":"7cf71b4f92d5bbc180b4","src_store_index_js":"b3c0e2be13c6c62873db","src_fullcalendar_eventSources_eventSourceFunction_js-src_utils_moment_js-data_image_svg_xml_3-b73258":"a830e20d5af09d6855dc","dashboard-lazy":"0dd354a2fd4b9e38ddcf","vendors-node_modules_vue-material-design-icons_CalendarBlank_vue-node_modules_vue-material-de-e2c1f8":"2e0b0e8bc0e8488c397c","vendors-node_modules_path-browserify_index_js-node_modules_nextcloud_dialogs_dist_chunks_Dial-e0595f":"728c782d2751f8e6150a","node_modules_nextcloud_dialogs_dist_legacy_mjs":"8be838e4c6e9aae56c87","vendors-node_modules_nextcloud_dialogs_dist_chunks_FilePicker-8ibBgPg__mjs":"ea54a36450de178d1141","vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96":"ce1bed825f57dd1d117a","node_modules_moment_locale_sync_recursive_":"4bc2c39c5e0ff182c2e3"}[chunkId] + "";
/******/ return "calendar-" + chunkId + ".js?v=" + {"vendors-node_modules_nextcloud_capabilities_dist_index_js-node_modules_nextcloud_vue-select_d-877981":"741d92f5ec54d0c1ff41","vendors-node_modules_vue_dist_vue_runtime_esm_js":"7e3171593bdc0f62040b","vendors-node_modules_nextcloud_cdav-library_dist_dist_js-node_modules_nextcloud_logger_dist_i-36c16b":"c3b3db23da041c717fc1","vendors-node_modules_webdav_dist_web_index_js":"454da8f908d41b47c607","vendors-node_modules_vue-material-design-icons_CalendarBlankOutline_vue-node_modules_nextclou-4adead":"01a7eb6779cc0e417f44","vendors-node_modules_nextcloud_vue-dashboard_dist_vue-dashboard_js-node_modules_css-loader_di-9e6f3d":"c2bd3081c493a88308a2","src_models_rfcProps_js-src_services_caldavService_js-src_services_talkService_js-src_services-8a2790":"870a881bc445f47fd3e0","src_store_index_js":"854eb1c42b63dedda92a","src_fullcalendar_eventSources_eventSourceFunction_js-src_utils_moment_js-data_image_svg_xml_3-b73258":"8bfde7d389740c269cd6","dashboard-lazy":"60b7f707e08fff04c7a1","vendors-node_modules_vue-material-design-icons_CalendarBlank_vue-node_modules_vue-material-de-e2c1f8":"0658eb6db50a09dd2afe","vendors-node_modules_path-browserify_index_js-node_modules_nextcloud_dialogs_dist_chunks_Dial-e0595f":"e0f3178442f3c9eb35e1","node_modules_nextcloud_dialogs_dist_legacy_mjs":"8be838e4c6e9aae56c87","vendors-node_modules_nextcloud_dialogs_dist_chunks_FilePicker-8ibBgPg__mjs":"ea54a36450de178d1141","vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96":"ce1bed825f57dd1d117a","node_modules_moment_locale_sync_recursive_":"4bc2c39c5e0ff182c2e3"}[chunkId] + "";
/******/ };
/******/ })();
/******/
@ -1580,4 +1580,4 @@ document.addEventListener('DOMContentLoaded', function () {
/******/ })()
;
//# sourceMappingURL=calendar-dashboard.js.map?v=9162dfb32cc95df9d030
//# sourceMappingURL=calendar-dashboard.js.map?v=dfa2e4156b37f7a69c4e

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -369,4 +369,4 @@ module.exports = /*#__PURE__*/JSON.parse('[{"country":"Algeria","filename":"Alge
/***/ })
}]);
//# sourceMappingURL=calendar-public-calendar-subscription-picker.js.map?v=9168fca99a878d4c37e3
//# sourceMappingURL=calendar-public-calendar-subscription-picker.js.map?v=0c8b5b050db3beb63d49

File diff suppressed because one or more lines are too long

View File

@ -8865,7 +8865,7 @@ window._registerCustomPickerElement = _;
/******/ // This function allow to reference async chunks
/******/ __webpack_require__.u = (chunkId) => {
/******/ // return url for filenames based on template
/******/ return "calendar-" + chunkId + ".js?v=" + {"vendors-node_modules_vue_dist_vue_runtime_esm_js":"7e3171593bdc0f62040b","vendors-node_modules_nextcloud_capabilities_dist_index_js-node_modules_nextcloud_vue-select_d-877981":"7bde6f386631234ba146","vendors-node_modules_nextcloud_cdav-library_dist_dist_js-node_modules_nextcloud_logger_dist_i-36c16b":"c3b3db23da041c717fc1","vendors-node_modules_vue-material-design-icons_CalendarBlank_vue-node_modules_vue-material-de-e2c1f8":"2e0b0e8bc0e8488c397c","vendors-node_modules_vue-material-design-icons_CalendarBlankOutline_vue-node_modules_nextclou-4adead":"273df538e0dc19672feb","vendors-node_modules_autosize_dist_autosize_esm_js-node_modules_html-entities_lib_index_js-no-4072c5":"56373f2063898525e8de","src_models_rfcProps_js-src_services_caldavService_js-src_services_talkService_js-src_services-8a2790":"7cf71b4f92d5bbc180b4","src_fullcalendar_eventSources_eventSourceFunction_js-src_utils_moment_js-data_image_svg_xml_3-b73258":"a830e20d5af09d6855dc","src_views_Calendar_vue-data_image_svg_xml_3csvg_20xmlns_27http_www_w3_org_2000_svg_27_20heigh-4a4254":"43b155c96a21c7810d4f","vendors-node_modules_webdav_dist_web_index_js":"454da8f908d41b47c607","src_store_index_js":"b3c0e2be13c6c62873db","vendors-node_modules_path-browserify_index_js-node_modules_nextcloud_dialogs_dist_chunks_Dial-e0595f":"728c782d2751f8e6150a","node_modules_nextcloud_dialogs_dist_legacy_mjs":"8be838e4c6e9aae56c87","vendors-node_modules_nextcloud_dialogs_dist_chunks_FilePicker-8ibBgPg__mjs":"ea54a36450de178d1141","public-calendar-subscription-picker":"9168fca99a878d4c37e3","vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96":"ce1bed825f57dd1d117a","node_modules_moment_locale_sync_recursive_":"4bc2c39c5e0ff182c2e3"}[chunkId] + "";
/******/ return "calendar-" + chunkId + ".js?v=" + {"vendors-node_modules_vue_dist_vue_runtime_esm_js":"7e3171593bdc0f62040b","vendors-node_modules_nextcloud_capabilities_dist_index_js-node_modules_nextcloud_vue-select_d-877981":"741d92f5ec54d0c1ff41","vendors-node_modules_nextcloud_cdav-library_dist_dist_js-node_modules_nextcloud_logger_dist_i-36c16b":"c3b3db23da041c717fc1","vendors-node_modules_vue-material-design-icons_CalendarBlank_vue-node_modules_vue-material-de-e2c1f8":"0658eb6db50a09dd2afe","vendors-node_modules_vue-material-design-icons_CalendarBlankOutline_vue-node_modules_nextclou-4adead":"01a7eb6779cc0e417f44","vendors-node_modules_autosize_dist_autosize_esm_js-node_modules_html-entities_lib_index_js-no-4072c5":"c3527b981de24f56109b","src_models_rfcProps_js-src_services_caldavService_js-src_services_talkService_js-src_services-8a2790":"870a881bc445f47fd3e0","src_fullcalendar_eventSources_eventSourceFunction_js-src_utils_moment_js-data_image_svg_xml_3-b73258":"8bfde7d389740c269cd6","src_views_Calendar_vue-data_image_svg_xml_3csvg_20xmlns_27http_www_w3_org_2000_svg_27_20heigh-4a4254":"cd491efe0949bd9d7d0f","vendors-node_modules_webdav_dist_web_index_js":"454da8f908d41b47c607","src_store_index_js":"854eb1c42b63dedda92a","vendors-node_modules_path-browserify_index_js-node_modules_nextcloud_dialogs_dist_chunks_Dial-e0595f":"e0f3178442f3c9eb35e1","node_modules_nextcloud_dialogs_dist_legacy_mjs":"8be838e4c6e9aae56c87","vendors-node_modules_nextcloud_dialogs_dist_chunks_FilePicker-8ibBgPg__mjs":"ea54a36450de178d1141","public-calendar-subscription-picker":"0c8b5b050db3beb63d49","vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96":"ce1bed825f57dd1d117a","node_modules_moment_locale_sync_recursive_":"4bc2c39c5e0ff182c2e3"}[chunkId] + "";
/******/ };
/******/ })();
/******/
@ -9115,4 +9115,4 @@ __webpack_require__.p = (0,_nextcloud_router__WEBPACK_IMPORTED_MODULE_1__.linkTo
/******/ })()
;
//# sourceMappingURL=calendar-reference.js.map?v=d5e354df7f94e54f1324
//# sourceMappingURL=calendar-reference.js.map?v=0ac1fcf77595c35c1331

File diff suppressed because one or more lines are too long

View File

@ -142,6 +142,14 @@ function eventSourceFunction(calendarObjects, calendar, start, end, timezone) {
if (isPrivateEvent && !isOwenOfEvent) {
title = (0,_nextcloud_l10n__WEBPACK_IMPORTED_MODULE_0__.translate)('calendar', "Absent (".concat(owenUser, ")"));
}
let absenceTypeIsLeave = false;
let absenceTypeProperties = object._properties.get('ABSENCETYPE');
if (absenceTypeProperties && absenceTypeProperties.length > 0) {
const absenceTypeValue = absenceTypeProperties[0]._value;
if (absenceTypeValue == 'LEAVE') {
absenceTypeIsLeave = true;
}
}
const fcEvent = {
id: [calendarObject.id, object.id].join('###'),
title,
@ -166,9 +174,15 @@ function eventSourceFunction(calendarObjects, calendar, start, end, timezone) {
description: object.description,
isPrivate: isPrivateEvent,
calendarObjectOwen: owenUser,
calendarObjectIsOwen: isOwenOfEvent
calendarObjectIsOwen: isOwenOfEvent,
absenceTypeIsLeave: absenceTypeIsLeave
}
};
if (absenceTypeIsLeave) {
fcEvent.backgroundColor = calendar.color;
fcEvent.borderColor = calendar.color;
fcEvent.textColor = (0,_utils_color_js__WEBPACK_IMPORTED_MODULE_1__.generateTextColorForHex)(calendar.color);
}
if (object.color) {
const customColor = (0,_utils_color_js__WEBPACK_IMPORTED_MODULE_1__.getHexForColorName)(object.color);
if (customColor) {
@ -1054,4 +1068,4 @@ module.exports = "data:image/svg+xml,%3csvg%20xmlns=%27http://www.w3.org/2000/sv
/***/ })
}]);
//# sourceMappingURL=calendar-src_fullcalendar_eventSources_eventSourceFunction_js-src_utils_moment_js-data_image_svg_xml_3-b73258.js.map?v=a830e20d5af09d6855dc
//# sourceMappingURL=calendar-src_fullcalendar_eventSources_eventSourceFunction_js-src_utils_moment_js-data_image_svg_xml_3-b73258.js.map?v=8bfde7d389740c269cd6

View File

@ -292,6 +292,10 @@ const getRFCProperties = () => {
placeholder: (0,_nextcloud_l10n__WEBPACK_IMPORTED_MODULE_0__.translate)('calendar', 'Choisir un client'),
icon: 'Human'
},
absenceType: {
readableName: (0,_nextcloud_l10n__WEBPACK_IMPORTED_MODULE_0__.translate)('calendar', 'Type d\'absence'),
placeholder: (0,_nextcloud_l10n__WEBPACK_IMPORTED_MODULE_0__.translate)('calendar', 'Type d\'absence')
},
embalmers: {
readableName: (0,_nextcloud_l10n__WEBPACK_IMPORTED_MODULE_0__.translate)('calendar', 'Embalmers'),
icon: 'Human',
@ -1826,4 +1830,4 @@ function GenColors(steps) {
/***/ })
}]);
//# sourceMappingURL=calendar-src_models_rfcProps_js-src_services_caldavService_js-src_services_talkService_js-src_services-8a2790.js.map?v=7cf71b4f92d5bbc180b4
//# sourceMappingURL=calendar-src_models_rfcProps_js-src_services_caldavService_js-src_services_talkService_js-src_services-8a2790.js.map?v=870a881bc445f47fd3e0

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -4331,7 +4331,9 @@ __webpack_require__.r(__webpack_exports__);
...(0,_fullcalendar_localization_localeProvider_js__WEBPACK_IMPORTED_MODULE_9__.getFullCalendarLocale)(),
// Rendering
dayHeaderDidMount: _fullcalendar_rendering_dayHeaderDidMount_js__WEBPACK_IMPORTED_MODULE_11__["default"],
eventDidMount: _fullcalendar_rendering_eventDidMount_js__WEBPACK_IMPORTED_MODULE_12__["default"],
eventDidMount: info => {
this.addAbsenceTypeEventClass(info);
},
noEventsDidMount: _fullcalendar_rendering_noEventsDidMount_js__WEBPACK_IMPORTED_MODULE_14__["default"],
eventOrder: ['start', '-duration', 'allDay', _fullcalendar_rendering_eventOrder_js__WEBPACK_IMPORTED_MODULE_13__["default"]],
forceEventDuration: false,
@ -4477,7 +4479,13 @@ __webpack_require__.r(__webpack_exports__);
initialView
});
}
}, 5000)
}, 5000),
addAbsenceTypeEventClass(info) {
if (info.event.extendedProps.absenceTypeIsLeave) {
info.el.style.backgroundColor = info.event.backgroundColor;
info.el.style.color = info.event.textColor;
}
}
}
});
@ -6013,6 +6021,66 @@ __webpack_require__.r(__webpack_exports__);
/***/ }),
/***/ "./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/lib/index.js??vue-loader-options!./src/components/Editor/Properties/PropertySelectAbsenceType.vue?vue&type=script&lang=js":
/*!****************************************************************************************************************************************************************************************************!*\
!*** ./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/lib/index.js??vue-loader-options!./src/components/Editor/Properties/PropertySelectAbsenceType.vue?vue&type=script&lang=js ***!
\****************************************************************************************************************************************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _nextcloud_vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @nextcloud/vue */ "./node_modules/@nextcloud/vue/dist/index.mjs");
/* harmony import */ var _mixins_PropertyMixin_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../mixins/PropertyMixin.js */ "./src/mixins/PropertyMixin.js");
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
name: 'PropertySelectAbsenceType',
components: {
NcSelect: _nextcloud_vue__WEBPACK_IMPORTED_MODULE_0__.NcSelect
},
props: {
isReadOnly: {
type: Boolean,
default: false // Par défaut, on permet la modification
}
},
data() {
return {
properties: [{
value: 'LEAVE',
label: 'Congé'
}, {
value: 'REST',
label: 'Repos'
}, {
value: 'DISEASE',
label: 'Maladie'
}]
};
},
mixins: [_mixins_PropertyMixin_js__WEBPACK_IMPORTED_MODULE_1__["default"]],
computed: {
options() {
return this.properties;
},
selectedValue() {
const value = this.value;
return this.properties.find(option => option.value == value);
}
},
methods: {
changeValue(selectedOption) {
var _selectedOption$value;
this.$emit('update:value', (_selectedOption$value = selectedOption.value) !== null && _selectedOption$value !== void 0 ? _selectedOption$value : null);
}
}
});
/***/ }),
/***/ "./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/lib/index.js??vue-loader-options!./src/components/Editor/Properties/PropertySelectAjax.vue?vue&type=script&lang=js":
/*!*********************************************************************************************************************************************************************************************!*\
!*** ./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/lib/index.js??vue-loader-options!./src/components/Editor/Properties/PropertySelectAjax.vue?vue&type=script&lang=js ***!
@ -8073,14 +8141,16 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var vue_material_design_icons_Download_vue__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! vue-material-design-icons/Download.vue */ "./node_modules/vue-material-design-icons/Download.vue");
/* harmony import */ var vue_material_design_icons_ContentDuplicate_vue__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! vue-material-design-icons/ContentDuplicate.vue */ "./node_modules/vue-material-design-icons/ContentDuplicate.vue");
/* harmony import */ var vue_material_design_icons_Pencil_vue__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! vue-material-design-icons/Pencil.vue */ "./node_modules/vue-material-design-icons/Pencil.vue");
/* harmony import */ var vuex__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! vuex */ "./node_modules/vuex/dist/vuex.esm.js");
/* harmony import */ var vuex__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! vuex */ "./node_modules/vuex/dist/vuex.esm.js");
/* harmony import */ var _components_Editor_Properties_PropertySelect_vue__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../components/Editor/Properties/PropertySelect.vue */ "./src/components/Editor/Properties/PropertySelect.vue");
/* harmony import */ var _components_Editor_Properties_PropertySelectAjax_vue__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../components/Editor/Properties/PropertySelectAjax.vue */ "./src/components/Editor/Properties/PropertySelectAjax.vue");
/* harmony import */ var _components_Editor_Properties_PropertySelectAjaxMultiple_vue__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../components/Editor/Properties/PropertySelectAjaxMultiple.vue */ "./src/components/Editor/Properties/PropertySelectAjaxMultiple.vue");
/* harmony import */ var _components_Editor_Properties_PropertySelectLieu_vue__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../components/Editor/Properties/PropertySelectLieu.vue */ "./src/components/Editor/Properties/PropertySelectLieu.vue");
/* harmony import */ var _components_Editor_Properties_PropertySelectClient_vue__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ../components/Editor/Properties/PropertySelectClient.vue */ "./src/components/Editor/Properties/PropertySelectClient.vue");
/* harmony import */ var _components_Editor_Properties_PropertySelectArticle_vue__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ../components/Editor/Properties/PropertySelectArticle.vue */ "./src/components/Editor/Properties/PropertySelectArticle.vue");
/* harmony import */ var _components_Editor_Properties_PropertyIsPrivate_vue__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ../components/Editor/Properties/PropertyIsPrivate.vue */ "./src/components/Editor/Properties/PropertyIsPrivate.vue");
/* harmony import */ var _components_Editor_Properties_PropertySelectAbsenceType_vue__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ../components/Editor/Properties/PropertySelectAbsenceType.vue */ "./src/components/Editor/Properties/PropertySelectAbsenceType.vue");
/* harmony import */ var _components_Editor_Properties_PropertyIsPrivate_vue__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ../components/Editor/Properties/PropertyIsPrivate.vue */ "./src/components/Editor/Properties/PropertyIsPrivate.vue");
@ -8114,13 +8184,14 @@ __webpack_require__.r(__webpack_exports__);
PropertySelectLieu: _components_Editor_Properties_PropertySelectLieu_vue__WEBPACK_IMPORTED_MODULE_20__["default"],
PropertySelectClient: _components_Editor_Properties_PropertySelectClient_vue__WEBPACK_IMPORTED_MODULE_21__["default"],
PropertySelectArticle: _components_Editor_Properties_PropertySelectArticle_vue__WEBPACK_IMPORTED_MODULE_22__["default"],
PropertyIsPrivate: _components_Editor_Properties_PropertyIsPrivate_vue__WEBPACK_IMPORTED_MODULE_23__["default"],
PropertyIsPrivate: _components_Editor_Properties_PropertyIsPrivate_vue__WEBPACK_IMPORTED_MODULE_24__["default"],
PropertySelect: _components_Editor_Properties_PropertySelect_vue__WEBPACK_IMPORTED_MODULE_17__["default"],
PopoverLoadingIndicator: _components_Popover_PopoverLoadingIndicator_vue__WEBPACK_IMPORTED_MODULE_6__["default"],
SaveButtons: _components_Editor_SaveButtons_vue__WEBPACK_IMPORTED_MODULE_5__["default"],
PropertyText: _components_Editor_Properties_PropertyText_vue__WEBPACK_IMPORTED_MODULE_4__["default"],
PropertyTitleTimePicker: _components_Editor_Properties_PropertyTitleTimePicker_vue__WEBPACK_IMPORTED_MODULE_3__["default"],
PropertyTitle: _components_Editor_Properties_PropertyTitle_vue__WEBPACK_IMPORTED_MODULE_2__["default"],
PropertySelectAbsenceType: _components_Editor_Properties_PropertySelectAbsenceType_vue__WEBPACK_IMPORTED_MODULE_23__["default"],
Popover: _nextcloud_vue__WEBPACK_IMPORTED_MODULE_0__.NcPopover,
Actions: _nextcloud_vue__WEBPACK_IMPORTED_MODULE_0__.NcActions,
ActionButton: _nextcloud_vue__WEBPACK_IMPORTED_MODULE_0__.NcActionButton,
@ -8149,7 +8220,7 @@ __webpack_require__.r(__webpack_exports__);
};
},
computed: {
...(0,vuex__WEBPACK_IMPORTED_MODULE_24__.mapState)({
...(0,vuex__WEBPACK_IMPORTED_MODULE_25__.mapState)({
hideEventExport: state => state.settings.hideEventExport,
widgetEventDetailsOpen: state => state.calendars.widgetEventDetailsOpen,
widgetEventDetails: state => state.calendars.widgetEventDetails,
@ -12908,6 +12979,53 @@ var staticRenderFns = [];
render._withStripped = true;
/***/ }),
/***/ "./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/lib/index.js??vue-loader-options!./src/components/Editor/Properties/PropertySelectAbsenceType.vue?vue&type=template&id=c8d0aea8&scoped=true":
/*!***************************************************************************************************************************************************************************************************************************************************************************************************!*\
!*** ./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/lib/index.js??vue-loader-options!./src/components/Editor/Properties/PropertySelectAbsenceType.vue?vue&type=template&id=c8d0aea8&scoped=true ***!
\***************************************************************************************************************************************************************************************************************************************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ render: () => (/* binding */ render),
/* harmony export */ staticRenderFns: () => (/* binding */ staticRenderFns)
/* harmony export */ });
var render = function render() {
var _vm = this,
_c = _vm._self._c;
return _c("div", {
staticClass: "property-select"
}, [_c("div", {
staticClass: "property-select__input",
class: {
"property-select__input--readonly": _vm.isReadOnly
}
}, [!_vm.isReadOnly ? _c("NcSelect", {
attrs: {
options: _vm.options,
searchable: true,
multiple: false,
taggable: false,
name: _vm.readableName,
value: _vm.selectedValue,
placeholder: _vm.placeholder,
clearable: true,
labelOutside: true,
"input-id": "value",
label: "label"
},
on: {
input: _vm.changeValue
}
}) : _c("div", [_vm._v(_vm._s(_vm.selectedValue.label))])], 1)]);
};
var staticRenderFns = [];
render._withStripped = true;
/***/ }),
/***/ "./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/lib/index.js??vue-loader-options!./src/components/Editor/Properties/PropertySelectAjax.vue?vue&type=template&id=3787864a&scoped=true":
@ -13647,17 +13765,7 @@ var render = function render() {
title: _vm.endTimezone,
size: 20
}
}) : _vm._e()], 1)] : _vm._e()], 2) : _vm._e(), _vm._v(" "), !_vm.isReadOnly ? _c("div", {
staticClass: "property-title-time-picker__all-day"
}, [_c("NcCheckboxRadioSwitch", {
attrs: {
checked: _vm.isAllDay,
disabled: !_vm.canModifyAllDay
},
on: {
"update:checked": _vm.toggleAllDay
}
}, [_vm._v("\n\t\t\t" + _vm._s(_vm.$t("calendar", "All day")) + "\n\t\t")])], 1) : _vm._e()], 1);
}) : _vm._e()], 1)] : _vm._e()], 2) : _vm._e()], 1);
};
var staticRenderFns = [];
render._withStripped = true;
@ -14410,7 +14518,31 @@ var render = function render() {
"update-end-timezone": _vm.updateEndTimezone,
"toggle-all-day": _vm.toggleAllDay
}
}), _vm._v(" "), _c("PropertyIsPrivate", {
}), _vm._v(" "), _c("div", {
staticStyle: {
display: "flex",
"margin-left": "7%"
}
}, [_c("div", {
staticStyle: {
width: "70%"
}
}, [_c("PropertySelectAbsenceType", {
attrs: {
value: _vm.absenceType,
"is-read-only": _vm.isReadOnly,
"prop-model": _vm.rfcProps.absenceType,
noWrap: true
},
on: {
"update:value": _vm.updateAbsenceType
}
})], 1), _vm._v(" "), _c("div", {
staticStyle: {
width: "30%",
"margin-top": "-11px"
}
}, [_c("PropertyIsPrivate", {
attrs: {
"is-read-only": _vm.isReadOnly,
"is-private": _vm.isPrivate
@ -14418,7 +14550,7 @@ var render = function render() {
on: {
"toggle-is-private": _vm.toggleIsPrivate
}
}), _vm._v(" "), _c("PropertySelectClient", {
})], 1)]), _vm._v(" "), _c("PropertySelectClient", {
staticClass: "property-location",
attrs: {
url: "/apps/gestion/ajaxGetClientsName",
@ -17224,7 +17356,7 @@ __webpack_require__.r(__webpack_exports__);
* Returns an object with properties from RFCs including
* their displayName, a description, options, etc.
*
* @return {{comment, geo, color, timeTransparency, description, resources, location, client, categories, accessClass, priority, status, locations, articles, clients,embalmer,embalmers}}
* @return {{absenceType, comment, geo, color, timeTransparency, description, resources, location, client, categories, accessClass, priority, status, locations, articles, clients,embalmer,embalmers}}
*/
rfcProps() {
return (0,_models_rfcProps_js__WEBPACK_IMPORTED_MODULE_0__.getRFCProperties)();
@ -17270,6 +17402,15 @@ __webpack_require__.r(__webpack_exports__);
return true;
}
return false;
},
/**
* Returns the absence type
*
* @return {string|null}
*/
absenceType() {
var _this$calendarObjectI30, _this$calendarObjectI31;
return (_this$calendarObjectI30 = (_this$calendarObjectI31 = this.calendarObjectInstance) === null || _this$calendarObjectI31 === void 0 ? void 0 : _this$calendarObjectI31.absenceType) !== null && _this$calendarObjectI30 !== void 0 ? _this$calendarObjectI30 : '';
}
},
methods: {
@ -17616,6 +17757,17 @@ __webpack_require__.r(__webpack_exports__);
watcher();
});
});
},
/**
* Updates the absence type of this event
*
* @param {string} absenceType New absence type
*/
updateAbsenceType(absenceType) {
this.$store.commit('changeAbsenceType', {
calendarObjectInstance: this.calendarObjectInstance,
absenceType
});
}
},
/**
@ -20594,6 +20746,35 @@ ___CSS_LOADER_EXPORT___.push([module.id, `.property-select__input[data-v-04aa9fc
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
/***/ }),
/***/ "./node_modules/css-loader/dist/cjs.js!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/resolve-url-loader/index.js!./node_modules/sass-loader/dist/cjs.js??clonedRuleSet-2.use[3]!./node_modules/vue-loader/lib/index.js??vue-loader-options!./src/components/Editor/Properties/PropertySelectAbsenceType.vue?vue&type=style&index=0&id=c8d0aea8&lang=scss&scoped=true":
/*!*****************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
!*** ./node_modules/css-loader/dist/cjs.js!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/resolve-url-loader/index.js!./node_modules/sass-loader/dist/cjs.js??clonedRuleSet-2.use[3]!./node_modules/vue-loader/lib/index.js??vue-loader-options!./src/components/Editor/Properties/PropertySelectAbsenceType.vue?vue&type=style&index=0&id=c8d0aea8&lang=scss&scoped=true ***!
\*****************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/***/ ((module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../../node_modules/css-loader/dist/runtime/noSourceMaps.js */ "./node_modules/css-loader/dist/runtime/noSourceMaps.js");
/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js");
/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);
// Imports
var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));
// Module
___CSS_LOADER_EXPORT___.push([module.id, `.property-select__input[data-v-c8d0aea8] {
width: calc(100% - 34px - 34px);
}`, ""]);
// Exports
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
/***/ }),
/***/ "./node_modules/css-loader/dist/cjs.js!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/resolve-url-loader/index.js!./node_modules/sass-loader/dist/cjs.js??clonedRuleSet-2.use[3]!./node_modules/vue-loader/lib/index.js??vue-loader-options!./src/components/Editor/Properties/PropertySelectAjax.vue?vue&type=style&index=0&id=3787864a&lang=scss&scoped=true":
@ -23157,6 +23338,47 @@ component.options.__file = "src/components/Editor/Properties/PropertySelect.vue"
/***/ }),
/***/ "./src/components/Editor/Properties/PropertySelectAbsenceType.vue":
/*!************************************************************************!*\
!*** ./src/components/Editor/Properties/PropertySelectAbsenceType.vue ***!
\************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _PropertySelectAbsenceType_vue_vue_type_template_id_c8d0aea8_scoped_true__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./PropertySelectAbsenceType.vue?vue&type=template&id=c8d0aea8&scoped=true */ "./src/components/Editor/Properties/PropertySelectAbsenceType.vue?vue&type=template&id=c8d0aea8&scoped=true");
/* harmony import */ var _PropertySelectAbsenceType_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./PropertySelectAbsenceType.vue?vue&type=script&lang=js */ "./src/components/Editor/Properties/PropertySelectAbsenceType.vue?vue&type=script&lang=js");
/* harmony import */ var _PropertySelectAbsenceType_vue_vue_type_style_index_0_id_c8d0aea8_lang_scss_scoped_true__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./PropertySelectAbsenceType.vue?vue&type=style&index=0&id=c8d0aea8&lang=scss&scoped=true */ "./src/components/Editor/Properties/PropertySelectAbsenceType.vue?vue&type=style&index=0&id=c8d0aea8&lang=scss&scoped=true");
/* harmony import */ var _node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! !../../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js */ "./node_modules/vue-loader/lib/runtime/componentNormalizer.js");
;
/* normalize component */
var component = (0,_node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_3__["default"])(
_PropertySelectAbsenceType_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__["default"],
_PropertySelectAbsenceType_vue_vue_type_template_id_c8d0aea8_scoped_true__WEBPACK_IMPORTED_MODULE_0__.render,
_PropertySelectAbsenceType_vue_vue_type_template_id_c8d0aea8_scoped_true__WEBPACK_IMPORTED_MODULE_0__.staticRenderFns,
false,
null,
"c8d0aea8",
null
)
/* hot reload */
if (false) { var api; }
component.options.__file = "src/components/Editor/Properties/PropertySelectAbsenceType.vue"
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (component.exports);
/***/ }),
/***/ "./src/components/Editor/Properties/PropertySelectAjax.vue":
/*!*****************************************************************!*\
!*** ./src/components/Editor/Properties/PropertySelectAjax.vue ***!
@ -24762,6 +24984,22 @@ __webpack_require__.r(__webpack_exports__);
/***/ }),
/***/ "./src/components/Editor/Properties/PropertySelectAbsenceType.vue?vue&type=script&lang=js":
/*!************************************************************************************************!*\
!*** ./src/components/Editor/Properties/PropertySelectAbsenceType.vue?vue&type=script&lang=js ***!
\************************************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _node_modules_babel_loader_lib_index_js_node_modules_vue_loader_lib_index_js_vue_loader_options_PropertySelectAbsenceType_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../../node_modules/babel-loader/lib/index.js!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./PropertySelectAbsenceType.vue?vue&type=script&lang=js */ "./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/lib/index.js??vue-loader-options!./src/components/Editor/Properties/PropertySelectAbsenceType.vue?vue&type=script&lang=js");
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_node_modules_babel_loader_lib_index_js_node_modules_vue_loader_lib_index_js_vue_loader_options_PropertySelectAbsenceType_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_0__["default"]);
/***/ }),
/***/ "./src/components/Editor/Properties/PropertySelectAjax.vue?vue&type=script&lang=js":
/*!*****************************************************************************************!*\
!*** ./src/components/Editor/Properties/PropertySelectAjax.vue?vue&type=script&lang=js ***!
@ -25965,6 +26203,23 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var _node_modules_babel_loader_lib_index_js_node_modules_vue_loader_lib_loaders_templateLoader_js_ruleSet_1_rules_3_node_modules_vue_loader_lib_index_js_vue_loader_options_PropertySelect_vue_vue_type_template_id_04aa9fca_scoped_true__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../../node_modules/babel-loader/lib/index.js!../../../../node_modules/vue-loader/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./PropertySelect.vue?vue&type=template&id=04aa9fca&scoped=true */ "./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/lib/index.js??vue-loader-options!./src/components/Editor/Properties/PropertySelect.vue?vue&type=template&id=04aa9fca&scoped=true");
/***/ }),
/***/ "./src/components/Editor/Properties/PropertySelectAbsenceType.vue?vue&type=template&id=c8d0aea8&scoped=true":
/*!******************************************************************************************************************!*\
!*** ./src/components/Editor/Properties/PropertySelectAbsenceType.vue?vue&type=template&id=c8d0aea8&scoped=true ***!
\******************************************************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ render: () => (/* reexport safe */ _node_modules_babel_loader_lib_index_js_node_modules_vue_loader_lib_loaders_templateLoader_js_ruleSet_1_rules_3_node_modules_vue_loader_lib_index_js_vue_loader_options_PropertySelectAbsenceType_vue_vue_type_template_id_c8d0aea8_scoped_true__WEBPACK_IMPORTED_MODULE_0__.render),
/* harmony export */ staticRenderFns: () => (/* reexport safe */ _node_modules_babel_loader_lib_index_js_node_modules_vue_loader_lib_loaders_templateLoader_js_ruleSet_1_rules_3_node_modules_vue_loader_lib_index_js_vue_loader_options_PropertySelectAbsenceType_vue_vue_type_template_id_c8d0aea8_scoped_true__WEBPACK_IMPORTED_MODULE_0__.staticRenderFns)
/* harmony export */ });
/* harmony import */ var _node_modules_babel_loader_lib_index_js_node_modules_vue_loader_lib_loaders_templateLoader_js_ruleSet_1_rules_3_node_modules_vue_loader_lib_index_js_vue_loader_options_PropertySelectAbsenceType_vue_vue_type_template_id_c8d0aea8_scoped_true__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../../node_modules/babel-loader/lib/index.js!../../../../node_modules/vue-loader/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./PropertySelectAbsenceType.vue?vue&type=template&id=c8d0aea8&scoped=true */ "./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/lib/index.js??vue-loader-options!./src/components/Editor/Properties/PropertySelectAbsenceType.vue?vue&type=template&id=c8d0aea8&scoped=true");
/***/ }),
/***/ "./src/components/Editor/Properties/PropertySelectAjax.vue?vue&type=template&id=3787864a&scoped=true":
@ -26790,6 +27045,23 @@ __webpack_require__.r(__webpack_exports__);
/* harmony reexport (unknown) */ __webpack_require__.d(__webpack_exports__, __WEBPACK_REEXPORT_OBJECT__);
/***/ }),
/***/ "./src/components/Editor/Properties/PropertySelectAbsenceType.vue?vue&type=style&index=0&id=c8d0aea8&lang=scss&scoped=true":
/*!*********************************************************************************************************************************!*\
!*** ./src/components/Editor/Properties/PropertySelectAbsenceType.vue?vue&type=style&index=0&id=c8d0aea8&lang=scss&scoped=true ***!
\*********************************************************************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_resolve_url_loader_index_js_node_modules_sass_loader_dist_cjs_js_clonedRuleSet_2_use_3_node_modules_vue_loader_lib_index_js_vue_loader_options_PropertySelectAbsenceType_vue_vue_type_style_index_0_id_c8d0aea8_lang_scss_scoped_true__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../../node_modules/vue-style-loader/index.js!../../../../node_modules/css-loader/dist/cjs.js!../../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../../node_modules/resolve-url-loader/index.js!../../../../node_modules/sass-loader/dist/cjs.js??clonedRuleSet-2.use[3]!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./PropertySelectAbsenceType.vue?vue&type=style&index=0&id=c8d0aea8&lang=scss&scoped=true */ "./node_modules/vue-style-loader/index.js!./node_modules/css-loader/dist/cjs.js!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/resolve-url-loader/index.js!./node_modules/sass-loader/dist/cjs.js??clonedRuleSet-2.use[3]!./node_modules/vue-loader/lib/index.js??vue-loader-options!./src/components/Editor/Properties/PropertySelectAbsenceType.vue?vue&type=style&index=0&id=c8d0aea8&lang=scss&scoped=true");
/* harmony import */ var _node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_resolve_url_loader_index_js_node_modules_sass_loader_dist_cjs_js_clonedRuleSet_2_use_3_node_modules_vue_loader_lib_index_js_vue_loader_options_PropertySelectAbsenceType_vue_vue_type_style_index_0_id_c8d0aea8_lang_scss_scoped_true__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_resolve_url_loader_index_js_node_modules_sass_loader_dist_cjs_js_clonedRuleSet_2_use_3_node_modules_vue_loader_lib_index_js_vue_loader_options_PropertySelectAbsenceType_vue_vue_type_style_index_0_id_c8d0aea8_lang_scss_scoped_true__WEBPACK_IMPORTED_MODULE_0__);
/* harmony reexport (unknown) */ var __WEBPACK_REEXPORT_OBJECT__ = {};
/* harmony reexport (unknown) */ for(const __WEBPACK_IMPORT_KEY__ in _node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_resolve_url_loader_index_js_node_modules_sass_loader_dist_cjs_js_clonedRuleSet_2_use_3_node_modules_vue_loader_lib_index_js_vue_loader_options_PropertySelectAbsenceType_vue_vue_type_style_index_0_id_c8d0aea8_lang_scss_scoped_true__WEBPACK_IMPORTED_MODULE_0__) if(__WEBPACK_IMPORT_KEY__ !== "default") __WEBPACK_REEXPORT_OBJECT__[__WEBPACK_IMPORT_KEY__] = () => _node_modules_vue_style_loader_index_js_node_modules_css_loader_dist_cjs_js_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_resolve_url_loader_index_js_node_modules_sass_loader_dist_cjs_js_clonedRuleSet_2_use_3_node_modules_vue_loader_lib_index_js_vue_loader_options_PropertySelectAbsenceType_vue_vue_type_style_index_0_id_c8d0aea8_lang_scss_scoped_true__WEBPACK_IMPORTED_MODULE_0__[__WEBPACK_IMPORT_KEY__]
/* harmony reexport (unknown) */ __webpack_require__.d(__webpack_exports__, __WEBPACK_REEXPORT_OBJECT__);
/***/ }),
/***/ "./src/components/Editor/Properties/PropertySelectAjax.vue?vue&type=style&index=0&id=3787864a&lang=scss&scoped=true":
@ -27516,6 +27788,27 @@ if(false) {}
/***/ }),
/***/ "./node_modules/vue-style-loader/index.js!./node_modules/css-loader/dist/cjs.js!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/resolve-url-loader/index.js!./node_modules/sass-loader/dist/cjs.js??clonedRuleSet-2.use[3]!./node_modules/vue-loader/lib/index.js??vue-loader-options!./src/components/Editor/Properties/PropertySelectAbsenceType.vue?vue&type=style&index=0&id=c8d0aea8&lang=scss&scoped=true":
/*!**********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
!*** ./node_modules/vue-style-loader/index.js!./node_modules/css-loader/dist/cjs.js!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/resolve-url-loader/index.js!./node_modules/sass-loader/dist/cjs.js??clonedRuleSet-2.use[3]!./node_modules/vue-loader/lib/index.js??vue-loader-options!./src/components/Editor/Properties/PropertySelectAbsenceType.vue?vue&type=style&index=0&id=c8d0aea8&lang=scss&scoped=true ***!
\**********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
// style-loader: Adds some css to the DOM by adding a <style> tag
// load the styles
var content = __webpack_require__(/*! !!../../../../node_modules/css-loader/dist/cjs.js!../../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../../node_modules/resolve-url-loader/index.js!../../../../node_modules/sass-loader/dist/cjs.js??clonedRuleSet-2.use[3]!../../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./PropertySelectAbsenceType.vue?vue&type=style&index=0&id=c8d0aea8&lang=scss&scoped=true */ "./node_modules/css-loader/dist/cjs.js!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/resolve-url-loader/index.js!./node_modules/sass-loader/dist/cjs.js??clonedRuleSet-2.use[3]!./node_modules/vue-loader/lib/index.js??vue-loader-options!./src/components/Editor/Properties/PropertySelectAbsenceType.vue?vue&type=style&index=0&id=c8d0aea8&lang=scss&scoped=true");
if(content.__esModule) content = content.default;
if(typeof content === 'string') content = [[module.id, content, '']];
if(content.locals) module.exports = content.locals;
// add the styles to the DOM
var add = (__webpack_require__(/*! !../../../../node_modules/vue-style-loader/lib/addStylesClient.js */ "./node_modules/vue-style-loader/lib/addStylesClient.js")["default"])
var update = add("23d09bee", content, false, {});
// Hot Module Replacement
if(false) {}
/***/ }),
/***/ "./node_modules/vue-style-loader/index.js!./node_modules/css-loader/dist/cjs.js!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/resolve-url-loader/index.js!./node_modules/sass-loader/dist/cjs.js??clonedRuleSet-2.use[3]!./node_modules/vue-loader/lib/index.js??vue-loader-options!./src/components/Editor/Properties/PropertySelectAjax.vue?vue&type=style&index=0&id=3787864a&lang=scss&scoped=true":
/*!***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
!*** ./node_modules/vue-style-loader/index.js!./node_modules/css-loader/dist/cjs.js!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/resolve-url-loader/index.js!./node_modules/sass-loader/dist/cjs.js??clonedRuleSet-2.use[3]!./node_modules/vue-loader/lib/index.js??vue-loader-options!./src/components/Editor/Properties/PropertySelectAjax.vue?vue&type=style&index=0&id=3787864a&lang=scss&scoped=true ***!
@ -27707,4 +28000,4 @@ module.exports = "data:image/svg+xml,%3csvg%20xmlns=%27http://www.w3.org/2000/sv
/***/ })
}]);
//# sourceMappingURL=calendar-src_views_Calendar_vue-data_image_svg_xml_3csvg_20xmlns_27http_www_w3_org_2000_svg_27_20heigh-4a4254.js.map?v=43b155c96a21c7810d4f
//# sourceMappingURL=calendar-src_views_Calendar_vue-data_image_svg_xml_3csvg_20xmlns_27http_www_w3_org_2000_svg_27_20heigh-4a4254.js.map?v=cd491efe0949bd9d7d0f

View File

@ -42554,4 +42554,4 @@ function hasInjectionContext() {
/***/ })
}]);
//# sourceMappingURL=calendar-vendors-node_modules_autosize_dist_autosize_esm_js-node_modules_html-entities_lib_index_js-no-4072c5.js.map?v=56373f2063898525e8de
//# sourceMappingURL=calendar-vendors-node_modules_autosize_dist_autosize_esm_js-node_modules_html-entities_lib_index_js-no-4072c5.js.map?v=c3527b981de24f56109b

View File

@ -21864,4 +21864,4 @@ const webNamespaces = {
/***/ })
}]);
//# sourceMappingURL=calendar-vendors-node_modules_nextcloud_capabilities_dist_index_js-node_modules_nextcloud_vue-select_d-877981.js.map?v=7bde6f386631234ba146
//# sourceMappingURL=calendar-vendors-node_modules_nextcloud_capabilities_dist_index_js-node_modules_nextcloud_vue-select_d-877981.js.map?v=741d92f5ec54d0c1ff41

View File

@ -27285,4 +27285,4 @@ window._registerCustomPickerElement = _;
/***/ })
}]);
//# sourceMappingURL=calendar-vendors-node_modules_nextcloud_vue-dashboard_dist_vue-dashboard_js-node_modules_css-loader_di-9e6f3d.js.map?v=86eaa619747854c0da61
//# sourceMappingURL=calendar-vendors-node_modules_nextcloud_vue-dashboard_dist_vue-dashboard_js-node_modules_css-loader_di-9e6f3d.js.map?v=c2bd3081c493a88308a2

View File

@ -80146,4 +80146,4 @@ module.exports = /*#__PURE__*/JSON.parse('{"compressed":true,"categories":[{"id"
/***/ })
}]);
//# sourceMappingURL=calendar-vendors-node_modules_path-browserify_index_js-node_modules_nextcloud_dialogs_dist_chunks_Dial-e0595f.js.map?v=728c782d2751f8e6150a
//# sourceMappingURL=calendar-vendors-node_modules_path-browserify_index_js-node_modules_nextcloud_dialogs_dist_chunks_Dial-e0595f.js.map?v=e0f3178442f3c9eb35e1

View File

@ -102420,4 +102420,4 @@ module.exports = /*#__PURE__*/JSON.parse('{"compressed":true,"categories":[{"id"
/***/ })
}]);
//# sourceMappingURL=calendar-vendors-node_modules_vue-material-design-icons_CalendarBlankOutline_vue-node_modules_nextclou-4adead.js.map?v=273df538e0dc19672feb
//# sourceMappingURL=calendar-vendors-node_modules_vue-material-design-icons_CalendarBlankOutline_vue-node_modules_nextclou-4adead.js.map?v=01a7eb6779cc0e417f44

View File

@ -2030,4 +2030,4 @@ render._withStripped = true
/***/ })
}]);
//# sourceMappingURL=calendar-vendors-node_modules_vue-material-design-icons_CalendarBlank_vue-node_modules_vue-material-de-e2c1f8.js.map?v=2e0b0e8bc0e8488c397c
//# sourceMappingURL=calendar-vendors-node_modules_vue-material-design-icons_CalendarBlank_vue-node_modules_vue-material-de-e2c1f8.js.map?v=0658eb6db50a09dd2afe

17467
calendar/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -91,8 +91,8 @@
"npm": "^10.0.0"
},
"devDependencies": {
"@babel/core": "^7.24.0",
"@babel/preset-env": "^7.24.0",
"@babel/core": "^7.26.10",
"@babel/preset-env": "^7.26.9",
"@nextcloud/babel-config": "^1.0.0",
"@nextcloud/browserslist-config": "^3.0.0",
"@nextcloud/eslint-config": "^8.3.0",
@ -101,6 +101,7 @@
"@vue/test-utils": "^1.3.6",
"@vue/vue2-jest": "^29.2.6",
"babel-jest": "^29.7.0",
"babel-loader": "^9.2.1",
"babel-loader-exclude-node-modules-except": "^1.2.1",
"ical.js": "^1.5.0",
"jest": "^29.7.0",
@ -108,7 +109,10 @@
"jest-serializer-vue": "^3.1.0",
"npm-force-resolutions": "^0.0.10",
"resolve-url-loader": "^5.0.0",
"vue-template-compiler": "^2.7.16"
"vue-loader": "^15.11.1",
"vue-template-compiler": "^2.7.16",
"webpack": "^5.98.0",
"webpack-cli": "^5.1.4"
},
"optionalDependencies": {
"fsevents": "^2.3.3"

View File

@ -139,7 +139,9 @@ export default {
...getFullCalendarLocale(),
// Rendering
dayHeaderDidMount,
eventDidMount,
eventDidMount : (info) => {
this.addAbsenceTypeEventClass(info);
},
noEventsDidMount,
eventOrder: ['start', '-duration', 'allDay', eventOrder],
forceEventDuration: false,
@ -303,6 +305,12 @@ export default {
this.$store.dispatch('setInitialView', { initialView })
}
}, 5000),
addAbsenceTypeEventClass(info){
if (info.event.extendedProps.absenceTypeIsLeave) {
info.el.style.backgroundColor = info.event.backgroundColor;
info.el.style.color = info.event.textColor;
}
}
},
}
</script>

View File

@ -0,0 +1,72 @@
<template>
<div class="property-select">
<div class="property-select__input"
:class="{ 'property-select__input--readonly': isReadOnly }">
<NcSelect v-if="!isReadOnly"
:options="options"
:searchable="true"
:multiple="false"
:taggable="false"
:name="readableName"
:value="selectedValue"
:placeholder="placeholder"
:clearable="true"
:labelOutside="true"
input-id="value"
label="label"
@input="changeValue" />
<div v-else>{{ selectedValue.label }}</div>
</div>
</div>
</template>
<script>
import { NcSelect } from '@nextcloud/vue';
import PropertyMixin from '../../../mixins/PropertyMixin.js'
export default {
name: 'PropertySelectAbsenceType',
components: {
NcSelect,
},
props: {
isReadOnly: {
type: Boolean,
default: false, // Par défaut, on permet la modification
}
},
data() {
return {
properties: [
{ value: 'LEAVE', label: 'Congé' },
{ value: 'REST', label: 'Repos' },
{ value: 'DISEASE', label: 'Maladie' },
],
};
},
mixins: [
PropertyMixin,
],
computed: {
options() {
return this.properties;
},
selectedValue() {
const value = this.value
return this.properties.find((option) => option.value == value)
},
},
methods: {
changeValue(selectedOption) {
this.$emit('update:value', selectedOption.value ?? null);
},
},
};
</script>
<style lang="scss" scoped>
.property-select {
&__input {
width: calc(100% - 34px - 34px);
}
}
</style>

View File

@ -75,13 +75,13 @@
</template>
</div>
<div v-if="!isReadOnly" class="property-title-time-picker__all-day">
<!-- <div v-if="!isReadOnly" class="property-title-time-picker__all-day">
<NcCheckboxRadioSwitch :checked="isAllDay"
:disabled="!canModifyAllDay"
@update:checked="toggleAllDay">
{{ $t('calendar', 'All day') }}
</NcCheckboxRadioSwitch>
</div>
</div> -->
</div>
</template>

View File

@ -143,6 +143,15 @@ export function eventSourceFunction(calendarObjects, calendar, start, end, timez
if (isPrivateEvent && !isOwenOfEvent ) {
title = t('calendar', `Absent (${owenUser})`)
}
let absenceTypeIsLeave = false;
let absenceTypeProperties = object._properties.get('ABSENCETYPE');
if (absenceTypeProperties && absenceTypeProperties.length > 0) {
const absenceTypeValue = absenceTypeProperties[0]._value
if(absenceTypeValue == 'LEAVE'){
absenceTypeIsLeave = true;
}
}
const fcEvent = {
id: [calendarObject.id, object.id].join('###'),
@ -171,9 +180,16 @@ export function eventSourceFunction(calendarObjects, calendar, start, end, timez
isPrivate: isPrivateEvent,
calendarObjectOwen : owenUser ,
calendarObjectIsOwen : isOwenOfEvent,
absenceTypeIsLeave : absenceTypeIsLeave
},
}
if(absenceTypeIsLeave){
fcEvent.backgroundColor = calendar.color
fcEvent.borderColor = calendar.color
fcEvent.textColor = generateTextColorForHex(calendar.color)
}
if (object.color) {
const customColor = getHexForColorName(object.color)
if (customColor) {
@ -183,6 +199,8 @@ export function eventSourceFunction(calendarObjects, calendar, start, end, timez
}
}
fcEvents.push(fcEvent)
}
}

View File

@ -360,7 +360,7 @@ export default {
* Returns an object with properties from RFCs including
* their displayName, a description, options, etc.
*
* @return {{comment, geo, color, timeTransparency, description, resources, location, client, categories, accessClass, priority, status, locations, articles, clients,embalmer,embalmers}}
* @return {{absenceType, comment, geo, color, timeTransparency, description, resources, location, client, categories, accessClass, priority, status, locations, articles, clients,embalmer,embalmers}}
*/
rfcProps() {
return getRFCProperties()
@ -412,6 +412,15 @@ export default {
return false
},
/**
* Returns the absence type
*
* @return {string|null}
*/
absenceType() {
return this.calendarObjectInstance?.absenceType ?? ''
},
},
methods: {
/**
@ -770,6 +779,19 @@ export default {
})
})
},
/**
* Updates the absence type of this event
*
* @param {string} absenceType New absence type
*/
updateAbsenceType(absenceType) {
this.$store.commit('changeAbsenceType', {
calendarObjectInstance: this.calendarObjectInstance,
absenceType,
})
}
},
/**
* This is executed before entering the Editor routes

View File

@ -60,6 +60,8 @@ const getDefaultEventObject = (props = {}) => Object.assign({}, {
client : null,
//embalmer(Thanato) of the event
embalmer : null,
//absenceType
absenceType : null,
//Private
isPrivate: false,
//comment of the event
@ -114,6 +116,7 @@ const mapEventComponentToEventObject = (eventComponent) => {
client : "CLIENT",
embalmer : "TEST",
comment : "",
absenceType : "",
description: eventComponent.description,
accessClass: eventComponent.accessClass,
status: eventComponent.status,
@ -215,6 +218,10 @@ const mapEventComponentToEventObject = (eventComponent) => {
eventObject.comment = eventComponent.getFirstPropertyFirstValue('COMMENT');
}
if(eventComponent.hasProperty('ABSENCETYPE')){
eventObject.absenceType = eventComponent.getFirstPropertyFirstValue('ABSENCETYPE');
}
return eventObject;
}

View File

@ -141,6 +141,10 @@ const getRFCProperties = () => {
placeholder: t('calendar', 'Choisir un client'),
icon: 'Human',
},
absenceType: {
readableName: t('calendar', 'Type d\'absence'),
placeholder: t('calendar', 'Type d\'absence'),
},
embalmers: {
readableName: t('calendar', 'Embalmers'),

View File

@ -377,6 +377,44 @@ const mutations = {
calendarObjectInstance.embalmer = embalmer
},
/**
* Change the absence type of an event
*
* @param {object} state The Vuex state
* @param {object} data The destructuring object
* @param {object} data.calendarObjectInstance The calendarObjectInstance object
* @param {string} data.embalmer New embalmer to set
*/
changeAbsenceType(state, { calendarObjectInstance, absenceType }) {
calendarObjectInstance.eventComponent.absenceType = absenceType ?? null
calendarObjectInstance.absenceType = absenceType ?? null
if(absenceType){
const types = [
{ value: 'LEAVE', label: 'Congé' },
{ value: 'REST', label: 'Repos' },
{ value: 'DISEASE', label: 'Arret maladie' },
];
types.forEach((element) => {
if(element.value == absenceType){
calendarObjectInstance.title = element.label
calendarObjectInstance.eventComponent.title = element.label
if(absenceType == 'LEAVE'){
const startDate = calendarObjectInstance.eventComponent.startDate
const endDate = calendarObjectInstance.eventComponent.endDate
startDate.hour = 8 ; endDate.hour = 17
calendarObjectInstance.startDate = getDateFromDateTimeValue(startDate)
calendarObjectInstance.endDate = getDateFromDateTimeValue(endDate)
}
}
})
}
},
/**
* Change the description of an event
*
@ -1526,6 +1564,11 @@ const mutations = {
}
},
setAbsenceType(state, { calendarObjectInstance, absenceType }) {
if (calendarObjectInstance) {
calendarObjectInstance.absenceType = absenceType;
}
},
}
const getters = {}
@ -1718,6 +1761,7 @@ const actions = {
let additionalFieldWasUpdated =
eventComponent.client != null ||
eventComponent.isPrivate != null ||
eventComponent.absenceType ||
eventComponent.comment != null ;
if (eventComponent.isDirty() || additionalFieldWasUpdated) {
const isForkedItem = eventComponent.primaryItem !== null
@ -2138,6 +2182,13 @@ const actions = {
commit('changeTimeToDefaultForTimedEvents', { calendarObjectInstance })
}
},
// async changeAbsenceType({ commit }, { calendarObjectInstance, absenceType }) {
// try {
// commit('setAbsenceType', { calendarObjectInstance, absenceType });
// } catch (error) {
// console.error('Erreur lors de la mise à jour du type d\'absence:', error);
// }
// },
}

View File

@ -273,6 +273,20 @@ const actions = {
icsValue = setCustomKeyValuesArrayToIcsAndReturnIcs(icsValue,customKeyValue);
}
}
if(eventComponent.absenceType != null && eventComponent.absenceType != ''){
let absenceTypeValue = eventComponent.absenceType;
let key = "ABSENCETYPE:"+absenceTypeValue;
let regex = /^ABSENCETYPE:.*$/m;
if(regex.test(icsValue)){
icsValue = icsValue.replace(regex, key);
}
else{
const customKeyValue = {
"ABSENCETYPE": absenceTypeValue
};
icsValue = setCustomKeyValuesArrayToIcsAndReturnIcs(icsValue,customKeyValue);
}
}
}
calendarObject.dav.data = icsValue;
@ -293,7 +307,8 @@ const actions = {
"CLIENT": eventComponent.client,
"EMBALMER": eventComponent.embalmer ,
"ISPRIVATE": eventComponent.isPrivate ? "1" : "0",
"COMMENT": eventComponent.comment
"COMMENT": eventComponent.comment,
"ABSENCETYPE": eventComponent.absenceType ?? ''
};
icsValue = setCustomKeyValuesArrayToIcsAndReturnIcs(icsValue,customKeyValue);
}

View File

@ -103,11 +103,26 @@
@update-end-timezone="updateEndTimezone"
@toggle-all-day="toggleAllDay" />
<PropertyIsPrivate
:is-read-only="isReadOnly"
:is-private="isPrivate"
@toggle-is-private="toggleIsPrivate"
/>
<div style='display:flex ;margin-left: 8px;'>
<div style='width:70%'>
<PropertySelectAbsenceType
:value="absenceType"
:is-read-only="isReadOnly"
:prop-model="rfcProps.absenceType"
:noWrap='true'
@update:value="updateAbsenceType" />
</div>
<div style='width:30% ;margin-top: -11px;'>
<PropertyIsPrivate
:is-read-only="isReadOnly"
:is-private="isPrivate"
@toggle-is-private="toggleIsPrivate"
/>
</div>
</div>
<PropertySelectClient class="property-location"
url="/apps/gestion/ajaxGetClientsName"
@ -361,6 +376,7 @@ import PropertySelectLieu from "../components/Editor/Properties/PropertySelectLi
import PropertySelectClient from "../components/Editor/Properties/PropertySelectClient.vue";
import PropertySelectArticle from "../components/Editor/Properties/PropertySelectArticle.vue";
import PropertyIsPrivate from "../components/Editor/Properties/PropertyIsPrivate.vue";
import PropertySelectAbsenceType from "../components/Editor/Properties/PropertySelectAbsenceType.vue";
export default {
@ -402,6 +418,7 @@ export default {
AttachmentsList,
CalendarPickerHeader,
PropertyTitle,
PropertySelectAbsenceType
},
mixins: [
EditorMixin,

View File

@ -106,7 +106,7 @@
<PropertyTitle :value="titleOrPlaceholder"
:is-read-only="isReadOnlyOrViewing"
@update:value="updateTitle" />
<PropertyTitleTimePicker :start-date="startDate"
:start-timezone="startTimezone"
:end-date="endDate"
@ -121,11 +121,27 @@
@update-end-timezone="updateEndTimezone"
@toggle-all-day="toggleAllDay" />
<PropertyIsPrivate
:is-read-only="isReadOnly"
:is-private="isPrivate"
@toggle-is-private="toggleIsPrivate"
/>
<div style='display:flex ;margin-left: 7%;'>
<div style='width:70%'>
<PropertySelectAbsenceType
:value="absenceType"
:is-read-only="isReadOnly"
:prop-model="rfcProps.absenceType"
:noWrap='true'
@update:value="updateAbsenceType" />
</div>
<div style='width:30% ;margin-top: -11px;'>
<PropertyIsPrivate
:is-read-only="isReadOnly"
:is-private="isPrivate"
@toggle-is-private="toggleIsPrivate"/>
</div>
</div>
<PropertySelectClient class="property-location"
url="/apps/gestion/ajaxGetClientsName"
@ -238,6 +254,7 @@ import PropertySelectAjaxMultiple from "../components/Editor/Properties/Property
import PropertySelectLieu from "../components/Editor/Properties/PropertySelectLieu.vue";
import PropertySelectClient from "../components/Editor/Properties/PropertySelectClient.vue";
import PropertySelectArticle from "../components/Editor/Properties/PropertySelectArticle.vue";
import PropertySelectAbsenceType from "../components/Editor/Properties/PropertySelectAbsenceType.vue";
import PropertyIsPrivate from "../components/Editor/Properties/PropertyIsPrivate.vue";
export default {
@ -255,6 +272,7 @@ export default {
PropertyText,
PropertyTitleTimePicker,
PropertyTitle,
PropertySelectAbsenceType,
Popover,
Actions,
ActionButton,

View File

@ -0,0 +1,10 @@
<?php
declare(strict_types=1);
namespace OCA\Gestion\Constants;
abstract class AbsenceTypeConstant
{
const LEAVE = "LEAVE";
const DISEASE = "DISEASE";
const REST = "REST";
}

View File

@ -5,4 +5,17 @@ namespace OCA\Gestion\Constants;
abstract class VCalendarPropertyConstant
{
const PROPERTY_IS_LEAVE = "ISPRIVATE";
const ABSENCE_TYPE = "ABSENCETYPE";
const ABSENCE_TYPES = [
AbsenceTypeConstant::LEAVE,
AbsenceTypeConstant::REST,
AbsenceTypeConstant::DISEASE
];
const ABSENCE_TYPES_KEYS_VALUES = [
AbsenceTypeConstant::LEAVE => "CONGE",
AbsenceTypeConstant::REST => "REPOS",
AbsenceTypeConstant::DISEASE => "MALADIE"
];
}

View File

@ -2605,30 +2605,8 @@ class PageController extends Controller {
}
$month = $month ?? date('m');
$year = $year ?? date('Y');
$exportData = $this->myDb->getExportThanatoStatisticData($thanatoIdsToExport,$month,$year);
try{
$current_config = json_decode($this->myDb->getConfiguration($this->idNextcloud));
$clean_folder = html_entity_decode($current_config[0]->path).'/';
$thanatoList = $this->myDb->getThanatoByIds($thanatoIdsToExport);
$thanatoFolders = $this->exportThanatoStatisticService->getThanatoStatisticFolders($thanatoList,$year);
$fileHeader = $this->exportThanatoStatisticService->getExportThanatoFileHeader();
$fileContent = $this->exportThanatoStatisticService->populateExportDataIntoFileContent($exportData,$fileHeader);
$filename = $this->exportThanatoStatisticService->getFilename($thanatoList,$month,$year);
$filenames = [];
foreach($thanatoFolders as $thanatoFolder){
$fullPath = $clean_folder.$thanatoFolder;
try {
$this->storage->newFolder($fullPath);
}
catch(\OCP\Files\NotPermittedException $e) {
}
$fileNamePath = $fullPath."STAT-THANATOS-" . $filename . '.csv';
$this->storage->newFile($fileNamePath);
$file = $this->storage->get($fileNamePath);
$file->putContent($fileContent);
$filenames[] = $fileNamePath;
}
$filenames = $this->exportThanatoStatisticService->exportThanatosListStatistic($thanatoIdsToExport,$month,$year,$this->idNextcloud);
return $filenames;
}
catch(\OCP\Files\NotFoundException $e) { }

View File

@ -9,6 +9,7 @@ use OCA\Gestion\Helpers\VCalendarHelpers;
use OCP\IDBConnection;
use OCP\IL10N;
use \Datetime;
use OCA\Gestion\Constants\VCalendarPropertyConstant;
use OCA\Gestion\Helpers\FileExportHelpers;
class Bdd {
@ -2093,10 +2094,9 @@ class Bdd {
$this->calculer_distance_trajet($ligne_trajet->id_trajet, $idNextcloud);
}
public function getExportThanatoStatisticData(array $thanatoIds,$month,$year){
$devisList = $this->getDevisListByThanatoIds($thanatoIds,$month,$year);
$devisListGroupedByDateAndThenByThanato = $this->getDevisListGroupedByDateAndThenByThanato($devisList);
return $devisListGroupedByDateAndThenByThanato;
public function getExportThanatoStatisticData($thanatoId,$month,$year){
$devisList = $this->getThanatoDevisPerDateInAMonthYear($thanatoId,$month,$year);
return $devisList;
}
private function getDevisListByThanatoIds(array $thanatoIds,$month,$year){
@ -2219,6 +2219,8 @@ class Bdd {
$devisTimeValue = VCalendarHelpers::GetStartAndEndTimeFromVCalendarString($calendarData);
$devis["startTime"] = $devisTimeValue["startTime"];
$devis["endTime"] = $devisTimeValue["endTime"];
$devis["totalHours"] = $devisTimeValue["totalHours"];
$devis["totalWorkedHours"] = $devisTimeValue["totalWorkedHours"];
return $devis;
}
@ -3355,4 +3357,204 @@ class Bdd {
return $message;
}
public function getThanatoById($thanatoId){
$sql = "SELECT id, nom, prenom,fk_user_uuid FROM ".$this->tableprefix."thanato WHERE id = ? LIMIT 1;";
$thanato = $this->execSQLNoJsonReturn($sql,[$thanatoId]);
if(!empty($thanato)){
return $thanato[0];
}
return null;
}
private function getCalendarByThanatoIdNextcloud($idNextCloud){
$searchString = "%principals/users/$idNextCloud%";
$sql = "SELECT * FROM ".self::DEFAULT_TABLE_PREFIX."calendars as calendar WHERE calendar.principaluri LIKE ? LIMIT 1;";
$calendar = $this->execSQLNoJsonReturn($sql,[$searchString]);
if(!empty($calendar)){
return $calendar[0];
}
return null;
}
private function getThanatoDevisListByDate($thanatoId,$date){
$dateFormatted = $date->format('Y-m-d');
$sql = "SELECT
devis.id,
devis.date,
devis.mentions,
devis.num as calendar_uuid,
devis.id_defunt as id_defunt,
devis.id_lieu as id_lieu,
devis.id_client as id_client,
devis.id_thanato as id_thanato,
thanato.nom as nom_thanato,
thanato.prenom as prenom_thanato,
defunt.nom as nom_defunt,
lieu.nom as nom_lieu,
lieu.latitude as lieu_latitude,
lieu.longitude as lieu_longitude,
client.nom as nom_client,
client.entreprise as client_entreprise,
client.adresse as client_adresse,
facture.num as facture_num
FROM ".$this->tableprefix."devis as devis
LEFT JOIN ".$this->tableprefix."thanato as thanato on devis.id_thanato = thanato.id
LEFT JOIN ".$this->tableprefix."lieu as lieu on devis.id_lieu = lieu.id
LEFT JOIN ".$this->tableprefix."defunt as defunt on devis.id_defunt = defunt.id
LEFT JOIN ".$this->tableprefix."client as client on devis.id_client = client.id
LEFT JOIN ".$this->tableprefix."facture as facture on devis.id = facture.id_devis
WHERE devis.date = ? AND
devis.id_thanato = ? AND
(devis.mentions = ? OR devis.mentions = ?)
ORDER BY devis.date ASC;";
$devisList = $this->execSQLNoJsonReturn(
$sql,
[$dateFormatted,$thanatoId,DevisMentionConstant::FACTURED,DevisMentionConstant::FACTURED_FORMATTED]);
return $devisList;
}
private function getThanatoLeaveByCalendarAndDate($calendarId,$date){
$isLeaveConditionAsString = "ABSENCETYPE:";
$datetimeFormatted = $date->format('Ymd');
$dateCondition = "%DTSTART%".$datetimeFormatted."%";
$conditions = [];
$params = [ $calendarId, $dateCondition ]; // First parameters for placeholders
$absenceTypes = VCalendarPropertyConstant::ABSENCE_TYPES;
foreach ($absenceTypes as $type) {
$conditions[] = "calendarobject.calendardata LIKE ?";
$params[] = "%$isLeaveConditionAsString$type%"; // Add corresponding values
}
$sql = "SELECT * FROM ".self::DEFAULT_TABLE_PREFIX."calendarobjects as calendarobject WHERE
calendarobject.calendarid = ? AND
calendarobject.calendardata LIKE ? AND
calendarobject.deleted_at IS NULL AND
(" . implode(" OR ", $conditions) . ");";
$leaves = $this->execSQLNoJsonReturn($sql,$params);
return $leaves;
}
private function setDevisIsPublicHolidayOrNotText($devis){
$isPublicHoliday = DateHelpers::isPublicHoliday($devis['date']);
$devis["dayType"] = DateHelpers::getPublicHolidayText($isPublicHoliday);
return $devis;
}
public function getThanatoDevisPerDateInAMonthYear($thanatoId,$month,$year){
$dateOfMonths = DateHelpers::getDatesOfMonth($year,$month);
$devisListPerThanatoPerDate = [];
$thanato = $this->getThanatoById($thanatoId);
$thanatoName = $thanato["nom"];
$thanatoCalendar = $this->getCalendarByThanatoIdNextcloud($thanato["fk_user_uuid"] ?? $thanato["nom"]);
if($thanatoCalendar == null){
return [];
}
$thanatoCalendarId = $thanatoCalendar["id"];
foreach($dateOfMonths as $currentDate){
$currentDateFormatted = $currentDate->format('Y-m-d');
$isPublicHoliday = DateHelpers::isPublicHoliday($currentDateFormatted);
$devisList = $this->getThanatoDevisListByDate($thanatoId,$currentDate);
$thereIsNoDevisForCurrentDate = empty($devisList);
if($thereIsNoDevisForCurrentDate){
$devisListPerThanatoPerDate[$currentDateFormatted]["hasDevis"] = false;
$thanatoLeavesThisDay = $this->getThanatoLeaveByCalendarAndDate($thanatoCalendarId,$currentDate);
if(empty($thanatoLeavesThisDay)){
$devisListPerThanatoPerDate[$currentDateFormatted]["leaves"][] = [
"onLeave" => false,
"startTime" => null,
"endTime" => null,
"thanatoName"=>$thanatoName,
"date" => $currentDateFormatted,
"totalHours" => 0,
"totalWorkedHours" => 8,
"isPublicHoliday" => $isPublicHoliday
];
}
else{
foreach($thanatoLeavesThisDay as $currentLeave){
$leaveTime = VCalendarHelpers::GetStartAndEndTimeFromVCalendarString($currentLeave['calendardata']);
$absenceType = VCalendarHelpers::GetValueFromKeyInVCalendarString(VCalendarPropertyConstant::ABSENCE_TYPE,$currentLeave['calendardata']);
$absenceTypeKey = null;
$absenceTypeLabel = null;
if($absenceType){
$absenceTypeKey = $absenceType;
$absenceTypeLabel = FileExportHelpers::GetAbsenceTypeLabelFromKey($absenceType);
}
$devisListPerThanatoPerDate[$currentDateFormatted]["leaves"][] = [
"onLeave" => true,
"startTime" => $leaveTime["startTime"],
"endTime" => $leaveTime["endTime"],
"thanatoName"=>$thanatoName,
"date" => $currentDateFormatted,
"totalHours" => $leaveTime["totalHours"],
"totalWorkedHours" => $leaveTime["totalWorkedHours"],
"isPublicHoliday" => $isPublicHoliday,
"absenceTypeKey" => $absenceTypeKey,
"absenceTypeLabel" => $absenceTypeLabel
];
}
}
}
else{
foreach($devisList as $devis){
$devis = $this->setDevisStartAndEndTime($devis);
$devis = $this->setDevisIsPublicHolidayOrNotText($devis);
$devis = $this->setDevisProduitsList($devis);
if (!isset($devisListPerThanatoPerDate[$currentDateFormatted])) {
$devisListPerThanatoPerDate[$currentDateFormatted] = [
'total_distance' => 0,
"devis" => [],
"devisId" => [],
"hasDevis" => true,
"leaves" => []
];
}
$devisListPerThanatoPerDate[$currentDateFormatted]["devis"][] = $devis;
$devisListPerThanatoPerDate[$currentDateFormatted]["devisId"][] = $devis['id'];
}
$devisListPerThanatoPerDate[$currentDateFormatted]["leaves"] = [];
$thanatoLeavesThisDay = $this->getThanatoLeaveByCalendarAndDate($thanatoCalendarId,$currentDate);
foreach($thanatoLeavesThisDay as $currentLeave){
$leaveTime = VCalendarHelpers::GetStartAndEndTimeFromVCalendarString($currentLeave['calendardata']);
$absenceType = VCalendarHelpers::GetValueFromKeyInVCalendarString(VCalendarPropertyConstant::ABSENCE_TYPE,$currentLeave['calendardata']);
$absenceTypeKey = null;
$absenceTypeLabel = null;
if($absenceType){
$absenceTypeKey = $absenceType;
$absenceTypeLabel = FileExportHelpers::GetAbsenceTypeLabelFromKey($absenceType);
}
$devisListPerThanatoPerDate[$currentDateFormatted]["leaves"][] = [
"onLeave" => true,
"startTime" => $leaveTime["startTime"],
"endTime" => $leaveTime["endTime"],
"thanatoName"=>$thanatoName,
"date" => $currentDateFormatted,
"totalHours" => $leaveTime["totalHours"],
"totalWorkedHours" => $leaveTime["totalWorkedHours"],
"isPublicHoliday" => $isPublicHoliday,
"absenceTypeKey" => $absenceTypeKey,
"absenceTypeLabel" => $absenceTypeLabel
];
}
}
}
return $devisListPerThanatoPerDate;
}
public function getRouteLinesByDevisIdList(array $devisIdList){
if(empty($devisIdList)){
return [];
}
$sqlConditionsPlaceholder = implode(',', array_fill(0, count($devisIdList), '?'));
$sql = "SELECT ligne_trajet.id, ligne_trajet.rang, ligne_trajet.id_nextcloud, ligne_trajet.date,
ligne_trajet.user_id, ligne_trajet.commentaire, ligne_trajet.source,
lieu.id as lieu_id, lieu.nom as lieu, lieu.latitude as latitude, lieu.longitude as longitude
FROM (".$this->tableprefix."ligne_trajet as ligne_trajet
LEFT JOIN ".$this->tableprefix."lieu as lieu on ligne_trajet.id_lieu = lieu.id)
WHERE ligne_trajet.id_devis IN ($sqlConditionsPlaceholder)
ORDER BY ligne_trajet.date ASC, ligne_trajet.rang ASC;";
return $this->execSQLNoJsonReturn($sql, $devisIdList);
}
}

View File

@ -64,4 +64,71 @@ class DateHelpers
return $lastDay;
}
public static function getDaysCountInAMonthAndYear($month,$year){
return $month == 2 ? ($year % 4 ? 28 : ($year % 100 ? 29 : ($year % 400 ? 28 : 29))) : (($month - 1) % 7 % 2 ? 30 : 31);
}
public static function getDatesOfMonth($year, $month) {
$dates = [];
$daysInMonth = self::getDaysCountInAMonthAndYear($month, $year);
for ($day = 1; $day <= $daysInMonth; $day++) {
$dateString = sprintf("%04d-%02d-%02d", $year, $month, $day);
$dates[] = new DateTime($dateString);
}
return $dates;
}
public static function isPublicHoliday(string $dateString): bool
{
try {
$date = new DateTime($dateString);
$dayOfWeek = $date->format('N');
return $dayOfWeek == 7;
} catch (Exception $e) {
return false;
}
}
public static function getPublicHolidayText($isPublicHoliday){
return $isPublicHoliday ? "Ferie" : "J";
}
public static function getHoursBetweenTwoDatetime($datetimeEnd,$datetimeStart){
if($datetimeEnd == null || $datetimeStart == null){
return 0;
}
$interval = $datetimeStart->diff($datetimeEnd);
$hours = $interval->h + ($interval->days * 24) + ($interval->i / 60);
return $hours;
}
public static function GetWorkingHoursBetweenDatetimeEndAndDatetimeStart(Datetime|null $datetimeEnd,Datetime|null $datetimeStart){
if($datetimeEnd == null || $datetimeStart == null){
return 0;
}
$workingStartAM = new DateTime($datetimeStart->format('Y-m-d') . ' 08:00',$datetimeStart->getTimezone());
$workingEndAM = new DateTime($datetimeStart->format('Y-m-d') . ' 12:00',$datetimeStart->getTimezone());
$workingStartPM = new DateTime($datetimeStart->format('Y-m-d') . ' 13:00',$datetimeStart->getTimezone());
$workingEndPM = new DateTime($datetimeStart->format('Y-m-d') . ' 17:00',$datetimeStart->getTimezone());
$totalHours = 0;
if ($datetimeStart->format('N') < 7) {
$dayStartAM = max($datetimeStart, $workingStartAM);
$dayEndAM = min($datetimeEnd, $workingEndAM);
if ($dayStartAM < $dayEndAM) {
$totalHours += ($dayEndAM->getTimestamp() - $dayStartAM->getTimestamp()) / 3600;
}
$dayStartPM = max($datetimeStart, $workingStartPM);
$dayEndPM = min($datetimeEnd, $workingEndPM);
if ($dayStartPM < $dayEndPM) {
$totalHours += ($dayEndPM->getTimestamp() - $dayStartPM->getTimestamp()) / 3600;
}
}
else{
$totalHours = ($datetimeEnd->getTimestamp() - $datetimeStart->getTimestamp()) / 3600;
}
return $totalHours;
}
}

View File

@ -2,6 +2,8 @@
namespace OCA\Gestion\Helpers;
use OCA\Gestion\Constants\VCalendarPropertyConstant;
class FileExportHelpers
{
@ -37,4 +39,16 @@ class FileExportHelpers
return $stringWithoutSpace;
}
public static function GetAbsenceTypeLabelFromKey(string $key){
$label = null;
$absenceTypes = VCalendarPropertyConstant::ABSENCE_TYPES_KEYS_VALUES;
foreach($absenceTypes as $absenceTypeKey => $absenceTypeLabel){
if($absenceTypeKey == $key){
$label = $absenceTypeLabel;
break;
}
}
return $label;
}
}

View File

@ -0,0 +1,17 @@
<?php
namespace OCA\Gestion\Helpers;
use DateTime;
use DateTimeZone;
use Exception;
use IntlDateFormatter;
class GeoHelpers
{
public static function getPointsTextFromLatitudeAndLongitude($latitude,$longitude): string
{
return (string)$latitude.','.(string)$longitude;
}
}

View File

@ -9,7 +9,7 @@ use Exception;
class VCalendarHelpers
{
public static function GetValueFromKeyInVCalendarString(string $key, string $vCalendarString): string
public static function GetValueFromKeyInVCalendarString(string $key, string $vCalendarString , ): string
{
$value = "";
preg_match("/$key:(.*)\r\n/", $vCalendarString, $matches);
@ -35,23 +35,28 @@ class VCalendarHelpers
}
}
public static function GetStartAndEndTimeFromVCalendarString(string $vCalendarString)
{
public static function GetStartAndEndTimeFromVCalendarString(string $vCalendarString){
$startTimeValue = "";
$endTimeValue = "";
if ($vCalendarString != "") {
$totalHours = 0;
$totalWorkedHours = 0;
if($vCalendarString != ""){
$dateStart = self::GetDateStartOrDateEndFromVCalendarString("DTSTART", $vCalendarString);
if ($dateStart != null) {
if($dateStart != null){
$startTimeValue = $dateStart->format("H") . "h";
}
$dateEnd = self::GetDateStartOrDateEndFromVCalendarString("DTEND", $vCalendarString);
if ($dateEnd != null) {
if($dateEnd != null){
$endTimeValue = $dateEnd->format("H") . "h";
}
$totalHours = DateHelpers::getHoursBetweenTwoDatetime($dateEnd,$dateStart);
$totalWorkedHours = DateHelpers::GetWorkingHoursBetweenDatetimeEndAndDatetimeStart($dateEnd,$dateStart);
}
return [
"startTime" => $startTimeValue,
"endTime" => $endTimeValue
"endTime" => $endTimeValue,
"totalHours" => $totalHours,
"totalWorkedHours" => $totalWorkedHours
];
}

View File

@ -26,11 +26,13 @@ declare(strict_types=1);
namespace OCA\Gestion\Service;
use OCA\Gestion\Constants\OrderTypeConstant;
use OCA\Gestion\Constants\ThanatoTypeConstant;
use OCA\Gestion\Constants\AbsenceTypeConstant;
use OCA\Gestion\Constants\BddConstant;
use OCA\Gestion\Db\Bdd;
use OCA\Gestion\Helpers\DateHelpers;
use OCA\Gestion\Helpers\FileExportHelpers;
use Psr\Log\LoggerInterface;
use OCP\Files\IRootFolder;
class ExportThanatoStatisticService {
/** @var Bdd */
@ -39,35 +41,70 @@ class ExportThanatoStatisticService {
/** @var LoggerInterface */
private $logger;
/** @var IRootFolder */
private $rootFolder;
private $geoService;
public function __construct(
Bdd $gestionBdd,
LoggerInterface $logger) {
LoggerInterface $logger,
IRootFolder $rootFolder,
GeoService $geoService) {
$this->geoService = $geoService;
$this->rootFolder = $rootFolder;
$this->logger = $logger;
$this->gestionBdd = $gestionBdd;
}
public function getThanatoStatisticFolders($thanatoList,$year){
$thanatoStatFolders = ['STATISTIQUES/THANATOS/'];
foreach($thanatoList as $thanato){
if($thanato['fk_thanato_type_key'] == ThanatoTypeConstant::THANATO_TYPE_SUBCONTRACTOR){
$thanatoStatFolders[] = 'STATISTIQUES/FOURNISSEURS/'.$year.'/';
break;
}
}
return $thanatoStatFolders;
}
public function getFilename(array $thanatoList,$month,$year){
private function getFilename($thanatoName,$thanatoLastName,$month,$year){
$filename = "$year-$month-";
foreach($thanatoList as $thanato){
$filename .= $thanato['thanato_nom'] . '-' . $thanato['thanato_prenom'] . '--';
}
$filename = rtrim($filename, '-');
$filename .= $thanatoName . '-' . $thanatoLastName;
$filename = str_replace(' ','-', $filename);
$filename = str_replace('&nbsp;','-', $filename);
return $filename;
}
private function exportThanatoStatistic($thanatoId,$month,$year,$idNextcloud){
$thanato = $this->gestionBdd->getThanatoById($thanatoId);
if($thanato == null){
return null;
}
$exportData = $this->gestionBdd->getExportThanatoStatisticData($thanatoId,$month,$year);
if(empty($exportData)){
return null;
}
$defaultConfig = json_decode($this->gestionBdd->getConfiguration(BddConstant::DEFAULT_ADMIN_APP_ID_NEXTCLOUD));
$racineFolder = html_entity_decode($defaultConfig[0]->path).'/';
$thanatoFolder = $racineFolder.'STATISTIQUES/THANATOS/';
$fileHeader = $this->getExportThanatoFileHeader();
$fileContent = $this->populateExportDataIntoFileContent($exportData,$fileHeader);
$storage = $this->rootFolder->getUserFolder($idNextcloud);
try{
$storage->newFolder($thanatoFolder);
}
catch(\OCP\Files\NotPermittedException $e) {
}
$filename = $this->getFilename($thanato["nom"],$thanato["prenom"],$month,$year);
$fileNamePath = $thanatoFolder."STAT-THANATO-" . $filename . '.csv';
$storage->newFile($fileNamePath);
$file = $storage->get($fileNamePath);
$file->putContent($fileContent);
return $fileNamePath;
}
public function exportThanatosListStatistic(array $thanatoIds,$month,$year,$idNextcloud){
$filenames = [];
foreach($thanatoIds as $thanatoId){
$filename = $this->exportThanatoStatistic($thanatoId,$month,$year,$idNextcloud);
if($filename != null){
$filenames[] = $filename;
}
}
return $filenames;
}
public function getExportThanatoFileHeader(): string{
$fileHeader =
'FACTURE'.';'.
@ -77,34 +114,142 @@ class ExportThanatoStatisticService {
'HEURE DE FIN'.';'.
'SOINS'.';'.
'JOUR/FERIE'.';'.
'CONGE'.';'.
'REPOS'.';'.
'MALADIE'.';'.
'NOM ET PRENOM'.';'.
'LIEU'.';'.
'POMPES FUNEBRES'.';'.
'ADRESSE'.';'.
'BON DE COMMANDE'.';'.
'TOTAL ACHAT'.';'.
'DISTANCE TOTALE KM'.';'.
'HEURES TOTAL DE SOIN'.';'.
'HEURES TOTAL DE CONGE'.';'.
'HEURES TOTAL DE REPOS'.';'.
'HEURES TOTAL DE MALADIE'.';'.
'HEURES TOTAL DE TRAVAIL'.';'.
'HEURES TOTAL DE PARCOURS ENTRE DEVIS'.';'.
"\n";
return $fileHeader;
}
private function populateNoDevisDataInADay(string $fileContent,$leave){
$startTimeValue = "";
$endTimeValue = "";
$leaveValue = "Non";
$diseaseValue = "Non";
$restValue = "Non";
if($leave["onLeave"]){
$startTimeValue = $leave["startTime"];
$endTimeValue = $leave["endTime"];
if($leave["absenceTypeKey"] == AbsenceTypeConstant::LEAVE){
$leaveValue = "Oui";
}
if($leave["absenceTypeKey"] == AbsenceTypeConstant::DISEASE){
$diseaseValue = "Oui";
}
if($leave["absenceTypeKey"] == AbsenceTypeConstant::REST){
$restValue = "Oui";
}
}
$fileContent = $fileContent.
''.';'.
FileExportHelpers::FormatTextForExport($leave['thanatoName']).';'.
$leave['date'].';'.
$startTimeValue.';'.
$endTimeValue.';'.
''.';'.
DateHelpers::getPublicHolidayText($leave['isPublicHoliday']).';'.
$leaveValue.';'.
$diseaseValue.';'.
$restValue.';'.
''.';'.
''.';'.
''.';'.
''.';'.
''.';'.
''.';'.
''.';'.
''.';'.
''.';'.
''.';'.
''.';'."\n";
return $fileContent;
}
public function populateExportDataIntoFileContent(array $exportData,string $fileContent): string{
foreach($exportData as $thanatoId => $devisPerThanato){
foreach($devisPerThanato as $devisDate => $devisData){
$distanceTotal = $this->gestionBdd->getDistanceTotalByDevisIdList($devisData["devisId"]);
foreach($exportData as $devisDate => $devisData){
$totalDevisHours = 0;
$totalWorkedHours = 8;
$totalLeaveHours = 0;
$totalDiseaseHours = 0;
$totalRestHours = 0;
$totalDistance = 0;
$totalTravelingHoursBetweenDevisLocation = 0;
$hasDevisInTheCurrentDate = $devisData['hasDevis'];
if($hasDevisInTheCurrentDate === false){
$leaves = $devisData["leaves"];
foreach($leaves as $leave){
$fileContent = $this->populateNoDevisDataInADay($fileContent,$leave);
if($leave["onLeave"]){
$totalLeaveHoursInsideWorkingHours = $leave["totalWorkedHours"];
if($leave["absenceTypeKey"] == AbsenceTypeConstant::LEAVE){
$totalLeaveHours += $totalLeaveHoursInsideWorkingHours;
}
if($leave["absenceTypeKey"] == AbsenceTypeConstant::REST){
$totalRestHours += $totalLeaveHoursInsideWorkingHours;
}
if($leave["absenceTypeKey"] == AbsenceTypeConstant::DISEASE){
$totalDiseaseHours += $totalLeaveHoursInsideWorkingHours;
}
}
}
$totalWorkedHours -= $totalLeaveHours - $totalRestHours - $totalDiseaseHours;
}
else{
$routeLines = $this->gestionBdd->getRouteLinesByDevisIdList($devisData["devisId"]);
$totalDistanceAndTotalTravelingHoursBetweenDevis = $this->geoService->getTotalDistanceAndTotalTravelingHoursBetweenDevisLocationByRouteLines($routeLines);
$totalDistance = $totalDistanceAndTotalTravelingHoursBetweenDevis["totalDistance"];
$totalTravelingHoursBetweenDevisLocation = $totalDistanceAndTotalTravelingHoursBetweenDevis["totalTravelingHours"];
$devisList = $devisData["devis"];
$leaves = $devisData["leaves"];
if(!empty($devisList)){
foreach($devisList as $devis){
$fileContent = $this->populateDevisDataIntoThanatoExportFileContent($fileContent,$devis);
$totalDevisHours += $devis["totalHours"];
}
$fileContent = $this->populateDistanceTotalIntoThanatoExportFileContent($fileContent,$distanceTotal);
}
foreach($leaves as $leave){
$fileContent = $this->populateNoDevisDataInADay($fileContent,$leave);
if($leave["onLeave"]){
$totalLeaveHoursInsideWorkingHours = $leave["totalWorkedHours"];
if($leave["absenceTypeKey"] == AbsenceTypeConstant::LEAVE){
$totalLeaveHours += $totalLeaveHoursInsideWorkingHours;
}
if($leave["absenceTypeKey"] == AbsenceTypeConstant::REST){
$totalRestHours += $totalLeaveHoursInsideWorkingHours;
}
if($leave["absenceTypeKey"] == AbsenceTypeConstant::DISEASE){
$totalDiseaseHours += $totalLeaveHoursInsideWorkingHours;
}
}
}
$totalWorkedHours -= $totalLeaveHours - $totalRestHours - $totalDiseaseHours;
}
$fileContent = $this->populateLastRecapForTheLine(
$fileContent,
$totalDistance,
$totalDevisHours,
$totalWorkedHours,
$totalLeaveHours,
$totalTravelingHoursBetweenDevisLocation,
$totalDiseaseHours,
$totalRestHours
);
}
return $fileContent;
}
private function populateDistanceTotalIntoThanatoExportFileContent(string $fileContent,$distance){
private function populateLastRecapForTheLine(string $fileContent,$distance,$totalDevisHours,$totalWorkedHours,$totalLeaveHours,$totalTravelingHours,$totalDiseaseHours = 0,$totalRestHours = 0){
$fileContent = $fileContent.
''.';'.
''.';'.
@ -119,7 +264,14 @@ class ExportThanatoStatisticService {
''.';'.
''.';'.
''.';'.
utf8_decode(html_entity_decode("$distance"))."\n";
''.';'.
"$distance"."KM".';'.
"$totalDevisHours"."H".';'.
"$totalLeaveHours"."H".';'.
"$totalRestHours"."H".';'.
"$totalDiseaseHours"."H".';'.
"$totalWorkedHours"."H".';'.
"$totalTravelingHours"."H"."\n";
return $fileContent;
}
@ -135,15 +287,6 @@ class ExportThanatoStatisticService {
private function populateDevisDataIntoThanatoExportFileContent(string $fileContent,array $devis){
$produitAsString = $this->getFormatDevisProduitsAsString($devis["produits"]);
$orderFullNumber = "";
$totalOrderPrice = "";
$isDevisDoneBySubContractor = $devis['fk_order_type_key'] == OrderTypeConstant::ORDER_TYPE_DEVIS &&
$devis['order_id'] != null && $devis["fk_thanato_type_key"] == ThanatoTypeConstant::THANATO_TYPE_SUBCONTRACTOR;
if($isDevisDoneBySubContractor){
$orderFullNumber = $devis["order_full_number"];
$totalOrderPrice = $devis["total_price"];
}
$fileContent = $fileContent.
FileExportHelpers::FormatTextForExport($devis["facture_num"]).';'.
FileExportHelpers::FormatTextForExport($devis['nom_thanato'] . ' ' . $devis['prenom_thanatho']).';'.
@ -152,12 +295,19 @@ class ExportThanatoStatisticService {
FileExportHelpers::FormatTextForExport($devis["endTime"]).';'.
FileExportHelpers::FormatTextForExport($produitAsString).';'.
FileExportHelpers::FormatTextForExport($devis["dayType"]).';'.
FileExportHelpers::FormatTextForExport('Non').';'.
''.';'.
''.';'.
FileExportHelpers::FormatTextForExport($devis["nom_defunt"]).';'.
FileExportHelpers::FormatTextForExport($devis["nom_lieu"] ?? "").';'.
FileExportHelpers::FormatTextForExport($devis["nom_client"] ?? "").';'.
FileExportHelpers::FormatTextForExport($devis["client_adresse"] ?? "").';'.
FileExportHelpers::FormatTextForExport($orderFullNumber).';'.
"$totalOrderPrice".';'.
FileExportHelpers::FormatTextForExport($devis["client_adresse"] ?? "").
''.';'.
''.';'.
''.';'.
''.';'.
''.';'.
''.';'.
''.';'."\n";
return $fileContent;

View File

@ -0,0 +1,128 @@
<?php
declare(strict_types=1);
/**
* Calendar App
*
* @copyright 2021 Anna Larch <anna.larch@gmx.net>
*
* @author Anna Larch <anna.larch@gmx.net>
* @author Richard Steinmetz <richard@steinmetz.cloud>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Gestion\Service;
use Exception;
use OCA\Gestion\Constants\GeoConstant;
use OCA\Gestion\Helpers\GeoHelpers;
class GeoService {
public function __construct() {
}
/**
* Calcul la distance entre les deux points à vol d'oiseau
*/
private function getDistanceInKmBetweenTwoPoints($lat1, $lon1, $lat2, $lon2) {
$R = 6371; // Rayon moyen de la Terre en kilomètres
$dLat = deg2rad($lat2 - $lat1);
$dLon = deg2rad($lon2 - $lon1);
$a = sin($dLat/2) * sin($dLat/2) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * sin($dLon/2) * sin($dLon/2);
$c = 2 * atan2(sqrt($a), sqrt(1-$a));
$d = $R * $c;
return round($d, 2);
}
private function getTravelingHourBetweenTwoPoints(array $origin,array $destination,$mode = "driving"){
$baseUrl = "https://api.geoapify.com/v1/routing";
$originPoints = GeoHelpers::getPointsTextFromLatitudeAndLongitude($origin["latitude"],$origin["longitude"]);
$destinationPoints = GeoHelpers::getPointsTextFromLatitudeAndLongitude($destination["latitude"],$destination["longitude"]);
$fullUrl = $baseUrl."?waypoints=$originPoints|$destinationPoints&mode=$mode&apiKey=9e23d93e7f454c988344f9171bf867aa";
$curl = curl_init();
try {
curl_setopt_array($curl, array(
CURLOPT_URL => $fullUrl,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
));
$response = curl_exec($curl);
curl_close($curl);
if ($response === false) {
return 0;
} else {
$timeInSecondes = json_decode($response)->features[0]->properties->time;
$travelTimeHours = $timeInSecondes / 3600;
$travelTimeHours = round($travelTimeHours, 2);
return $travelTimeHours;
}
}
catch(Exception $e){
return 0;
}
}
public function getTotalDistanceAndTotalTravelingHoursBetweenDevisLocationByRouteLines(array $routeLines){
$distanceCumul = 0;
$totalTravelingHoursBetweenTwoDevisLocation = 0;
$lastPoint = NULL;
for ($i=0; $i < sizeof($routeLines); $i++) {
$currentDistance = 0;
if($routeLines[$i]['lieu_id'] != NULL){
$lastPoint = $routeLines[$i];
}
if($lastPoint['lieu_id'] != NULL && $routeLines[$i+1]['lieu_id'] != NULL){
$currentDistance = $this->getDistanceInKmBetweenTwoPoints(
floatval(value: $lastPoint['latitude']),
floatval($lastPoint['longitude']),
floatval($routeLines[$i+1]['latitude']),
floatval($routeLines[$i+1]['longitude'])
);
$targetIsBetweenTwoDevisLocation = $lastPoint['source'] != "siege" && $routeLines[$i+1]["source"] != "siege";
if($targetIsBetweenTwoDevisLocation){
$originPoints = [
"latitude" => $lastPoint["latitude"],
"longitude" => $lastPoint["longitude"]
];
$destinationPoints = [
"latitude" => $routeLines[$i+1]["latitude"],
"longitude" => $routeLines[$i+1]["longitude"]
];
$totalTravelingHoursBetweenTwoDevisLocation+= $this->getTravelingHourBetweenTwoPoints(
$originPoints,
$destinationPoints,
GeoConstant::DRIVING_MODE
);
}
}
$distanceCumul += $currentDistance;
}
return [
"totalDistance" => $distanceCumul,
"totalTravelingHours" => $totalTravelingHoursBetweenTwoDevisLocation
];
}
}

View File

@ -209,7 +209,8 @@ class GestionService {
try{
$isPrivate = $this->GetIsPivateFromVCalendarString($vCalendarString);
if($isPrivate){
$absenceType = VCalendarHelpers::GetValueFromKeyInVCalendarString('ABSENCETYPE',$vCalendarString);
if($isPrivate || $absenceType){
//Nothing to do manage fo a private calendar
return;
}
@ -412,10 +413,12 @@ class GestionService {
public function HandleUpdatedCalendarObject(string $vCalendarString , $cookie){
try{
$isPrivate = $this->GetIsPivateFromVCalendarString($vCalendarString);
if($isPrivate){
$absenceType = VCalendarHelpers::GetValueFromKeyInVCalendarString('ABSENCETYPE',$vCalendarString);
if($isPrivate || $absenceType){
//Nothing to do manage fo a private calendar
return;
}
$calendarUuid = $this->GetCalendarUuidFromVCalendarString($vCalendarString);
$devis = $this->gestionBdd->getDevisByCalendarUuid($calendarUuid);
if($devis != null){