Skip to content
Snippets Groups Projects
Select Git revision
  • 3d8cb20aef2c55cadd38dccc3f51128d7e357ecf
  • main default protected
  • step-3263
  • feature/plugins-cli
  • feature/vite
  • step-2484-peerreview
  • biest/issue-5051
  • tests/simplify-jsonapi-tests
  • fix/typo-in-1a70031
  • feature/broadcasting
  • database-seeders-and-factories
  • feature/peer-review-2
  • feature-feedback-jsonapi
  • feature/peerreview
  • feature/balloon-plus
  • feature/stock-images-unsplash
  • tic-2588
  • 5.0
  • 5.2
  • biest/unlock-blocks
  • biest-1514
21 results

UserProgressOfBlocksShow.php

Blame
  • Forked from Stud.IP / Stud.IP
    Source project has a limited visibility.
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    export.php 19.30 KiB
    <?php
    
    /**
     * requests.php - contains Resources_ExportController
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License as
     * published by the Free Software Foundation; either version 2 of
     * the License, or (at your option) any later version.
     *
     * @author      Moritz Strohm <strohm@data-quest.de>
     * @license     http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
     * @copyright   2017
     * @category    Stud.IP
     * @since       4.1
     */
    
    
    /**
     * Resources_ExportController contains functionality for data export
     * for resources and especially rooms, buildings and locations.
     */
    class Resources_ExportController extends AuthenticatedController
    {
        protected function returnCsvData($data = [], $file_name = '')
        {
            if (!is_array($data)) {
                throw new InvalidArgumentException(
                    'Resources_ExportController::returnCsvData requires an array as parameter!'
                );
            }
            $this->render_csv(
                $data,
                $file_name
            );
        }
    
        protected function returnHtmlData($data = '')
        {
            $this->set_content_type('text/html');
            $this->render_text($data);
        }
    
        public function before_filter(&$action, &$args)
        {
            parent::before_filter($action, $args);
    
            $this->export_type  = Request::get('export_type', 'default');
            $this->export_param = Request::get('export_param', '');
    
            if (Navigation::hasItem('/resources/export')) {
                Navigation::activateItem('/resources/export');
            }
        }
    
        public function select_booking_sources_action($range_with_id = null)
        {
            if (Navigation::hasItem('/resources/export/select_booking_sources')) {
                Navigation::activateItem('/resources/export/select_booking_sources');
            }
            if (
                !ResourceManager::userHasGlobalPermission(User::findCurrent())
                && !ResourceManager::userHasResourcePermissions(User::findCurrent(), 'user')
            ) {
                throw new AccessDeniedException();
            }
    
            $this->available_rooms = [];
            $this->available_clipboards = [];
    
            PageLayout::setTitle(_('Quellen für den Export von Buchungen auswählen'));
    
            $this->weekdays = ['1', '2', '3', '4', '5'];
            $this->select_rooms = Request::get('select_rooms');
    
            if ($this->select_rooms) {
                $this->available_rooms = RoomManager::getUserRooms(
                    User::findCurrent()
                );
                if (!$this->available_rooms) {
                    PageLayout::postInfo(
                        _('Es sind keine Quellen für den Export von Buchungen vorhanden!')
                    );
                }
            } else {
                $this->available_clipboards = Clipboard::getClipboardsForUser(
                    $GLOBALS['user']->id,
                    ['Room']
                );
    
                if(!$this->available_clipboards) {
                    PageLayout::postInfo(
                        _('Sie müssen zunächst Raumgruppen erstellen'),
                        [
                            sprintf(
                                _('Klicken Sie %shier%s, um eine Raumgruppe anzulegen.'),
                                '<a href="' . URLHelper::getLink('dispatch.php/room_management/overview/rooms') . '">',
                                '</a>')
                        ]
                    );
                }
            }
    
    
            $this->begin = new DateTime();
            $this->begin->setDate(
                intval(date('Y')),
                intval(date('m')),
                1
            );
            $this->begin->setTime(0, 0, 0);
            $this->end = clone $this->begin;
            $this->end = $this->end->add(
                new DateInterval('P1M')
            )->sub(
                new DateInterval('P1D')
            );
            $this->end->setTime(23, 59, 59);
    
            $this->range_type = null;
            $this->range_id   = null;
    
            if (!$range_with_id) {
                //Check if range-ID and range_type are provided in an URL parameter:
                $this->range_type = Request::get('range_type');
                $this->range_id   = Request::get('range_id');
            }
    
            // All available booking types.
            $this->booking_types = [
                ResourceBooking::TYPE_NORMAL          => _('Buchung'),
                ResourceBooking::TYPE_RESERVATION     => _('Reservierung'),
                ResourceBooking::TYPE_LOCK            => _('Sperrbuchung'),
                ResourceBooking::TYPE_PLANNED => _('geplante Buchung')
            ];
            $this->selected_booking_types = Request::intArray('bookingtypes') ?:
                Config::get()->RESOURCES_EXPORT_BOOKINGTYPES_DEFAULT;
    
            //Build sidebar
    
            $sidebar = Sidebar::get();
    
            $views = new ViewsWidget();
            $views->addLink(
                _('Raumgruppen auswählen'),
                $this->select_booking_sourcesURL()
            )->setActive(!$this->select_rooms);
            $views->addLink(
                _('Räume auswählen'),
                $this->select_booking_sourcesURL(
                    [
                        'select_rooms' => '1'
                    ]
                )
            )->setActive($this->select_rooms);
            $sidebar->addWidget($views);
        }
    
    
        public function resource_bookings_action($resource_id = null)
        {
            PageLayout::setTitle(
                _('Buchungen exportieren')
            );
    
            if (!$resource_id) {
                PageLayout::postError(
                    _('Es wurde keine Ressource ausgewählt!')
                );
                return;
            }
    
            $this->resource = Resource::find($resource_id);
            if (!$this->resource) {
                PageLayout::postError(
                    _('Die gewählte Ressource wurde nicht gefunden!')
                );
                return;
            }
            $this->resource = $this->resource->getDerivedClassInstance();
    
            PageLayout::setTitle(
                sprintf(
                    '%s: Buchungen exportieren',
                    $this->resource->getFullName()
                )
            );
    
            $this->current_user = User::findCurrent();
    
            if (!$this->resource->userHasPermission($this->current_user, 'user')) {
                throw new AccessDeniedException();
            }
    
            $this->begin = new DateTime();
            $this->end   = clone $this->begin;
    
            $begin_timestamp = Request::get('begin');
            $end_timestamp   = Request::get('end');
            $week_timestamp  = Request::get('timestamp');
            if ($week_timestamp) {
                //Calculate start and end of week:
                $this->begin->setTimestamp($week_timestamp);
                if ($this->begin->format('N') > 1) {
                    $this->begin->sub(
                        new DateInterval('P' . ($this->begin->format('N') - 1) . 'D')
                    );
                }
                $this->begin->setTime(0, 0);
                $this->end = clone $this->begin;
                $this->end = $this->end->add(
                    new DateInterval('P7D')
                )->sub(
                    new DateInterval('PT1S')
                );
            } elseif ($begin_timestamp && $end_timestamp) {
                $this->begin->setTimestamp($begin_timestamp);
                $this->end->setTimestamp($end_timestamp);
            } else {
                $this->begin->setDate(
                    intval(date('Y')),
                    intval(date('m')),
                    1
                );
                $this->begin->setTime(0, 0, 0);
                $this->end = clone $this->begin;
                $this->end = $this->end->add(
                    new DateInterval('P1M')
                )->sub(
                    new DateInterval('P1D')
                );
                $this->end->setTime(23, 59, 59);
            }
    
            $this->weekdays = ['1', '2', '3', '4', '5'];
    
            // All available booking types.
            $this->booking_types = [
                ResourceBooking::TYPE_NORMAL          => _('Buchung'),
                ResourceBooking::TYPE_RESERVATION     => _('Reservierung'),
                ResourceBooking::TYPE_LOCK            => _('Sperrbuchung'),
                ResourceBooking::TYPE_PLANNED => _('geplante Buchung')
            ];
            $this->selected_booking_types = Config::get()->RESOURCES_EXPORT_BOOKINGTYPES_DEFAULT;
        }
    
    
        public function bookings_action()
        {
            CSRFProtection::verifyUnsafeRequest();
    
            //Get the IDs of all selected clipboards and rooms:
            $this->selected_clipboard_ids = Request::getArray('selected_clipboards');
            $this->selected_room_ids      = Request::getArray('selected_rooms');
            $this->selected_resource_ids  = Request::getArray('selected_resources');
    
            //Get begin and end date:
            $this->begin = Request::getDateTime(
                'begin_date',
                'd.m.Y',
                'begin_time',
                'H:i'
            );
            $this->end   = Request::getDateTime(
                'end_date',
                'd.m.Y',
                'end_time',
                'H:i'
            );
    
            //Get the selected weekdays:
            $this->weekdays = Request::getArray('weekdays');
    
            if ($this->begin >= $this->end) {
                PageLayout::postError(
                    _('Der Startzeitpunkt darf nicht hinter dem Endzeitpunkt liegen!')
                );
                $this->redirect(Request::get('from'));
                return;
            }
            if (!$this->weekdays) {
                PageLayout::postError(
                    _('Bitte mindestens einen Wochentag auswählen.')
                );
                $this->redirect(Request::get('from'));
                return;
            }
    
            //Resolve the IDs to clipboards (or rooms) and build a list of rooms.
    
            $this->selected_clipboards = Clipboard::findMany(
                $this->selected_clipboard_ids
            );
            $room_sql                  = "INNER JOIN resource_categories rc
                ON resources.category_id = rc.id
                WHERE
                rc.class_name IN ( :room_class_names )
                AND resources.id IN ( :room_ids )
                ORDER BY resources.name ASC";
            $this->selected_rooms      = Room::findBySql(
                $room_sql,
                [
                    'room_ids' => $this->selected_room_ids,
                    'room_class_names' => RoomManager::getAllRoomClassNames()
                ]
            );
            $this->selected_resources  = Resource::findMany(
                $this->selected_resource_ids
            );
    
            $resources = [];
            foreach ($this->selected_clipboards as $clipboard) {
                $clipboard_room_ids = $clipboard->getAllRangeIds('Room');
                $clipboard_rooms    = Room::findBySql(
                    $room_sql,
                    [
                        'room_ids' => $clipboard_room_ids,
                        'room_class_names' => RoomManager::getAllRoomClassNames()
                    ]
                );
                $resources          = array_merge($resources, $clipboard_rooms);
            }
    
            $resources = array_merge($resources, $this->selected_rooms, $this->selected_resources);
    
            //Collect all bookings in the selected time range and export them.
    
            $booking_data = [
                [
                    _('Beginn'),
                    _('Ende'),
                    _('Rüstzeit'),
                    _('Raumname'),
                    _('Buchungstyp'),
                    _('Beschreibung'),
                    _('Buchende Person'),
                    _('Belegende Person(en)'),
                    _('Interner Kommentar')
                ]
            ];
    
            foreach ($resources as $resource) {
                //Retrieve the bookings in the specified time range:
                $intervals = ResourceBookingInterval::findBySql(
                    "`takes_place` = 1 AND `resource_id` = :resource_id AND `begin` < :end AND `end` > :begin
                     ORDER BY `begin`, `end`",
                    [
                        'resource_id' => $resource->id,
                        'begin' => $this->begin->getTimestamp(),
                        'end'   => $this->end->getTimestamp()
                    ]
                );
    
                $types = Request::intArray('bookingtypes') ?:
                    Config::get()->RESOURCES_EXPORT_BOOKINGTYPES_DEFAULT;
    
                //Prepare data for export:
    
                foreach ($intervals as $interval) {
                    //Check the weekday of the interval first to avoid any other computation
                    //if the weekday is not one of the selected weekdays.
                    if (date('Ymd', $interval->begin) !== date('Ymd', $interval->end)) {
                        //The interval spans over multiple days. So the computation for the weekdays must
                        //take that into account.
                        $current_day = new DateTime();
                        $current_day->setTimestamp($interval->begin);
                        $current_day->setTime(0,0,0);
                        $end = new DateTime();
                        $end->setTimestamp($interval->end);
                        $interval_is_on_weekday = false;
                        while ($current_day <= $end && !$interval_is_on_weekday) {
                            $interval_is_on_weekday = in_array($current_day->format('N'), $this->weekdays);
                            $current_day = $current_day->add(new DateInterval('P1D'));
                        }
                        if (!$interval_is_on_weekday) {
                            //The interval does not take place on one of the weekdays that have been selected.
                            continue;
                        }
                    } else {
                        //The interval lies on one day.
                        $interval_weekday = date('N', $interval->begin);
                        if (!in_array($interval_weekday, $this->weekdays)) {
                            //The interval is not on one of the selected weekdays.
                            continue;
                        }
                    }
                    $booking = $interval->booking;
                    if (!$booking instanceof ResourceBooking || !in_array($booking->booking_type, $types)) {
                        continue;
                    }
                    $description = $booking->description;
                    if (!$booking->isSimpleBooking()) {
                        $course = $booking->assigned_course_date->course;
                        if ($course instanceof Course) {
                            $description = $course->getFullName();
                        }
                    }
                    $booking_data[] = [
                        date('d.m.Y H:i', ($interval->begin + $booking->preparation_time)),
                        date('d.m.Y H:i', $interval->end),
                        sprintf(
                            _('%u min.'),
                            intval($booking->preparation_time / 60)
                        ),
                        $booking->resource->name,
                        (
                        $booking->booking_type == ResourceBooking::TYPE_NORMAL
                            ? _('Buchung')
                            : (
                        $booking->booking_type == ResourceBooking::TYPE_RESERVATION
                            ? _('Reservierung')
                            : (
                        $booking->booking_type == ResourceBooking::TYPE_LOCK
                            ? _('Sperrbuchung')
                            : _('sonstiges')
                        )
                        )
                        ),
                        $description,
                        $booking->booking_user ? $booking->booking_user->getFullName() : '',
                        implode(', ', $booking->getAssignedUsers()),
                        $booking->internal_comment
                    ];
                }
            }
    
            $this->returnCsvData(
                $booking_data,
                sprintf(
                    '%1$s_%2$s - %3$s-%4$s.csv',
                    date('Ymd', time()),
                    _('Buchungsliste'),
                    $this->begin->format('Ymd_Hi'),
                    $this->end->format('Ymd_Hi')
                )
            );
        }
    
    
        public function booking_plan_action($resource_id = null)
        {
            $this->resource = Resource::find($resource_id);
            if (!$this->resource) {
                PageLayout::postError(
                    _('Die angegebene Ressource wurde nicht gefunden!')
                );
                return;
            }
            $this->resource = $this->resource->getDerivedClassInstance();
    
            $user_has_user_permissions = $this->resource->userHasPermission(
                User::findCurrent(),
                'user'
            );
            if (!$user_has_user_permissions) {
                throw new AccessDeniedException();
            }
    
            $week_timestamp = Request::get('timestamp', time());
    
            $this->date = new DateTime();
            $this->date->setTimestamp($week_timestamp);
    
            $week_begin = clone $this->date;
            $week_begin->sub(
                new DateInterval('P' . abs($this->date->format('N') - 1) . 'D')
            );
            $week_begin->setTime(0, 0, 0);
    
            $week_end = clone $week_begin;
            $week_end->add(new DateInterval('P7D'))->sub(new DateInterval('PT1S'));
    
            if ($this->export_type == 'csv') {
                $csv_data = [];
    
                $csv_data[] = [
                    _('Beginn'),
                    _('Ende'),
                    _('Rüstzeit (Minuten)'),
                    (
                    $this->resource instanceof Room
                        ? _('Raum / Gebäude')
                        : _('Ressource')
                    ),
                    _('Buchungstyp'),
                    _('Beschreibung'),
                    _('Buchende Person'),
                    _('Belegende Person(en)'),
                    _('Interner Kommentar')
                ];
    
                //Get booking intervals:
                if ($this->resource instanceof Room) {
                    $intervals = RoomManager::getBookingIntervalsForRoom(
                        $this->resource,
                        $week_begin,
                        $week_end,
                        [0, 2],
                        [0, 2]
                    );
                } else {
                    $intervals = $this->resource->getResourceBookings(
                        $week_begin,
                        $week_end,
                        [0, 2]
                    );
                }
    
                foreach ($intervals as $interval) {
                    $resource_name = '';
                    if ($interval->resource) {
                        $interval_resource = $interval->resource->getDerivedClassInstance();
                        $resource_name     = $interval_resource->getFullName();
                    }
    
                    $booking_type_string = '';
                    if ($interval->booking->booking_type == ResourceBooking::TYPE_NORMAL) {
                        $booking_type_string = _('Buchung');
                    } elseif ($interval->booking->booking_type == ResourceBooking::TYPE_RESERVATION) {
                        $booking_type_string = _('Reservierung');
                    } elseif ($interval->booking->booking_type == ResourceBooking::TYPE_LOCK) {
                        $booking_type_string = _('Sperrbuchung');
                    }
    
                    $csv_data[] = [
                        date('d.m.Y H:i', $interval->begin),
                        date('d.m.Y H:i', $interval->end),
                        round($interval->booking->preparation_time / 60),
                        $resource_name,
                        $booking_type_string,
                        $interval->booking->description,
                        (
                        $interval->booking->booking_user instanceof User
                            ? $interval->booking->booking_user->getFullName()
                            : ''
                        ),
                        $interval->booking->getAssignedUserName(),
                        $interval->booking->internal_comment
                    ];
                }
    
                $file_name = sprintf(
                    _('Belegungsplan %1$s, KW %2$d.csv'),
                    $this->resource->getFullName(),
                    $this->date->format('W')
                );
                $this->returnCsvData($csv_data, $file_name);
            } else {
                $this->render_nothing();
            }
        }
    }