Compare commits

...

17 Commits

Author SHA1 Message Date
Tiavina
b935617c29 Merge branch 'releases/release-h2f' into releases/release-h2f-prod 2025-04-01 10:13:13 +03:00
Narindra ezway
452e363877 Merge branch 'releases/release-h2f' of https://gitlab.com/ezwaytechnology/nextcloud_custom_apps into releases/release-h2f 2025-03-28 18:00:43 +03:00
Narindra ezway
eafe063f54 Merge branch 'h2f/features/add-the-email-in-pj' into releases/release-h2f 2025-03-28 18:00:36 +03:00
Narindra ezway
7c1ec3c829 add email contenu with pj attachment 2025-03-28 17:59:51 +03:00
Tiavina
97274d9d49 Merge branch 'fixes/fix-talk-minutes' into releases/release-h2f 2025-03-28 17:04:01 +03:00
Tiavina
102655c21e Add dateStart and dateEnd variables to VCalendarHelpers for improved date handling 2025-03-28 17:03:42 +03:00
Tiavina
8a368c838a Refactor message formatting in getDevisTalkRoomClientContent and update VCalendarHelpers to return datetime objects 2025-03-28 17:02:04 +03:00
Tiavina
f252f931d7 Merge branch 'fixes/fix-stat-features' into releases/release-h2f 2025-03-28 16:48:21 +03:00
Tiavina
5cf18b50dc Enhance exportThanatoStatistic method to include month and year parameters; refactor absence hour calculations for clarity 2025-03-28 16:47:58 +03:00
Narindra ezway
de431c0f95 Merge branch 'feature/conge-auto-full-day' into releases/release-h2f 2025-03-27 18:05:13 +03:00
Narindra ezway
9409cd3d6a send build 2025-03-27 18:04:21 +03:00
Narindra ezway
7b24555be4 Add absence type constants and helper methods for absence type labels 2025-03-27 18:02:06 +03:00
Narindra ezway
b6a3a3a55b congé+repos+arrat-maladie : OK 2025-03-27 14:47:29 +03:00
Narindra ezway
b6f363829e Merge remote-tracking branch 'origin/releases/release-h2f' into feature/conge-auto-full-day 2025-03-27 10:10:23 +03:00
ismaelraj-ezway
99926b408e Champ select 'congé, repos, arrêt maladie' dans la création événement 2025-03-27 09:39:57 +03:00
Tiavina
f30b73d850 Merge branch 'hotfixes/hotfix-facture-devis' into releases/release-h2f-prod 2025-03-26 17:56:43 +03:00
Tiavina
c5105136d8 HOTFIXES : hotfix facture devis 2025-03-26 17:54:47 +03:00
64 changed files with 14068 additions and 6683 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":"748ab31152e1226f9b22","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=fd08a5d56f376e2cd30d

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":"297f1f42ac74bad32e69","vendors-node_modules_webdav_dist_web_index_js":"454da8f908d41b47c607","src_store_index_js":"748ab31152e1226f9b22","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=c50a6845f9eb0b6964ef

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: 'Arrêt 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",
@ -17007,14 +17139,23 @@ __webpack_require__.r(__webpack_exports__);
var _this$calendarObjectI12, _this$calendarObjectI13;
return (_this$calendarObjectI12 = (_this$calendarObjectI13 = this.calendarObjectInstance) === null || _this$calendarObjectI13 === void 0 ? void 0 : _this$calendarObjectI13.isPrivate) !== null && _this$calendarObjectI12 !== void 0 ? _this$calendarObjectI12 : false;
},
/**
* Returns the emailId property
*
* @return {string|null}
*/
emailId() {
var _this$calendarObjectI14, _this$calendarObjectI15;
return (_this$calendarObjectI14 = (_this$calendarObjectI15 = this.calendarObjectInstance) === null || _this$calendarObjectI15 === void 0 ? void 0 : _this$calendarObjectI15.emailId) !== null && _this$calendarObjectI14 !== void 0 ? _this$calendarObjectI14 : null;
},
/**
* Returns the description or null if the event is still loading
*
* @return {string|null}
*/
description() {
var _this$calendarObjectI14, _this$calendarObjectI15;
return (_this$calendarObjectI14 = (_this$calendarObjectI15 = this.calendarObjectInstance) === null || _this$calendarObjectI15 === void 0 ? void 0 : _this$calendarObjectI15.description) !== null && _this$calendarObjectI14 !== void 0 ? _this$calendarObjectI14 : null;
var _this$calendarObjectI16, _this$calendarObjectI17;
return (_this$calendarObjectI16 = (_this$calendarObjectI17 = this.calendarObjectInstance) === null || _this$calendarObjectI17 === void 0 ? void 0 : _this$calendarObjectI17.description) !== null && _this$calendarObjectI16 !== void 0 ? _this$calendarObjectI16 : null;
},
/**
* Returns the start-date (without timezone) or null if the event is still loading
@ -17022,8 +17163,8 @@ __webpack_require__.r(__webpack_exports__);
* @return {Date|null}
*/
startDate() {
var _this$calendarObjectI16, _this$calendarObjectI17;
return (_this$calendarObjectI16 = (_this$calendarObjectI17 = this.calendarObjectInstance) === null || _this$calendarObjectI17 === void 0 ? void 0 : _this$calendarObjectI17.startDate) !== null && _this$calendarObjectI16 !== void 0 ? _this$calendarObjectI16 : null;
var _this$calendarObjectI18, _this$calendarObjectI19;
return (_this$calendarObjectI18 = (_this$calendarObjectI19 = this.calendarObjectInstance) === null || _this$calendarObjectI19 === void 0 ? void 0 : _this$calendarObjectI19.startDate) !== null && _this$calendarObjectI18 !== void 0 ? _this$calendarObjectI18 : null;
},
/**
* Returns the timezone of the event's start-date or null if the event is still loading
@ -17031,8 +17172,8 @@ __webpack_require__.r(__webpack_exports__);
* @return {string|null}
*/
startTimezone() {
var _this$calendarObjectI18, _this$calendarObjectI19;
return (_this$calendarObjectI18 = (_this$calendarObjectI19 = this.calendarObjectInstance) === null || _this$calendarObjectI19 === void 0 ? void 0 : _this$calendarObjectI19.startTimezoneId) !== null && _this$calendarObjectI18 !== void 0 ? _this$calendarObjectI18 : null;
var _this$calendarObjectI20, _this$calendarObjectI21;
return (_this$calendarObjectI20 = (_this$calendarObjectI21 = this.calendarObjectInstance) === null || _this$calendarObjectI21 === void 0 ? void 0 : _this$calendarObjectI21.startTimezoneId) !== null && _this$calendarObjectI20 !== void 0 ? _this$calendarObjectI20 : null;
},
/**
* Returns the end-date (without timezone) or null if the event is still loading
@ -17040,8 +17181,8 @@ __webpack_require__.r(__webpack_exports__);
* @return {Date|null}
*/
endDate() {
var _this$calendarObjectI20, _this$calendarObjectI21;
return (_this$calendarObjectI20 = (_this$calendarObjectI21 = this.calendarObjectInstance) === null || _this$calendarObjectI21 === void 0 ? void 0 : _this$calendarObjectI21.endDate) !== null && _this$calendarObjectI20 !== void 0 ? _this$calendarObjectI20 : null;
var _this$calendarObjectI22, _this$calendarObjectI23;
return (_this$calendarObjectI22 = (_this$calendarObjectI23 = this.calendarObjectInstance) === null || _this$calendarObjectI23 === void 0 ? void 0 : _this$calendarObjectI23.endDate) !== null && _this$calendarObjectI22 !== void 0 ? _this$calendarObjectI22 : null;
},
/**
* Returns the timezone of the event's end-date or null if the event is still loading
@ -17049,8 +17190,8 @@ __webpack_require__.r(__webpack_exports__);
* @return {string|null}
*/
endTimezone() {
var _this$calendarObjectI22, _this$calendarObjectI23;
return (_this$calendarObjectI22 = (_this$calendarObjectI23 = this.calendarObjectInstance) === null || _this$calendarObjectI23 === void 0 ? void 0 : _this$calendarObjectI23.endTimezoneId) !== null && _this$calendarObjectI22 !== void 0 ? _this$calendarObjectI22 : null;
var _this$calendarObjectI24, _this$calendarObjectI25;
return (_this$calendarObjectI24 = (_this$calendarObjectI25 = this.calendarObjectInstance) === null || _this$calendarObjectI25 === void 0 ? void 0 : _this$calendarObjectI25.endTimezoneId) !== null && _this$calendarObjectI24 !== void 0 ? _this$calendarObjectI24 : null;
},
/**
* Returns whether or not the event is all-day or null if the event is still loading
@ -17058,8 +17199,8 @@ __webpack_require__.r(__webpack_exports__);
* @return {boolean}
*/
isAllDay() {
var _this$calendarObjectI24, _this$calendarObjectI25;
return (_this$calendarObjectI24 = (_this$calendarObjectI25 = this.calendarObjectInstance) === null || _this$calendarObjectI25 === void 0 ? void 0 : _this$calendarObjectI25.isAllDay) !== null && _this$calendarObjectI24 !== void 0 ? _this$calendarObjectI24 : false;
var _this$calendarObjectI26, _this$calendarObjectI27;
return (_this$calendarObjectI26 = (_this$calendarObjectI27 = this.calendarObjectInstance) === null || _this$calendarObjectI27 === void 0 ? void 0 : _this$calendarObjectI27.isAllDay) !== null && _this$calendarObjectI26 !== void 0 ? _this$calendarObjectI26 : false;
},
/**
* Returns whether or not the user is allowed to modify the all-day setting
@ -17067,8 +17208,8 @@ __webpack_require__.r(__webpack_exports__);
* @return {boolean}
*/
canModifyAllDay() {
var _this$calendarObjectI26, _this$calendarObjectI27;
return (_this$calendarObjectI26 = (_this$calendarObjectI27 = this.calendarObjectInstance) === null || _this$calendarObjectI27 === void 0 ? void 0 : _this$calendarObjectI27.canModifyAllDay) !== null && _this$calendarObjectI26 !== void 0 ? _this$calendarObjectI26 : false;
var _this$calendarObjectI28, _this$calendarObjectI29;
return (_this$calendarObjectI28 = (_this$calendarObjectI29 = this.calendarObjectInstance) === null || _this$calendarObjectI29 === void 0 ? void 0 : _this$calendarObjectI29.canModifyAllDay) !== null && _this$calendarObjectI28 !== void 0 ? _this$calendarObjectI28 : false;
},
/**
* Returns the color the illustration should be colored in
@ -17100,8 +17241,8 @@ __webpack_require__.r(__webpack_exports__);
* @return {null | string}
*/
color() {
var _this$calendarObjectI28, _this$calendarObjectI29;
return (_this$calendarObjectI28 = (_this$calendarObjectI29 = this.calendarObjectInstance) === null || _this$calendarObjectI29 === void 0 ? void 0 : _this$calendarObjectI29.customColor) !== null && _this$calendarObjectI28 !== void 0 ? _this$calendarObjectI28 : null;
var _this$calendarObjectI30, _this$calendarObjectI31;
return (_this$calendarObjectI30 = (_this$calendarObjectI31 = this.calendarObjectInstance) === null || _this$calendarObjectI31 === void 0 ? void 0 : _this$calendarObjectI31.customColor) !== null && _this$calendarObjectI30 !== void 0 ? _this$calendarObjectI30 : null;
},
/**
* Returns whether or not to display save buttons
@ -17224,7 +17365,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 +17411,15 @@ __webpack_require__.r(__webpack_exports__);
return true;
}
return false;
},
/**
* Returns the absence type
*
* @return {string|null}
*/
absenceType() {
var _this$calendarObjectI32, _this$calendarObjectI33;
return (_this$calendarObjectI32 = (_this$calendarObjectI33 = this.calendarObjectInstance) === null || _this$calendarObjectI33 === void 0 ? void 0 : _this$calendarObjectI33.absenceType) !== null && _this$calendarObjectI32 !== void 0 ? _this$calendarObjectI32 : '';
}
},
methods: {
@ -17586,6 +17736,15 @@ __webpack_require__.r(__webpack_exports__);
isPrivate
});
},
/**
* Toggles the event to private
*/
addEmailId(emailId) {
this.$store.commit('addEmailId', {
calendarObjectInstance: this.calendarObjectInstance,
emailId
});
},
/**
* Resets the internal state after changing the viewed calendar-object
*/
@ -17616,6 +17775,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 +20764,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 +23356,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 +25002,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 +26221,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 +27063,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 +27806,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 +28018,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=297f1f42ac74bad32e69

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

View File

@ -153,12 +153,18 @@ class EmailBoxController extends Controller {
} finally {
$client->logout();
}
$data['fullMessage'] = $json;
$data['attachments'] = array_map(function ($a) use ($messageId) {
return $this->enrichDownloadUrl(
$messageId,
$a
);
}, $json['attachments']);
if(isset( $json['attachments'])) {
unset($json['attachments']);
}
return new JSONResponse(($data));
}
/**

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

@ -109,8 +109,11 @@
<div class="mailHeader">
{{ getLabelEmailBox(selectedMail.from) + ' : ' + selectedMail.subject }}
</div>
<div class="mailContent">
{{ selectedMail.previewText }}
<div class="mailContent" v-if="selectedMail.body">
<div v-html="selectedMail.body "></div>
</div>
<div class="mailContent" v-else>
<div v-html="selectedMail.previewText "></div>
</div>
</div>
@ -256,6 +259,13 @@ export default {
calendarObjectInstance: this.calendarObjectInstance,
attachment,
})
if (this.selectedAttachements.length = 0) {
const emailId = null;
this.$store.commit('addEmailId', {
calendarObjectInstance: this.calendarObjectInstance,
emailId,
})
}
},
async openFilesModal() {
const picker = getFilePickerBuilder(t('calendar', 'Choose a file to add as attachment'))
@ -385,13 +395,21 @@ export default {
},
async getAttachments(mail){
this.loadingText = 'Récupération des piecs jointes ...'
this.selectedMail = mail
this.loadingDataEmailBox = true
this.showAttachmentsSection = true
this.selectedMail = mail
this.mailAttachmentData = [] ;
await this.loadAttachments(mail)
this.loadingDataEmailBox = false
},
async addEmailToVcalendar(mail){
const emailId = mail.databaseId ?? null;
this.$store.commit('addEmailId', {
calendarObjectInstance: this.calendarObjectInstance,
emailId,
})
},
selectAttachement(attachementId){
if(this.isInSelectedAttachment(attachementId)){
console.log("remove")
@ -411,6 +429,7 @@ export default {
//upload only attachmen if id is in selectedAttachements
const selectedAttachements = this.selectedAttachements.map(id => this.mailAttachmentData.find(attachement => attachement.id === id))
await this.uploadAttachment(selectedAttachements)
this.addEmailToVcalendar(this.selectedMail);
this.closeMailBoxModal()
this.resetMailBoxModal()
@ -468,19 +487,8 @@ export default {
await axios.get(ajaxUrl)
.then(response => {
// response.data.attachments.forEach(attachement => {
// this.mailAttachmentData.push({
// id : attachement.id,
// fileName : attachement.fileName,
// downloadUrl : attachement.downloadUrl,
// id : attachement.id,
// isImage : attachement.isImage,
// isCalendarEvent : attachement.isCalendarEvent,
// size : attachement.size,
// })
// })
this.mailAttachmentData = response.data.attachments
this.selectedMail["body"] = response.data.fullMessage.body
})
.catch(error => {
console.log(error)
@ -639,6 +647,8 @@ label {
flex-direction: column;
align-items: flex-start;
padding: 10px;
max-height: 400px;
overflow: scroll;
}
</style>

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: 'Arrêt 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

@ -137,6 +137,15 @@ export default {
return this.calendarObjectInstance?.isPrivate ?? false
},
/**
* Returns the emailId property
*
* @return {string|null}
*/
emailId() {
return this.calendarObjectInstance?.emailId ?? null
},
/**
* Returns the description or null if the event is still loading
*
@ -360,7 +369,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 +421,15 @@ export default {
return false
},
/**
* Returns the absence type
*
* @return {string|null}
*/
absenceType() {
return this.calendarObjectInstance?.absenceType ?? ''
},
},
methods: {
/**
@ -738,6 +756,15 @@ export default {
isPrivate
})
},
/**
* Toggles the event to private
*/
addEmailId(emailId) {
this.$store.commit('addEmailId', {
calendarObjectInstance: this.calendarObjectInstance,
emailId
})
},
/**
* Resets the internal state after changing the viewed calendar-object
*/
@ -770,6 +797,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
@ -94,6 +96,8 @@ const getDefaultEventObject = (props = {}) => Object.assign({}, {
customColor: null,
// Categories
categories: [],
// The event's UID
emailId: null,
// Attachments of this event
attachments: [],
}, props)
@ -114,6 +118,8 @@ const mapEventComponentToEventObject = (eventComponent) => {
client : "CLIENT",
embalmer : "TEST",
comment : "",
absenceType : "",
emailId: null,
description: eventComponent.description,
accessClass: eventComponent.accessClass,
status: eventComponent.status,
@ -215,6 +221,14 @@ const mapEventComponentToEventObject = (eventComponent) => {
eventObject.comment = eventComponent.getFirstPropertyFirstValue('COMMENT');
}
if(eventComponent.hasProperty('ABSENCETYPE')){
eventObject.absenceType = eventComponent.getFirstPropertyFirstValue('ABSENCETYPE');
}
if(eventComponent.hasProperty('EMAILID')){
eventObject.emailId = eventComponent.getFirstPropertyFirstValue('EMAILID');
}
return eventObject;
}
@ -231,6 +245,7 @@ const copyCalendarObjectInstanceIntoEventComponent = (eventObject, eventComponen
eventComponent.embalmer = eventObject.embalmer
eventComponent.isPrivate = eventObject.isPrivate
eventComponent.comment = eventObject.comment
eventComponent.emailId = eventObject.emailId
eventComponent.description = eventObject.description
eventComponent.accessClass = eventObject.accessClass
eventComponent.status = eventObject.status

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

@ -297,8 +297,18 @@ const mutations = {
calendarObjectInstance.eventComponent.isPrivate = isPrivate
calendarObjectInstance.isPrivate = isPrivate
},
/**
*Email id
*
* @param {object} state The Vuex state
* @param {object} data The destructuring object
* @param {object} data.calendarObjectInstance The calendarObjectInstance object
*/
addEmailId(state, { calendarObjectInstance, emailId }) {
calendarObjectInstance.eventComponent.emailId = emailId
calendarObjectInstance.emailId = emailId
},
/**
@ -377,6 +387,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: 'Arrêt 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 +1574,11 @@ const mutations = {
}
},
setAbsenceType(state, { calendarObjectInstance, absenceType }) {
if (calendarObjectInstance) {
calendarObjectInstance.absenceType = absenceType;
}
},
}
const getters = {}
@ -1718,6 +1771,8 @@ const actions = {
let additionalFieldWasUpdated =
eventComponent.client != null ||
eventComponent.isPrivate != null ||
eventComponent.absenceType ||
eventComponent.emailId ||
eventComponent.comment != null ;
if (eventComponent.isDirty() || additionalFieldWasUpdated) {
const isForkedItem = eventComponent.primaryItem !== null
@ -2138,6 +2193,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,34 @@ const actions = {
icsValue = setCustomKeyValuesArrayToIcsAndReturnIcs(icsValue,customKeyValue);
}
}
if(eventComponent.emailId != null){
let emailIdValue = eventComponent.emailId ;
let emailIdValueValue = "EMAILID:"+emailIdValue;
let regex = /EMAILID:\d+/;
if(regex.test(icsValue)){
icsValue = icsValue.replace(regex, emailIdValueValue);
}
else{
const customKeyValue = {
"EMAILID": emailIdValue
};
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 +321,10 @@ const actions = {
"CLIENT": eventComponent.client,
"EMBALMER": eventComponent.embalmer ,
"ISPRIVATE": eventComponent.isPrivate ? "1" : "0",
"COMMENT": eventComponent.comment
"COMMENT": eventComponent.comment,
"EMAILID": eventComponent.emailId,
"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

@ -2599,36 +2599,14 @@ class PageController extends Controller {
*
*/
public function exportThanatoStatistic($thanatoIdsToExport){
public function exportThanatoStatistic($thanatoIdsToExport,$month,$year){
if(empty($thanatoIdsToExport)){
return "";
}
$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;
}
@ -2783,16 +2785,20 @@ class Bdd {
return null;
}
private function getDevisIdListFilteredByMentionAndDevisListId($mentionToNotInclude,$devisListId){
private function getDevisIdListFilteredByMentionAndDevisListId($mentionsFilter,$devisListId){
if (empty($devisListId)) {
return [];
}
$placeholders = implode(',', array_fill(0, count($devisListId), '?'));
$mentionsFilterPlaceholders = implode(',', array_fill(0, count($mentionsFilter), '?'));
$sql = "SELECT devis.id as id,devis.date as devis_date
FROM ".$this->tableprefix."devis as devis
WHERE devis.id IN ($placeholders) AND mentions != ?";
WHERE devis.id IN ($placeholders) AND
mentions IN ($mentionsFilterPlaceholders)";
$result = $this->execSQLNoJsonReturn($sql,array_merge($devisListId, [$mentionToNotInclude]));
$result = $this->execSQLNoJsonReturn($sql,array_merge(
$devisListId,
$mentionsFilter));
return $result;
}
@ -2855,12 +2861,21 @@ class Bdd {
}
public function insertFactureForeEachDevisId($idNextCloud,$devisIdArray,$paymentDate = null){
$mentionToNotInclude = 'factur&eacute;';
$mentionsFilter = [
DevisMentionConstant::NEW,
DevisMentionConstant::MENTION
];
$devisIdArray = array_unique($devisIdArray);
$devisIdListFiltered = $this->getDevisIdListFilteredByMentionAndDevisListId($mentionToNotInclude,$devisIdArray);
$devisIdListFiltered = $this->getDevisIdListFilteredByMentionAndDevisListId($mentionsFilter,$devisIdArray);
$factureIdsGenerated = [];
foreach($devisIdListFiltered as $devis){
$factureId = $this->insertFactureByDevisId($idNextCloud,$devis['id'],$devis['devis_date'],$paymentDate);
$facture = $this->getFactureIdByDevisId($devis['id']);
if($facture != null){
$factureId = $facture['id'];
}
else{
$factureId = $this->insertFactureByDevisId($idNextCloud,$devis['id'],$devis['devis_date'],$paymentDate);
}
$factureIdsGenerated[] = $factureId;
}
return $factureIdsGenerated;
@ -3271,7 +3286,7 @@ class Bdd {
}
private function getDevisTalkRoomClientContent($clientPrenom){
$message = ". Pour PF: ";
$message = "Pour PF: ";
$clientNameContent = "aucun";
$clientPrenomIsSet = $clientPrenom != null && $clientPrenom != "" && $clientPrenom != "-";
if($clientPrenomIsSet){
@ -3293,8 +3308,16 @@ class Bdd {
}
$calendarData = $this->getCalendarDataByCalendarObjectUuid($devis->num);
$devisTimeValue = VCalendarHelpers::GetStartAndEndTimeFromVCalendarString($calendarData);
$devis->startTime = $devisTimeValue["startTime"];
$devis->endTime = $devisTimeValue["endTime"];
$startTimeValueWithMinutes = "";
$endTimeValueWithMinutes = "";
if($devisTimeValue["datetimeStart"]){
$startTimeValueWithMinutes = $devisTimeValue["datetimeStart"]->format('H\hi');
}
if($devisTimeValue["datetimeEnd"]){
$endTimeValueWithMinutes = $devisTimeValue["datetimeEnd"]->format('H\hi');
}
$devis->startTime = $startTimeValueWithMinutes;
$devis->endTime = $endTimeValueWithMinutes;
$devisProducts = $this->getDevisProduits($devisId);
$devisProducts = json_encode($devisProducts);
$devisProducts = json_decode($devisProducts);
@ -3306,7 +3329,7 @@ class Bdd {
if(empty($devisProducts)){
return "";
}
$productMessage = ". ACTE A FAIRE : ";
$productMessage = "ACTE A FAIRE : ";
foreach($devisProducts as $product){
$productMessage.= html_entity_decode($product->produit_reference).", ";
}
@ -3324,19 +3347,24 @@ class Bdd {
$devisDate = $devisDate->format('d/m/Y');
$message = "NOUVELLE INTERVENTION: ";
$message .= html_entity_decode($devis->nom_defunt) . ' ';
$message .= 'le '.$devisDate. ' ';
$message .= 'à '.$devis->startTime. ' ';
$message .= 'à '.html_entity_decode($devis->lieu). ' '. html_entity_decode($devis->adresse_soin);
$message .= '
le '.$devisDate;
$message .= ' à '.$devis->startTime. ' ';
$message .= '
à '.html_entity_decode($devis->lieu). ' '. html_entity_decode($devis->adresse_soin);
$clientMessageContent = $this->getDevisTalkRoomClientContent($devis->prenom);
$message .= $clientMessageContent;
$message .= '
'.$clientMessageContent;
$productMessage = $this->getDevisTalkRoomProductSectionMessage($devis->products);
$message .= $productMessage;
$message .= '
'.$productMessage;
$comment = "aucun";
if(strtolower($devis->comment) != "commentaire" && $devis->comment != ""){
$comment = html_entity_decode($devis->comment);
}
$message .= ". COMMENTAIRES: ".$comment.". ";
$message .= "
COMMENTAIRES: ".$comment;
$locationCodes = [
"Code portail" => $devis->portal_code,
"Code alarme" => $devis->alarm_code,
@ -3351,8 +3379,209 @@ class Bdd {
$locationCodeMessageContent .= $label. ": ".$value.". ";
}
$locationCodeMessageContent = trim($locationCodeMessageContent);
$message .= $locationCodeMessageContent;
$message .= '
'.$locationCodeMessageContent;
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,32 @@ class VCalendarHelpers
}
}
public static function GetStartAndEndTimeFromVCalendarString(string $vCalendarString)
{
public static function GetStartAndEndTimeFromVCalendarString(string $vCalendarString){
$startTimeValue = "";
$endTimeValue = "";
if ($vCalendarString != "") {
$totalHours = 0;
$totalWorkedHours = 0;
$dateStart = null;
$dateEnd = null;
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 [
"datetimeStart" => $dateStart,
"datetimeEnd" => $dateEnd,
"startTime" => $startTimeValue,
"endTime" => $endTimeValue
"endTime" => $endTimeValue,
"totalHours" => $totalHours,
"totalWorkedHours" => $totalWorkedHours
];
}
@ -67,6 +76,17 @@ class VCalendarHelpers
{
return str_contains($vCalendarString, 'ATTACH;FMTTYPE');
}
public static function hasEmailIdInVCalendar(string $vCalendarString): bool
{
return self::getEmailIdInVCalendar("EMAILID", $vCalendarString) ? true : false;
}
public static function getEmailIdInVCalendar(string $vCalendarString): string|int|null
{
return self::GetValueFromKeyInVCalendarString("EMAILID", $vCalendarString) ?? null;
}
public static function extractAttachments(string $vCalendarString): array
{
$attachments = [];

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,144 @@ 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.';'.
$restValue.';'.
$diseaseValue.';'.
''.';'.
''.';'.
''.';'.
''.';'.
''.';'.
''.';'.
''.';'.
''.';'.
''.';'.
''.';'.
''.';'."\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;
}
}
}
$totalAbsenceHours = $totalLeaveHours + $totalRestHours + $totalDiseaseHours;
$totalWorkedHours -= $totalAbsenceHours;
}
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;
}
}
}
$totalAbsenceHours = $totalLeaveHours + $totalRestHours + $totalDiseaseHours;
$totalWorkedHours -= $totalAbsenceHours;
}
$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 +266,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 +289,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 +297,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

@ -26,7 +26,6 @@ declare(strict_types=1);
namespace OCA\Gestion\Service;
use GuzzleHttp\Exception\GuzzleException;
use OCP\IConfig;
use OCP\DB\Exception;
use OCP\IUserSession;
@ -37,12 +36,17 @@ use OC\Files\Filesystem;
use OCP\Files\IRootFolder;
use OCA\Gestion\Db\OrderBdd;
use Psr\Log\LoggerInterface;
use OCA\Mail\Contracts\IMailManager;
use OCA\Mail\IMAP\IMAPClientFactory;
use OCA\Mail\Service\AccountService;
use OCA\Gestion\Constants\BddConstant;
use OCA\Gestion\Helpers\FolderHelpers;
use GuzzleHttp\Exception\GuzzleException;
use OCA\Gestion\Helpers\VCalendarHelpers;
use OCA\Gestion\Constants\OrderStatusConstant;
use OCA\Gestion\Constants\ThanatoTypeConstant;
use OCA\Gestion\Service\Order\OrderPdfService;
use OCP\AppFramework\Db\DoesNotExistException;
use OCA\Gestion\Constants\DevisMentionConstant;
use OCA\Gestion\Service\Devis\Pdf\DevisPdfService;
use OCA\Gestion\Constants\VCalendarPropertyConstant;
@ -62,8 +66,6 @@ class GestionService {
private $orderPdfService;
private $devisPdfService;
private $userSession;
private string $userConnectedUuid;
private $userConnectedStorage;
@ -72,8 +74,17 @@ class GestionService {
protected $config;
private IMailManager $mailManager;
private $accountService;
private IMAPClientFactory $clientFactory;
private ?string $currentUserId;
public function __construct(
?string $UserId,
Bdd $gestionBdd,
OrderBdd $orderBdd,
LoggerInterface $logger,
@ -84,19 +95,26 @@ class GestionService {
IRootFolder $rootFolder,
IMailer $mailer,
IConfig $config,
IMailManager $mailManager,
AccountService $accountService,
IMAPClientFactory $clientFactory,
) {
$this->currentUserId = $UserId;
$this->orderBdd = $orderBdd;
$this->logger = $logger;
$this->gestionBdd = $gestionBdd;
$this->orderPdfService = $orderPdfService;
$this->devisPdfService = $devisPdfService;
$this->talkService = $talkService;
$this->userSession = $userSession;
$this->userConnectedUuid = $userSession->getUser()?->getUID() ?? BddConstant::DEFAULT_ADMIN_APP_ID_NEXTCLOUD;
$this->userConnectedStorage = $rootFolder->getUserFolder($this->userConnectedUuid);
$this->mailer = $mailer;
$this->config = $config;
$this->mailManager = $mailManager;
$this->accountService = $accountService;
$this->clientFactory = $clientFactory;
}
@ -208,8 +226,10 @@ class GestionService {
public function HandleCreatedCalendarObject(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;
}
@ -262,11 +282,15 @@ class GestionService {
if($devis != null && $devis["client_entreprise"] != null){
$destinationFolderAttachment = FolderHelpers::GetDefuntFolder($devis["client_entreprise"],$devis["defunt_nom"]);
$attachments = VCalendarHelpers::extractAttachments($vCalendarString);
$this->moveCalendarAttachmentFile($attachments,$destinationFolderAttachment);
if ($thanatoIsSubcontractor) {
$thanatoHasEmail = $thanato["thanato_email"] != null;
if($thanatoHasEmail){
$this->sendEmailAttachment($thanato["thanato_email"] , $devis["defunt_nom"],$attachments);
$emailBody = $this->extractBodyOfEmailAttachment(VCalendarHelpers::getEmailIdInVCalendar($vCalendarString));
$this->sendEmailAndAttachment($thanato["thanato_email"] , $devis["defunt_nom"],$emailBody ,$attachments);
}
}else {
$roomToken = $this->talkService->getRoomTokenBeetwenTwoUser($this->userConnectedUuid, $userName);
@ -412,10 +436,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){
@ -432,7 +458,8 @@ class GestionService {
$this->devisPdfService->generateDevisPdfByDevisId($devis['id'],$this->userConnectedUuid);
}
if (VCalendarHelpers::hasAttachment($vCalendarString)) {
if (VCalendarHelpers::hasAttachment($vCalendarString) || VCalendarHelpers::hasEmailIdInVCalendar($vCalendarString)) {
$thanato = $this->gestionBdd->getThanatoByThanatoId($devis['id_thanato']);
$thanatoIsSubcontractor = $thanato["fk_thanato_type_key"] === ThanatoTypeConstant::THANATO_TYPE_SUBCONTRACTOR;
@ -444,7 +471,8 @@ class GestionService {
if ($thanatoIsSubcontractor ) {
$thanatoHasEmail = $thanato["thanato_email"] != null;
if($thanatoHasEmail){
$this->sendEmailAttachment($thanato["thanato_email"] , $devis["defunt_nom"],$attachments);
$emailBody = $this->extractBodyOfEmailAttachment(VCalendarHelpers::getEmailIdInVCalendar($vCalendarString));
$this->sendEmailAndAttachment($thanato["thanato_email"] , $devis["defunt_nom"],$emailBody,$attachments);
}
}else{
@ -474,16 +502,42 @@ class GestionService {
}
}
public function sendEmailAttachment($to , $defunt_nom ,$attachments = []){
private function extractBodyOfEmailAttachment($emailId){
$messageId = (int) $emailId;
try {
$message = $this->mailManager->getMessage($this->currentUserId, $messageId);
$mailbox = $this->mailManager->getMailbox($this->currentUserId, $message->getMailboxId());
$account = $this->accountService->find($this->currentUserId, $mailbox->getAccountId());
} catch (DoesNotExistException $e) {
}
$client = $this->clientFactory->getClient($account);
try {
$imapMessage = $this->mailManager->getImapMessage(
$client,
$account,
$mailbox,
$message->getUid(), true
);
$fullMessage = $imapMessage->getFullMessage($messageId);
} finally {
$client->logout();
}
return $fullMessage["body"] ?? '';
}
public function sendEmailAndAttachment($to , $defunt_nom ,$emailBody = '' ,$attachments = []){
$this->userConnectedStorage->getFullPath("/");
$subject = "Piece jointe";
$body = "
<p>Bonjour.</p>
<p>Vous trouverez en pièce jointe les documents concernant de « $defunt_nom ».</p>
<p>Vous trouverez ci-dessous l'email et le(s) pièce(s) jointe(s) de « $defunt_nom ».</p>
<p>Vous en souhaitant bonne réception</p>
<p>Cordialement</p>
";
<div>$emailBody</div>";
$message = $this->mailer->createMessage();
$message->setSubject($subject);
@ -494,10 +548,10 @@ class GestionService {
$content = $this->mailer->createAttachment( Filesystem::file_get_contents($path),$attachment['name'],$attachment['mime_type']);
$message->attach($content);
}
$message->setHtmlBody( $body);
$message->setHtmlBody($body);
$this->mailer->send($message);
}
public function sendFileAttachmentToTalk($roomToken, $cookie , $fileName ) {