YetiForceCompany/YetiForceCRM

View on GitHub
modules/Calendar/models/Calendar.php

Summary

Maintainability
D
1 day
Test Coverage
F
0%
<?php

/**
 * Calendar Model Class.
 *
 * @copyright YetiForce S.A.
 * @license   YetiForce Public License 6.5 (licenses/LicenseEN.txt or yetiforce.com)
 * @author    YetiForce S.A.
 */
class Calendar_Calendar_Model extends Vtiger_Calendar_Model
{
    public $moduleName = 'Calendar';
    public $module;
    public $relationAcounts = [
        'Contacts' => ['vtiger_contactdetails', 'contactid', 'parentid'],
        'Project' => ['vtiger_project', 'projectid', 'linktoaccountscontacts'],
        'HelpDesk' => ['vtiger_troubletickets', 'ticketid', 'parent_id'],
        'ServiceContracts' => ['vtiger_servicecontracts', 'servicecontractsid', 'sc_related_to'],
    ];

    /**
     * Get query.
     *
     * @return \App\Db\Query
     */
    public function getQuery()
    {
        $queryGenerator = new App\QueryGenerator($this->getModuleName());
        if ($this->has('customFilter')) {
            $queryGenerator->initForCustomViewById($this->get('customFilter'));
        }
        $queryGenerator->setFields(array_keys($queryGenerator->getModuleFields()));
        $queryGenerator->setField('id');
        if ($types = $this->get('types')) {
            $queryGenerator->addCondition('activitytype', implode('##', $types), 'e');
        }
        switch ($this->get('time')) {
            case 'current':
                $queryGenerator->addCondition('activitystatus', implode('##', Calendar_Module_Model::getComponentActivityStateLabel('current')), 'e');
                break;
            case 'history':
                $queryGenerator->addCondition('activitystatus', implode('##', Calendar_Module_Model::getComponentActivityStateLabel('history')), 'e');
                break;
            default:
                break;
        }
        if (!empty($this->get('activitystatus'))) {
            $queryGenerator->addNativeCondition(['vtiger_activity.status' => $this->get('activitystatus')]);
        }
        if ($this->get('start') && $this->get('end')) {
            $dbStartDateOject = DateTimeField::convertToDBTimeZone($this->get('start'));
            $dbStartDateTime = $dbStartDateOject->format('Y-m-d H:i:s');
            $dbStartDate = $dbStartDateOject->format('Y-m-d');
            $dbEndDateObject = DateTimeField::convertToDBTimeZone($this->get('end'));
            $dbEndDateTime = $dbEndDateObject->format('Y-m-d H:i:s');
            $dbEndDate = $dbEndDateObject->format('Y-m-d');
            $queryGenerator->addNativeCondition([
                'or',
                [
                    'and',
                    ['>=', new \yii\db\Expression("CONCAT(date_start, ' ', time_start)"), $dbStartDateTime],
                    ['<=', new \yii\db\Expression("CONCAT(date_start, ' ', time_start)"), $dbEndDateTime],
                ],
                [
                    'and',
                    ['>=', new \yii\db\Expression("CONCAT(due_date, ' ', time_end)"), $dbStartDateTime],
                    ['<=', new \yii\db\Expression("CONCAT(due_date, ' ', time_end)"), $dbEndDateTime],
                ],
                [
                    'and',
                    ['<', 'date_start', $dbStartDate],
                    ['>', 'due_date', $dbEndDate],
                ],
            ]);
        }
        $query = $queryGenerator->createQuery();
        if ($this->has('filters')) {
            foreach ($this->get('filters') as $filter) {
                $filterClassName = Vtiger_Loader::getComponentClassName('CalendarFilter', $filter['name'], 'Calendar');
                $filterInstance = new $filterClassName();
                if ($filterInstance->checkPermissions() && $conditions = $filterInstance->getCondition($filter['value'])) {
                    $query->andWhere($conditions);
                }
            }
        }
        $conditions = [];
        if (!empty($this->get('user')) && isset($this->get('user')['selectedIds'][0])) {
            $selectedUsers = $this->get('user');
            $selectedIds = $selectedUsers['selectedIds'];
            if ('all' !== $selectedIds[0]) {
                $conditions[] = ['vtiger_crmentity.smownerid' => $selectedIds];
                $subQuery = (new \App\Db\Query())->select(['crmid'])->from('u_#__crmentity_showners')->where(['userid' => $selectedIds]);
                $conditions[] = ['vtiger_crmentity.crmid' => $subQuery];
            }
            if (isset($selectedUsers['excludedIds']) && 'all' === $selectedIds[0]) {
                $conditions[] = ['not in', 'vtiger_crmentity.smownerid', $selectedUsers['excludedIds']];
            }
        }
        if ($conditions) {
            $query->andWhere(array_merge(['or'], $conditions));
        }
        $query->orderBy('vtiger_activity.date_start,vtiger_activity.time_start');

        return $query;
    }

    /**
     * Gets entity data.
     *
     * @throws \App\Exceptions\NoPermittedToRecord
     *
     * @return array
     */
    public function getEntity()
    {
        $return = [];
        $currentUser = \App\User::getCurrentUserModel();
        $moduleModel = Vtiger_Module_Model::getInstance($this->getModuleName());
        $editForm = \App\Config::module('Calendar', 'SHOW_EDIT_FORM');
        $dataReader = $this->getQuery()->createCommand()->query();
        $colors = \App\Fields\Picklist::getColors('activitytype', false);
        while ($row = $dataReader->read()) {
            $item = [];
            if ($editForm && $moduleModel->getRecordFromArray($row)->setId($row['id'])->isEditable()) {
                $item['url'] = 'index.php?module=' . $this->getModuleName() . '&view=EventForm&record=' . $row['id'];
            } else {
                $item['url'] = 'index.php?module=' . $this->getModuleName() . '&view=ActivityState&record=' . $row['id'];
            }
            $item['module'] = $this->getModuleName();
            $item['title'] = \App\Purifier::encodeHtml($row['subject']);
            $item['id'] = $row['id'];
            $item['set'] = 'Task' == $row['activitytype'] ? 'Task' : 'Event';
            $dateTimeFieldInstance = new DateTimeField($row['date_start'] . ' ' . $row['time_start']);
            $userDateTimeString = $dateTimeFieldInstance->getFullcalenderDateTimevalue();
            $startDateTimeDisplay = $dateTimeFieldInstance->getDisplayDateTimeValue();
            $startTimeDisplay = $dateTimeFieldInstance->getDisplayTime();
            $dateTimeComponents = explode(' ', $userDateTimeString);
            $dateComponent = $dateTimeComponents[0];
            $startTimeFormated = $dateTimeComponents[1];
            //Conveting the date format in to Y-m-d . since full calendar expects in the same format
            $startDateFormated = DateTimeField::__convertToDBFormat($dateComponent, $currentUser->getDetail('date_format'));

            $dateTimeFieldInstance = new DateTimeField($row['due_date'] . ' ' . $row['time_end']);
            $userDateTimeString = $dateTimeFieldInstance->getFullcalenderDateTimevalue();
            $endDateTimeDisplay = $dateTimeFieldInstance->getDisplayDateTimeValue();
            $dateTimeComponents = explode(' ', $userDateTimeString);
            $dateComponent = $dateTimeComponents[0];
            $endTimeFormated = $dateTimeComponents[1];
            //Conveting the date format in to Y-m-d . since full calendar expects in the same format
            $endDateFormated = DateTimeField::__convertToDBFormat($dateComponent, $currentUser->getDetail('date_format'));

            $item['allDay'] = 1 == $row['allday'];
            $item['start_date'] = $row['date_start'];
            if ($item['allDay']) {
                $item['start'] = $startDateFormated;
                $item['end'] = $endDateFormated;
            } else {
                $item['start'] = $startDateFormated . ' ' . $startTimeFormated;
                $item['end'] = $endDateFormated . ' ' . $endTimeFormated;
            }

            $item['start_display'] = $startDateTimeDisplay;
            $item['end_display'] = $endDateTimeDisplay;
            $item['hour_start'] = $startTimeDisplay;
            $item['borderColor'] = $colors[$row['activitytype']] ?? '';
            $item['className'] = 'js-popover-tooltip--record ownerCBg_' . $row['assigned_user_id'];
            $return[] = $item;
        }
        $dataReader->close();
        return $return;
    }

    /**
     * Gets number of events.
     *
     * @return array
     */
    public function getEntityCount(): array
    {
        $colors = \App\Fields\Picklist::getColors('activitytype', false);
        $currentUser = Users_Record_Model::getCurrentUserModel();
        $startDate = DateTimeField::convertToDBTimeZone($this->get('start'));
        $startDate = strtotime($startDate->format('Y-m-d H:i:s'));
        $endDate = DateTimeField::convertToDBTimeZone($this->get('end'));
        $endDate = strtotime($endDate->format('Y-m-d H:i:s'));
        $dataReader = $this->getQuery()
            ->createCommand()
            ->query();
        $return = [];
        while ($record = $dataReader->read()) {
            $activityType = $record['activitytype'];

            $dateTimeFieldInstance = new DateTimeField($record['date_start'] . ' ' . $record['time_start']);
            $userDateTimeString = $dateTimeFieldInstance->getDisplayDateTimeValue($currentUser);
            $dateTimeComponents = explode(' ', $userDateTimeString);
            $dateComponent = $dateTimeComponents[0];
            $startDateFormated = DateTimeField::__convertToDBFormat($dateComponent, $currentUser->get('date_format'));

            $dateTimeFieldInstance = new DateTimeField($record['due_date'] . ' ' . $record['time_end']);
            $userDateTimeString = $dateTimeFieldInstance->getDisplayDateTimeValue($currentUser);
            $dateTimeComponents = explode(' ', $userDateTimeString);
            $dateComponent = $dateTimeComponents[0];
            $endDateFormated = DateTimeField::__convertToDBFormat($dateComponent, $currentUser->get('date_format'));

            $begin = new DateTime($startDateFormated);
            $end = new DateTime($endDateFormated);
            $end->modify('+1 day');
            $interval = DateInterval::createFromDateString('1 day');
            foreach (new DatePeriod($begin, $interval, $end) as $dt) {
                $date = strtotime($dt->format('Y-m-d'));
                if ($date >= $startDate && $date <= $endDate) {
                    $date = date('Y-m-d', $date);
                    $dateKey = $date . '__' . $activityType;

                    $return[$dateKey]['allDay'] = true;
                    $return[$dateKey]['start'] = $date;
                    if (isset($return[$dateKey]['title'])) {
                        ++$return[$dateKey]['title'];
                    } else {
                        $return[$dateKey]['title'] = 1;
                    }
                    $return[$dateKey]['label'] = \App\Language::translate($activityType, $this->getModuleName());
                    $return[$dateKey]['className'] = 'fc-draggable picklistCBg_Calendar_activitytype_' . $activityType;
                    $return[$dateKey]['borderColor'] = $colors[$record['activitytype']] ?? '';
                    $return[$dateKey]['type'] = 'widget';
                    $return[$dateKey]['activityType'] = $activityType;
                    $return[$dateKey]['url'] = 'index.php?module=' . $this->getModuleName() . '&view=List&entityState=Active';
                }
            }
        }
        $dataReader->close();
        return array_values($return);
    }

    /**
     * Static Function to get the instance of Vtiger Module Model for the given id or name.
     *
     * @param mixed id or name of the module
     */
    public static function getCleanInstance()
    {
        $instance = Vtiger_Cache::get('calendarModels', 'Calendar');
        if (false === $instance) {
            $instance = new self();
            Vtiger_Cache::set('calendarModels', 'Calendar', clone $instance);

            return $instance;
        }
        return clone $instance;
    }

    public static function getCalendarTypes()
    {
        return [
            'PLL_WORKING_TIME',
            'PLL_BREAK_TIME',
            'PLL_HOLIDAY',
        ];
    }

    /** {@inheritdoc} */
    public function getSideBarLinks($linkParams)
    {
        $links = Vtiger_Link_Model::getAllByType($this->getModule()->getId(), ['SIDEBARWIDGET'], $linkParams)['SIDEBARWIDGET'] ?? [];
        $request = \App\Request::init();
        $historyUsers = $request->has('user') ? $request->get('user') : [];
        $links[] = Vtiger_Link_Model::getInstanceFromValues([
            'linktype' => 'SIDEBARWIDGET',
            'linklabel' => 'LBL_USERS',
            'linkclass' => 'js-users-form usersForm ',
            'template' => 'Filters/Users.tpl',
            'filterData' => Vtiger_CalendarRightPanel_Model::getUsersList($this->moduleName),
            'historyUsers' => $historyUsers,
        ]);
        $links[] = Vtiger_Link_Model::getInstanceFromValues([
            'linktype' => 'SIDEBARWIDGET',
            'linklabel' => 'LBL_GROUPS',
            'linkclass' => 'js-group-form groupForm',
            'template' => 'Filters/Groups.tpl',
            'filterData' => Vtiger_CalendarRightPanel_Model::getGroupsList($this->moduleName),
            'historyUsers' => $historyUsers,
        ]);
        return $links;
    }

    /** {@inheritdoc} */
    public function updateEvent(int $recordId, string $start, string $end, App\Request $request): bool
    {
        try {
            $recordModel = Vtiger_Record_Model::getInstanceById($recordId, $this->getModuleName());
            if ($success = $recordModel->isEditable()) {
                $start = DateTimeField::convertToDBTimeZone($start);
                $recordModel->set('date_start', $start->format('Y-m-d'));
                $end = DateTimeField::convertToDBTimeZone($end);
                $recordModel->set('due_date', $end->format('Y-m-d'));
                if ($request->getBoolean('allDay')) {
                    $recordModel->set('allday', 1);
                } else {
                    $recordModel->set('time_start', $start->format('H:i:s'));
                    $recordModel->set('time_end', $end->format('H:i:s'));
                    $recordModel->set('allday', 0);
                }
                $recordModel->save();
                $success = true;
            }
        } catch (Exception $e) {
            \App\Log::error($e->__toString());
            $success = false;
        }
        return $success;
    }
}