119 $currentUserId = \CCalendar::getCurUserId();
127 $resourseList = Internals\ResourceTable::query()
129 ->where(
'PARENT_TYPE', $userField[
'ENTITY_ID'])
130 ->where(
'PARENT_ID', $userField[
'VALUE_ID'])
131 ->where(
'UF_ID', $userField[
'ID'])
135 $currentEntriesIndex = [];
136 while ($resourse = $resourseList->fetch())
138 $currentEntriesIndex[$resourse[
'CAL_TYPE'].$resourse[
'RESOURCE_ID']] = $resourse;
141 if (self::isCrmEntity($userField[
'ENTITY_ID']) && Loader::includeModule(
'crm'))
143 if ($userField[
'ENTITY_ID'] === self::CRM_DEAL_ENTITY_ID)
145 $dealResult = \CCrmDeal::GetListEx(
147 [
'=ID' => $userField[
'VALUE_ID'],
'CHECK_PERMISSIONS' =>
'N'],
153 if (!empty($dealResult))
155 $entity = $dealResult->Fetch();
158 if (!empty($entity) && $entity[
'TITLE'])
160 $entityTitle =
Loc::getMessage(
"USER_TYPE_RESOURCE_EVENT_TITLE").
': '.$entity[
'TITLE'];
163 elseif ($userField[
'ENTITY_ID'] === self::CRM_LEAD_ENTITY_ID)
165 $leadResult = \CCrmLead::GetListEx(
167 [
'=ID' => $userField[
'VALUE_ID'],
'CHECK_PERMISSIONS' =>
'N'],
173 if (!empty($leadResult))
175 $entity = $leadResult->Fetch();
178 if (!empty($entity) && $entity[
'TITLE'])
180 $entityTitle =
Loc::getMessage(
"USER_TYPE_RESOURCE_EVENT_TITLE").
': '.$entity[
'TITLE'];
185 $userField[
'ENTITY_ID'] === self::CRM_SUSPENDED_DEAL_ENTITY_ID
186 || $userField[
'ENTITY_ID'] === self::CRM_SUSPENDED_LEAD_ENTITY_ID
189 $entityTitle =
Loc::getMessage(
"USER_TYPE_RESOURCE_EVENT_TITLE").
" (Deleted)";
199 foreach ($values as $value)
201 if ((
string)$value === (
string)((
int)$value))
203 $currentValue = static::fetchFieldValue($value);
204 $skipTime = is_array($userField[
'SETTINGS']) && $userField[
'SETTINGS'][
'FULL_DAY'] ===
'Y';
205 $fromTs = \CCalendar::timestamp($currentValue[
'DATE_FROM'],
true, !$skipTime);
206 $toTs = \CCalendar::timestamp($currentValue[
'DATE_TO'],
true, !$skipTime);
208 foreach ($currentValue[
'ENTRIES'] as $entry)
212 foreach ($values as $iValue)
214 $str = $entry[
'TYPE'].
'|'.$entry[
'RESOURCE_ID'];
215 if (str_starts_with($iValue, $str))
226 $entry[
'RESOURCE_ID'],
227 $currentValue[
'DATE_FROM'],
229 $currentValue[
'SERVICE_NAME']
236 $values = array_merge($values, $valuesToMerge);
238 foreach ($values as $value)
242 if (!is_array($value))
247 if (!$dateFrom || !$dateTo)
249 $dateFromTimestamp = \CCalendar::timestamp($value[
'from']);
250 $skipTime = isset($userField[
'SETTINGS']) && $userField[
'SETTINGS'][
'FULL_DAY'] ===
'Y';
251 $dateFrom = \CCalendar::date($dateFromTimestamp, !$skipTime);
252 $duration = (int)$value[
'duration'];
253 $dateTo = \CCalendar::date($dateFromTimestamp + ($skipTime ? $duration - \CCalendar::DAY_LENGTH : $duration), !$skipTime);
254 $serviceName = trim($value[
'serviceName']);
257 "DATE_FROM" => $dateFrom,
258 "DATE_TO" => $dateTo,
259 "SKIP_TIME" => $skipTime,
260 "NAME" => $entityTitle
264 $userField[
'ENTITY_ID'] === self::CRM_SUSPENDED_DEAL_ENTITY_ID
265 || $userField[
'ENTITY_ID'] === self::CRM_SUSPENDED_LEAD_ENTITY_ID
268 $fields[
"DELETED"] =
'Y';
271 if ($serviceName !==
'')
273 $fields[
"DESCRIPTION"] =
Loc::getMessage(
"USER_TYPE_RESOURCE_SERVICE_LABEL").
': '.$serviceName;
278 if ($userField[
'SETTINGS'][
'USE_USER_TIMEZONE'] ===
'Y')
280 $timezoneName = \CCalendar::getUserTimezoneName($currentUserId,
true);
282 else if($userField[
'SETTINGS'][
'TIMEZONE'])
284 $timezoneName = $userField[
'SETTINGS'][
'TIMEZONE'];
288 $timezoneName = \CCalendar::GetGoodTimezoneForOffset((
int)date(
"Z"));
293 $fields[
'TZ_FROM'] = $timezoneName;
294 $fields[
'TZ_TO'] = $timezoneName;
300 if (isset($currentEntriesIndex[$value[
'type'] . $value[
'id']]))
302 $fields[
'ID'] = $currentEntriesIndex[$value[
'type'].$value[
'id']][
'EVENT_ID'];
303 $entryId = $currentEntriesIndex[$value[
'type'].$value[
'id']][
'ID'];
307 unset($fields[
'ID']);
316 'userField' => $userField,
317 'serviceName' => $serviceName
321 if ($resourceBookingId)
323 $valuesToSave[] = $resourceBookingId;
327 foreach ($currentEntriesIndex as $resourceEntry)
329 if (!in_array($resourceEntry[
'ID'], $valuesToSave))
335 return $valuesToSave;
368 public static function saveResource($id, $resourceType, $resourceId, $eventFields = [], $params = [])
371 $currentUserId = \CCalendar::getCurUserId();
373 $eventFields[
"EVENT_TYPE"] =
'#resourcebooking#';
374 if ($resourceType ===
'user')
376 $eventFields[
"CAL_TYPE"] = $resourceType;
377 $eventFields[
"OWNER_ID"] = $resourceId;
379 if ($params[
'userField'][
'ENTITY_ID'] ===
'CRM_DEAL' || $params[
'userField'][
'ENTITY_ID'] ===
'CRM_LEAD')
381 $sectionId = \CCalendar::getCrmSection($resourceId,
true);
385 $sectionId = \CCalendar::getMeetingSection($resourceId,
true);
389 $eventFields[
'SECTIONS'] = [$sectionId];
394 if ($params[
'userField'][
'ENTITY_ID'] ===
'CRM_DEAL')
396 $userFields[
'UF_CRM_CAL_EVENT'] = [
"D_".$params[
'userField'][
'VALUE_ID']];
398 elseif ($params[
'userField'][
'ENTITY_ID'] ===
'CRM_LEAD')
400 $userFields[
'UF_CRM_CAL_EVENT'] = [
"L_".$params[
'userField'][
'VALUE_ID']];
403 $entryId = \CCalendar::saveEvent([
404 'arFields' => $eventFields,
406 'silentErrorMode' =>
false,
407 'autoDetectSection' =>
true,
408 'autoCreateSection' =>
true,
409 'checkPermission' =>
false
414 $eventFields[
"CAL_TYPE"] = $resourceType;
415 $eventFields[
"SECTIONS"] = $resourceId;
416 $entryId = \CCalendarEvent::edit([
417 'arFields' => $eventFields
423 if ($eventFields[
'TZ_FROM'] ??
null)
427 $fromUtc =
new Type\DateTime($eventFields[
"DATE_FROM"],
null,
new \DateTimeZone(
'UTC'));
428 $toUtc =
new Type\DateTime($eventFields[
"DATE_TO"],
null,
new \DateTimeZone(
'UTC'));
438 \CTimeZone::Disable();
440 $resourceTableFields = [
441 'EVENT_ID' => $entryId,
442 'CAL_TYPE' => $eventFields[
"CAL_TYPE"],
443 'RESOURCE_ID' => $resourceId,
444 'PARENT_TYPE' => $params[
'bindingEntityType'] ?? $params[
'userField'][
'ENTITY_ID'],
445 'PARENT_ID' => $params[
'bindingEntityId'] ?? $params[
'userField'][
'VALUE_ID'],
446 'UF_ID' => $params[
'bindingUserfieldId'] ?? $params[
'userField'][
'ID'],
447 'DATE_FROM' => $from,
449 'SKIP_TIME' => $eventFields[
'SKIP_TIME'] ??
null,
450 'DATE_FROM_UTC' => $fromUtc,
451 'DATE_TO_UTC' => $toUtc,
452 'TZ_FROM' => $eventFields[
'TZ_FROM'] ??
null,
453 'TZ_TO' => $eventFields[
'TZ_TO'] ??
null,
454 'TZ_OFFSET_FROM' => \CCalendar::getTimezoneOffset(
455 $eventFields[
'TZ_FROM'] ??
null,
456 \CCalendar::timestamp($eventFields[
"DATE_FROM"])
458 'TZ_OFFSET_TO' => \CCalendar::getTimezoneOffset(
459 $eventFields[
'TZ_TO'] ??
null,
460 \CCalendar::timestamp($eventFields[
"DATE_TO"])
462 'CREATED_BY' => $currentUserId,
463 'SERVICE_NAME' => $params[
'serviceName'] ?? null
468 $result = Internals\ResourceTable::update($id, $resourceTableFields);
472 $result = Internals\ResourceTable::add($resourceTableFields);
475 if ($result->isSuccess())
477 $valueToSave = $result->getId();
481 \CCalendar::deleteEvent((
int)$entryId,
false);
486 ExecuteModuleEventEx($event, [[
487 'userFieldValueId' => $valueToSave,
488 'bookingEventId' => $entryId,
489 'resourceType' => $resourceType,
490 'resourceId' => $resourceId,
491 'serviceName' => $params[
'serviceName'] ??
null,
494 'skipTime' => $eventFields[
'SKIP_TIME'],
495 'timezoneFrom' => $eventFields[
'TZ_FROM'] ??
null,
496 'timezoneTo' => $eventFields[
'TZ_TO'] ??
null,
500 \CTimeZone::Enable();
508 return in_array($entityId, [self::CRM_LEAD_ENTITY_ID, self::CRM_SUSPENDED_LEAD_ENTITY_ID,self::CRM_DEAL_ENTITY_ID, self::CRM_SUSPENDED_DEAL_ENTITY_ID]);
615 function getSettingsHTML($userField =
false, $htmlControl = [], $varsFromForm =
false)
617 \Bitrix\Main\UI\Extension::load([
'uf',
'calendar.resourcebookinguserfield',
'calendar_planner',
'socnetlogdest',
'helper',
'main',
'ui',
'ui.selector']);
621 $settingsValue =
$GLOBALS[$htmlControl[
"NAME"]];
623 elseif(is_array($userField))
625 $settingsValue = $userField[
"SETTINGS"];
632 $controlId = $userField[
'FIELD_NAME'].
'_'.rand();
634 'controlId' => $controlId,
635 'settings' => $settingsValue,
636 'userField' => $userField,
637 'htmlControl' => $htmlControl,
638 'outerWrapId' => $controlId.
'-settings-outer-wrap',
639 'formName' =>
'post_form'
642 if ($settingsValue[
'USE_USERS'] ===
'Y')
644 $params[
'socnetDestination'] = \CCalendar::getSocNetDestination(
false, [], $settingsValue[
'SELECTED_USERS']);
650 <div id="'.HtmlFilter::encode($params[
'outerWrapId']).
'"></div>
651 <script>(function(){new BX.Calendar.AdminSettingsViewer('.
652 \Bitrix\Main\Web\Json::encode($params).
653 ').showLayout();})();</script>
667 \Bitrix\Main\UI\Extension::load([
'uf',
'calendar.resourcebookinguserfield',
'calendar_planner',
'socnetlogdest']);
669 $fieldName = static::getFieldName($userField, $additionalParams);
670 $userField[
'VALUE'] = static::getFieldValue($userField, $additionalParams);
672 $value = static::fetchFieldValue($userField[
"VALUE"]);
675 $userField[
'SETTINGS'][
'USE_RESOURCES'] ===
'Y'
676 && (!is_array($userField[
'SETTINGS'][
'SELECTED_RESOURCES']) || empty($userField[
'SETTINGS'][
'SELECTED_RESOURCES']))
679 $userField[
'SETTINGS'][
'USE_RESOURCES'] =
'N';
682 $controlId = $userField[
'FIELD_NAME'].
'_'.rand();
684 'controlId' => $controlId,
685 'inputName' => $fieldName,
687 'plannerId' => $controlId.
'_planner',
688 'userSelectorId' =>
'resource_booking_user_selector',
689 'useUsers' => $userField[
'SETTINGS'][
'USE_USERS'] ===
'Y',
690 'useResources' => $userField[
'SETTINGS'][
'USE_RESOURCES'] ===
'Y',
691 'fullDay' => $userField[
'SETTINGS'][
'FULL_DAY'] ===
'Y',
692 'allowOverbooking' => $userField[
'SETTINGS'][
'ALLOW_OVERBOOKING'] !==
'N',
693 'useServices' => $userField[
'SETTINGS'][
'USE_SERVICES'] ===
'Y',
694 'serviceList' => $userField[
'SETTINGS'][
'SERVICE_LIST'],
695 'resourceList' => $userField[
'SETTINGS'][
'SELECTED_RESOURCES'],
696 'userList' => $userField[
'SETTINGS'][
'SELECTED_USERS'],
697 'userfieldId' => $userField[
'ID'],
699 'workTime' => [\COption::getOptionString(
'calendar',
'work_time_start', 9), \COption::getOptionString(
'calendar',
'work_time_end', 19)]
702 if ($params[
'useUsers'])
704 $params[
'socnetDestination'] = \CCalendar::getSocNetDestination(
false, [], $userField[
'SETTINGS'][
'SELECTED_USERS']);
710 <div
id=
"<?= HtmlFilter::encode($params['controlId'])?>" class=
"crm-entity-widget-resourcebook-container"></div>
714 BX.Runtime.loadExtension(
'calendar.resourcebookinguserfield').then(
function(exports)
716 if (exports &&
BX.type.isFunction(exports.ResourcebookingUserfield))
718 exports.ResourcebookingUserfield.initEditFieldController(<?= \
Bitrix\Main\Web\Json::encode($params)?>);
725 $html = ob_get_clean();
727 return static::getHelper()->wrapDisplayResult($html);
732 $context = $additionalParams[
'CONTEXT'] ??
'';
733 $value = static::fetchFieldValue($userField[
"VALUE"] ??
null);
734 $skipTime = is_array($userField[
'SETTINGS'] ??
null) && ($userField[
'SETTINGS'][
'FULL_DAY'] ??
null) ==
'Y';
735 $fromTs = \CCalendar::timestamp($value[
'DATE_FROM'] ??
null,
true, !$skipTime);
736 $toTs = \CCalendar::timestamp($value[
'DATE_TO'] ??
null,
true, !$skipTime);
742 $resourceIdList = [];
744 foreach($value[
'ENTRIES'] as $entry)
746 if ($entry[
'TYPE'] ===
'user')
748 $userIdList[] = (int) $entry[
'RESOURCE_ID'];
752 $resourceIdList[] = (int) $entry[
'RESOURCE_ID'];
756 $userIdList = array_unique($userIdList);
757 $resourceIdList = array_unique($resourceIdList);
759 if (!empty($userIdList))
761 $orm = UserTable::getList([
763 '=ID' => $userIdList,
766 'select' => [
'ID',
'LOGIN',
'NAME',
'LAST_NAME',
'SECOND_NAME',
'TITLE',
'PERSONAL_PHOTO']
769 while ($user = $orm->fetch())
771 $user[
'URL'] = \CCalendar::getUserUrl($user[
"ID"]);
776 if (!empty($resourceIdList))
778 $sectionList = Internals\SectionTable::getList(
782 "!=CAL_TYPE" => [
'user',
'group',
'company_calendar',
'company',
'calendar_company'],
783 "ID" => $resourceIdList
785 "select" => array(
"ID",
"CAL_TYPE",
"NAME")
789 while ($section = $sectionList->fetch())
791 $resources[$section[
'ID']] = $section;
796 if ($context ===
'CRM_GRID')
798 \Bitrix\Main\UI\Extension::load([
803 \Bitrix\Main\Page\Asset::getInstance()->addCss(
'/bitrix/js/calendar/userfield/resourcebooking.css');
807 foreach($users as $user)
809 $resListItems[] =
'<span>'.HtmlFilter::encode(\CCalendar::getUserName($user)).
'</span>';
812 if (!empty($resourceNames))
814 foreach($resourceNames as $resourceName)
816 $resListItems[] =
'<span>'.$resourceName.
'</span>';
820 if (!empty($resListItems))
822 $html =
'<span>'.\CCalendar::getFromToHtml($fromTs, $toTs, $skipTime, $toTs - $fromTs).
'</span>: ';
823 if(!empty($value[
'SERVICE_NAME']))
825 $html .=
'<span>'.HtmlFilter::encode($value[
'SERVICE_NAME']).
'</span>, ';
827 $html .=
'<span>'.implode(
', ', $resListItems).
'</span>';
831 $html =
'<span class="calendar-resbook-field-empty">'.Loc::getMessage(
"USER_TYPE_RESOURCE_EMPTY").
'</span>';
836 \Bitrix\Main\UI\Extension::load([
'uf',
'calendar.resourcebookinguserfield']);
837 if (empty($users) && empty($resourceNames))
845 <div
class=
"calendar-res-book-public-view-outer-wrap">
846 <div
class=
"calendar-res-book-public-view-inner-wrap">
847 <div
class=
"crm-entity-widget-content-block crm-entity-widget-content-block-field-select">
848 <div
class=
"crm-entity-widget-content-block-title">
850 class=
"crm-entity-widget-content-block-title-text"><?= ($skipTime ?
Loc::getMessage(
"USER_TYPE_RESOURCE_DATE_BLOCK_TITLE") :
Loc::getMessage(
"USER_TYPE_RESOURCE_DATETIME_BLOCK_TITLE")) ?></span>
853 class=
"crm-entity-widget-content-block-inner"><?= \CCalendar::getFromToHtml($fromTs, $toTs, $skipTime, $toTs - $fromTs) ?></div>
856 <?
if(!empty($value[
'SERVICE_NAME'])): ?>
857 <div
class=
"crm-entity-widget-content-block crm-entity-widget-content-block-field-select">
858 <div
class=
"crm-entity-widget-content-block-title">
860 class=
"crm-entity-widget-content-block-title-text"><?=
Loc::getMessage(
"USER_TYPE_RESOURCE_SERVICE_PLACEHOLDER") ?></span>
863 class=
"crm-entity-widget-content-block-inner"><?=
HtmlFilter::encode($value[
'SERVICE_NAME']) ?></div>
867 <?
if (!empty($users)): ?>
868 <div
class=
"crm-entity-widget-content-block crm-entity-widget-content-block-field-select">
869 <div
class=
"crm-entity-widget-content-block-title">
871 class=
"crm-entity-widget-content-block-title-text"><?=
Loc::getMessage(
"USER_TYPE_RESOURCE_USERS_CONTROL_DEFAULT_NAME") ?></span>
873 <?
foreach($users as $user): ?>
874 <div
class=
"crm-widget-employee-container">
875 <a
class=
"crm-widget-employee-avatar-container" href=
"<?= $user['URL'] ?>" target=
"_blank" style=
"background-image: url('<?= \CCalendar::getUserAvatarSrc($user) ?>'); background-size: 30px;"></a>
876 <span
class=
"crm-widget-employee-info"><a
class=
"crm-widget-employee-name" href=
"<?= $user['URL']?>" target=
"_blank"><?=
HtmlFilter::encode(\CCalendar::getUserName($user))?></a><span
class=
"crm-widget-employee-position"></span></span>
882 <?
if (!empty($resourceNames)): ?>
883 <div
class=
"crm-entity-widget-content-block crm-entity-widget-content-block-field-select">
884 <div
class=
"crm-entity-widget-content-block-title">
886 class=
"crm-entity-widget-content-block-title-text"><?=
Loc::getMessage(
"USER_TYPE_RESOURCE_RESOURCE_CONTROL_DEFAULT_NAME") ?></span>
888 <div
class=
"crm-entity-widget-content-block-inner"><?= implode(
', ', $resourceNames) ?></div>
894 $html = ob_get_clean();
898 if ($context ===
'UI_EDITOR')
900 $html =
'<span class="field-item">' . $html .
'</span>';
903 return static::getHelper()->wrapDisplayResult($html);
909 $value = static::fetchFieldValue($userField[
"VALUE"]);
915 $resourseIdList = [];
917 foreach($value[
'ENTRIES'] as $entry)
919 if ($entry[
'TYPE'] ===
'user')
921 $userIdList[] = (int) $entry[
'RESOURCE_ID'];
925 $resourseIdList[] = (int) $entry[
'RESOURCE_ID'];
929 $userIdList = array_unique($userIdList);
930 $resourseIdList = array_unique($resourseIdList);
932 if (!empty($userIdList))
934 $orm = UserTable::getList([
936 '=ID' => $userIdList,
939 'select' => [
'ID',
'LOGIN',
'NAME',
'LAST_NAME',
'SECOND_NAME',
'TITLE',
'PERSONAL_PHOTO']
942 while ($user = $orm->fetch())
944 $user[
'URL'] = \CCalendar::getUserUrl($user[
"ID"]);
949 if (!empty($resourseIdList))
951 $sectionList = Internals\SectionTable::getList(
955 "!=CAL_TYPE" => [
'user',
'group',
'company_calendar',
'company',
'calendar_company'],
956 "ID" => $resourseIdList
958 "select" => array(
"ID",
"CAL_TYPE",
"NAME")
962 while ($section = $sectionList->fetch())
964 $resources[$section[
'ID']] = $section;
965 $resourceNames[] = $section[
'NAME'];
972 foreach($users as $user)
974 $resListItems[] = \CCalendar::getUserName($user);
977 if (!empty($resourceNames))
979 foreach($resourceNames as $resourceName)
981 $resListItems[] = $resourceName;
985 if (!empty($resListItems))
987 $skipTime = is_array($userField[
'SETTINGS']) && $userField[
'SETTINGS'][
'FULL_DAY'] ===
'Y';
988 $fromTs = isset($value[
'DATE_FROM']) ? \CCalendar::timestamp($value[
'DATE_FROM'],
true, !$skipTime) : 0;
989 $toTs = isset($value[
'DATE_TO']) ? \CCalendar::timestamp($value[
'DATE_TO'],
true, !$skipTime) : 0;
991 $resultText = \CCalendar::getFromToHtml($fromTs, $toTs, $skipTime, $toTs - $fromTs).
': ';
992 $resultText = str_replace(
"–",
'-', $resultText);
993 if(!empty($value[
'SERVICE_NAME']))
995 $resultText .= $value[
'SERVICE_NAME'].
', ';
997 $resultText .= implode(
', ', $resListItems);
1006 $typeList = Internals\TypeTable::getList(
1009 "XML_ID" => self::RESOURCE_CALENDAR_TYPE
1011 "select" => array(
"XML_ID",
"NAME")
1015 while ($type = $typeList->fetch())
1017 $type[
'SECTIONS'] = [];
1018 $result[$type[
'XML_ID']] = $type;
1021 if (!$result[self::RESOURCE_CALENDAR_TYPE])
1023 Internals\TypeTable::add([
1024 'XML_ID' => self::RESOURCE_CALENDAR_TYPE,
1025 'NAME' => self::RESOURCE_CALENDAR_TYPE,
1028 \CCalendar::ClearCache(
'type_list');
1036 $sectionList = Internals\SectionTable::getList(
1040 "CAL_TYPE" => [self::RESOURCE_CALENDAR_TYPE],
1043 "select" => array(
"ID",
"CAL_TYPE",
"NAME")
1047 while ($section = $sectionList->fetch())
1049 if (is_array($result[$section[
'CAL_TYPE']][
'SECTIONS']))
1051 $result[$section[
'CAL_TYPE']][
'SECTIONS'][] = $section;
1060 $resourseList = Internals\ResourceTable::getList(
1072 while ($resourse = $resourseList->fetch())
1074 if (!isset($result[
'DATE_FROM']))
1076 \CTimeZone::Disable();
1077 $result[
'DATE_FROM'] = $resourse[
'DATE_FROM']->toString();
1078 $result[
'DATE_TO'] = $resourse[
'DATE_TO']->toString();
1079 $result[
'SERVICE_NAME'] = $resourse[
'SERVICE_NAME'];
1080 \CTimeZone::Enable();
1082 $fromTs = \CCalendar::timestamp($result[
'DATE_FROM']);
1083 $toTs = \CCalendar::timestamp($result[
'DATE_TO']);
1085 if (!$resourse[
'SKIP_TIME'])
1087 $currentUserID = \CCalendar::getCurUserId();
1089 $userOffsetFrom = \CCalendar::getTimezoneOffset($resourse[
'TZ_FROM'], $fromTs) - \CCalendar::getCurrentOffsetUTC($currentUserID);
1090 $userOffsetTo = \CCalendar::getTimezoneOffset($resourse[
'TZ_TO'], $toTs) - \CCalendar::getCurrentOffsetUTC($currentUserID);
1092 $result[
'DATE_FROM'] = \CCalendar::date($fromTs - $userOffsetFrom);
1093 $result[
'DATE_TO'] = \CCalendar::date($toTs - $userOffsetTo);
1097 $result[
'DATE_TO'] = \CCalendar::date($toTs + \CCalendar::DAY_LENGTH);
1101 $result[
'ENTRIES'][] = array(
1102 'ID' => $resourse[
'ID'],
1103 'EVENT_ID' => $resourse[
'EVENT_ID'],
1104 'TYPE' => $resourse[
'CAL_TYPE'],
1105 'RESOURCE_ID' => $resourse[
'RESOURCE_ID']
1174 $r = \CUserTypeEntity::getList(array(
"ID" =>
"ASC"), array(
"FIELD_NAME" => $fieldName));
1177 $resultData = $r->fetch();
1181 if (!is_array($selectedUsers))
1183 $selectedUsers = [];
1185 if (is_array($resultData) && isset($resultData[
'SETTINGS'][
'SELECTED_USERS']))
1187 $selectedUsers = array_merge($selectedUsers, $resultData[
'SETTINGS'][
'SELECTED_USERS']);
1190 array_walk($selectedUsers,
'intval');
1191 $selectedUsers = array_unique($selectedUsers);
1193 if (!empty($selectedUsers))
1195 $orm = UserTable::getList([
1197 '=ID' => $selectedUsers,
1200 'select' => [
'ID',
'LOGIN',
'NAME',
'LAST_NAME',
'SECOND_NAME',
'EMAIL']
1203 $resultData[
'SETTINGS'][
'USER_INDEX'] = [];
1204 while($user = $orm->fetch())
1206 $resultData[
'SETTINGS'][
'USER_INDEX'][$user[
'ID']] = [
1207 'id' => $user[
'ID'],
1208 'displayName' => \CCalendar::getUserName($user)
1220 $curUserId = $USER->GetID();
1222 if (isset($params[
'from']) && $params[
'from'] instanceof
Date
1223 && isset($params[
'to']) && $params[
'to'] instanceof
Date
1227 $from = $params[
'from']->toString();
1228 $to = $params[
'to']->toString();
1232 $fromTs = (isset($params[
'from']) && $params[
'from']) ? \CCalendar::timestamp($params[
'from']) : time();
1233 $from = \CCalendar::date($fromTs,
false);
1234 $to = (isset($params[
'to']) && $params[
'to'])
1235 ? \CCalendar::date(\CCalendar::timestamp($params[
'to']),
false)
1236 : \CCalendar::date($fromTs + \CCalendar::DAY_LENGTH * 60,
false);
1239 if (isset($params[
'timezone']))
1241 $deltaOffset = \CCalendar::GetTimezoneOffset($params[
'timezone']) - \CCalendar::GetCurrentOffsetUTC($curUserId);
1247 $resultData[
'timezoneOffset'] = 0;
1250 if ($params[
'fieldName'])
1252 $r = \CUserTypeEntity::getList(array(
"ID" =>
"ASC"), array(
"FIELD_NAME" => $params[
'fieldName']));
1255 $fieldProperties = $r->fetch();
1256 $resultData[
'fieldSettings'] = $fieldProperties[
'SETTINGS'];
1258 if ($resultData[
'fieldSettings'][
'USE_USER_TIMEZONE'] ===
'N')
1260 $resultData[
'timezoneOffset'] = $resultData[
'fieldSettings'][
'TIMEZONE'] ? \CCalendar::GetTimezoneOffset($resultData[
'fieldSettings'][
'TIMEZONE']) : intval(date(
"Z"));
1261 $resultData[
'timezoneOffsetLabel'] =
'UTC'.($resultData[
'timezoneOffset'] <> 0 ?
' '.($resultData[
'timezoneOffset'] < 0?
'-':
'+').sprintf(
"%02d", ($h = floor(abs($resultData[
'timezoneOffset'])/3600))).
':'.sprintf(
"%02d", abs($resultData[
'timezoneOffset']) / 60 - $h * 60) :
'');
1266 if (isset($data[
'users']))
1268 $userIdList = is_array($data[
'users'][
'value'])
1269 ? $data[
'users'][
'value']
1270 : explode(
'|', $data[
'users'][
'value']);
1271 array_walk($userIdList,
'intval');
1273 $resultData[
'usersAccessibility'] = [];
1274 $accessibility = \CCalendar::getAccessibilityForUsers(array(
1275 'users' => $userIdList,
1278 'getFromHR' =>
true,
1279 'checkPermissions' =>
false
1282 foreach($accessibility as $userId => $entries)
1284 $resultData[
'usersAccessibility'][$userId] = [];
1286 foreach($entries as $entry)
1288 if (isset($entry[
'DT_FROM']) && !isset($entry[
'DATE_FROM']))
1290 $resultData[
'usersAccessibility'][$userId][] = array(
1291 'id' => $entry[
'ID'],
1292 'dateFrom' => $entry[
'DT_FROM'],
1293 'dateTo' => $entry[
'DT_TO'],
1298 $fromTs = \CCalendar::Timestamp($entry[
'DATE_FROM']);
1299 $toTs = \CCalendar::Timestamp($entry[
'DATE_TO']);
1301 if ($entry[
'DT_SKIP_TIME'] !==
"Y")
1303 if ($resultData[
'fieldSettings'][
'USE_USER_TIMEZONE'] ===
'N')
1305 $fromTs -= \CCalendar::GetTimezoneOffset($entry[
'TZ_FROM']) - $resultData[
'timezoneOffset'];
1306 $toTs -= \CCalendar::GetTimezoneOffset($entry[
'TZ_TO']) - $resultData[
'timezoneOffset'];
1310 $fromTs -= $entry[
'~USER_OFFSET_FROM'];
1311 $toTs -= $entry[
'~USER_OFFSET_TO'];
1312 $fromTs += $deltaOffset;
1313 $toTs += $deltaOffset;
1317 $resultData[
'usersAccessibility'][$userId][] = array(
1318 'id' => $entry[
'ID'],
1319 'dateFrom' => \CCalendar::Date($fromTs, $entry[
'DT_SKIP_TIME'] !=
'Y'),
1320 'dateTo' => \CCalendar::Date($toTs, $entry[
'DT_SKIP_TIME'] !=
'Y'),
1321 'fullDay' => $entry[
'DT_SKIP_TIME'] ===
"Y"
1328 $orm = UserTable::getList(
1331 '=ID' => $userIdList,
1334 'select' => [
'ID',
'LOGIN',
'NAME',
'LAST_NAME',
'SECOND_NAME',
'EMAIL']
1338 $resultData[
'SETTINGS'][
'USER_INDEX'] = [];
1339 while($user = $orm->fetch())
1341 $resultData[
'userIndex'][$user[
'ID']] = [
1342 'id' => $user[
'ID'],
1343 'displayName' => \CCalendar::getUserName($user)
1348 if (isset($data[
'resources']))
1350 $resultData[
'resourcesAccessibility'] = [];
1352 $resourceIdList = is_array($data[
'resources'][
'value'])
1353 ? $data[
'resources'][
'value']
1354 : explode(
'|', $data[
'resources'][
'value']);
1356 array_walk($resourceIdList,
'intval');
1358 $resEntries = \CCalendarEvent::getList(
1360 'arFilter' => array(
1361 "FROM_LIMIT" => $from,
1363 "CAL_TYPE" =>
'resource',
1364 "ACTIVE_SECTION" =>
"Y",
1365 "SECTION" => $resourceIdList
1367 'parseRecursion' =>
true,
1368 'setDefaultLimit' =>
false
1372 foreach($resEntries as $row)
1374 $fromTs = \CCalendar::timestamp($row[
"DATE_FROM"]);
1375 $toTs = \CCalendar::timestamp($row[
'DATE_TO']);
1377 if ($row[
'DT_SKIP_TIME'] !==
"Y" && $resultData[
'fieldSettings'][
'USE_USER_TIMEZONE'] !==
'N')
1379 if ($resultData[
'fieldSettings'][
'USE_USER_TIMEZONE'] ===
'N')
1381 $fromTs -= \CCalendar::GetTimezoneOffset($entry[
'TZ_FROM']) - $resultData[
'timezoneOffset'];
1382 $toTs -= \CCalendar::GetTimezoneOffset($entry[
'TZ_TO']) - $resultData[
'timezoneOffset'];
1386 $fromTs -= $row[
'~USER_OFFSET_FROM'];
1387 $toTs -= $row[
'~USER_OFFSET_TO'];
1388 $fromTs += $deltaOffset;
1389 $toTs += $deltaOffset;
1393 $resultData[
'resourcesAccessibility'][$row[
'SECT_ID']][] = array(
1395 'dateFrom' => \CCalendar::date($fromTs, $row[
'DT_SKIP_TIME'] !==
'Y'),
1396 'dateTo' => \CCalendar::date($toTs, $row[
'DT_SKIP_TIME'] !==
'Y'),
1397 'fullDay' => $row[
'DT_SKIP_TIME'] ===
"Y"
1402 $resultData[
'workTimeStart'] = floor(floatVal(\COption::GetOptionString(
'calendar',
'work_time_start', 9)));
1403 $resultData[
'workTimeEnd'] = ceil(floatVal(\COption::GetOptionString(
'calendar',
'work_time_end', 19)));
1410 $from = (isset($options[
'from']) && $options[
'from'] instanceof
Date) ? $options[
'from'] :
new Date();
1411 if (isset($options[
'to']) && ($options[
'to'] instanceof
Date))
1413 $to = $options[
'to'];
1418 $to->add($options[
'dateInterval'] ??
'P5D');
1421 $formData = \Bitrix\Calendar\UserField\ResourceBooking::getFillFormData(
1422 $options[
'settingsData'],
1424 'fieldName' => $fieldName,
1431 $accessibility = [];
1432 if ($formData[
'fieldSettings'][
'USE_USERS'] ===
'Y'
1433 && isset($options[
'settingsData'][
'users'][
'value']))
1435 $selectedUser = $options[
'settingsData'][
'users'][
'value'];
1437 isset($formData[
'usersAccessibility'])
1438 && isset($formData[
'usersAccessibility'][$selectedUser])
1441 $accessibility = array_merge($accessibility, $formData[
'usersAccessibility'][$selectedUser]);
1445 if ($formData[
'fieldSettings'][
'USE_RESOURCES'] ===
'Y'
1446 && isset($options[
'settingsData'][
'resources'][
'value']))
1448 $selectedResource = $options[
'settingsData'][
'resources'][
'value'];
1450 isset($formData[
'resourcesAccessibility'])
1451 && isset($formData[
'resourcesAccessibility'][$selectedResource])
1454 $accessibility = array_merge($accessibility, $formData[
'resourcesAccessibility'][$selectedResource]);
1459 if ($selectedUser || $selectedResource)
1461 $format = Date::convertFormatToPhp(FORMAT_DATETIME);
1462 foreach ($accessibility as $i => $item)
1464 $accessibility[$i][
'fromTs'] = (
new DateTime($item[
'dateFrom'], $format))->getTimestamp();
1465 $accessibility[$i][
'toTs'] = (
new DateTime($item[
'dateTo'], $format))->getTimestamp();
1468 $result = self::getAvailableTimeSlots($accessibility, [
1471 'scale' => $options[
'settingsData'][
'time'][
'scale']
1534 if (!isset($dateFrom) || !($dateFrom instanceof
DateTime))
1536 throw new \Bitrix\Main\SystemException(
'Wrong dateFrom value type. DateTime expected');
1538 if (empty($fieldName))
1540 throw new \Bitrix\Main\SystemException(
'Wrong fieldName given');
1544 if (!empty($options[
'settingsData'][
'duration'][
'value']))
1546 $duration = $options[
'settingsData'][
'duration'][
'value'];
1548 else if (!empty($options[
'settingsData'][
'duration'][
'defaultValue']))
1550 $duration = $options[
'settingsData'][
'duration'][
'defaultValue'];
1553 $r = \CUserTypeEntity::getList([
"ID" =>
"ASC"], [
"FIELD_NAME" => $fieldName]);
1556 $fieldProperties = $r->fetch();
1557 $fieldSettings = $fieldProperties[
'SETTINGS'];
1559 if ($fieldSettings[
'USE_USERS'] ===
'Y'
1560 && isset($options[
'settingsData'][
'users'][
'value']))
1562 $result[] =
self::prepareValue(
'user', $options[
'settingsData'][
'users'][
'value'], $dateFrom->toString(), $duration);
1565 if ($fieldSettings[
'USE_RESOURCES'] ===
'Y'
1566 && isset($options[
'settingsData'][
'resources'][
'value']))
1568 $result[] =
self::prepareValue(
'resource', $options[
'settingsData'][
'resources'][
'value'], $dateFrom->toString(), $duration);