Source of file Roster.php
Size: 19,186 Bytes - Last Modified: 2019-03-28T10:10:58+00:00
/var/www/docs.ssmods.com/process/src/code/model/Roster.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543 | <?php /** * Author: danae-miller-clendon * Date: 26/05/15 * Time: 11:22 AM */ /** * Class Roster * * @property string StartDate * @property string EndDate * @property string Holidays * * @method ManyManyList WeeklyRosters * @method ManyManyList StaffLeave * * @TODO: Implement number of days * @TODO: Improve storage efficiency */ class Roster extends DataObject implements PermissionProvider { private static $singular_name = 'Roster'; private static $plural_name = 'Rosters'; private static $description = 'Represents a working week on the roster'; private static $default_sort = 'StartDate DESC'; private static $db = array( 'StartDate' => 'Date', 'EndDate' => 'Date', 'Holidays' => 'Text' ); private static $summary_fields = array( 'StartDate' ); private static $many_many = array( 'WeeklyRosters' => 'JobRole', 'StaffLeave' => 'Member' ); private static $many_many_extraFields = array( 'WeeklyRosters' => array( 'StaffAm0' => 'Varchar(20)', 'StaffPm0' => 'Varchar(20)', 'StaffAm1' => 'Varchar(20)', 'StaffPm1' => 'Varchar(20)', 'StaffAm2' => 'Varchar(20)', 'StaffPm2' => 'Varchar(20)', 'StaffAm3' => 'Varchar(20)', 'StaffPm3' => 'Varchar(20)', 'StaffAm4' => 'Varchar(20)', 'StaffPm4' => 'Varchar(20)', 'StaffAm5' => 'Varchar(20)', 'StaffPm5' => 'Varchar(20)', 'StaffAm6' => 'Varchar(20)', 'StaffPm6' => 'Varchar(20)' ), 'StaffLeave' => array( 'Leave' => 'Text' ) ); /** * Number of days from start date to display in roster. Max 7 * * @var int */ private static $number_of_days = 5; /** * @return FieldList */ public function getCMSFields() { /** ========================================= * Requirements ===========================================*/ Requirements::css('roster/css/rosterAdmin.css'); $fields = parent::getCMSFields(); $endDate = $this->EndDate; $startDate = $this->StartDate; /** ========================================= * Date ==========================================*/ /** @var MultiDateField $holidayField */ $holidayField = MultiDateField::create('Holidays'); $holidayField->setConfig('dateformat', 'dd-MM-yyyy'); $holidayField->setConfig('showcalendar', true); $holidayField->setConfig('separator',', '); $holidayField->setConfig('min', $startDate); $holidayField->setConfig('max', $endDate); /** @var DateField $dateField */ $dateField = DateField::create('StartDate'); $dateField->setConfig('dateformat', 'dd-MM-yyyy'); $fields->addFieldsToTab('Root.Main', array( $dateField, $holidayField )); /** @var $dateField DateField */ $dateField->setConfig('showcalendar', true); /** ========================================= * Staff Roster ===========================================*/ $fields->removeByName(array('WeeklyRosters', 'StaffLeave', 'EndDate')); /** ----------------------------------------- * Variables -------------------------------------------*/ $roles = JobRole::get(); $numberOfDays = Config::inst()->get('Roster', 'number_of_days') ?: 5; /** @var DataList $staffMembers */ $staffMembers = Group::get()->filter(array('Code' => 'staff-members'))->first()->Members(); $staffMap = $staffMembers->count() ? $staffMembers->map('ID', 'Initials')->toArray() : array(); /** ----------------------------------------- * Fields -------------------------------------------*/ if ($roles->count()) { /** ----------------------------------------- * Weekly Rosters -------------------------------------------*/ if ($this->WeeklyRosters()->count()) { $editableColumns = new GridFieldEditableColumns(); $editableColumns->setDisplayFields(array( 'Title' => array( 'title' => 'Role', 'field' => 'ReadonlyField' ), 'StaffAm0' => function($record, $column, $grid) use ($staffMap) { return ListboxField::create($column, 'AM', $staffMap)->setMultiple(true); }, 'StaffPm0' => function($record, $column, $grid) use ($staffMap) { return ListboxField::create($column, 'PM', $staffMap)->setMultiple(true); }, 'StaffAm1' => function($record, $column, $grid) use ($staffMap) { return ListboxField::create($column, 'AM', $staffMap)->setMultiple(true); }, 'StaffPm1' => function($record, $column, $grid) use ($staffMap) { return ListboxField::create($column, 'PM', $staffMap)->setMultiple(true); }, 'StaffAm2' => function($record, $column, $grid) use ($staffMap) { return ListboxField::create($column, 'AM', $staffMap)->setMultiple(true); }, 'StaffPm2' => function($record, $column, $grid) use ($staffMap) { return ListboxField::create($column, 'PM', $staffMap)->setMultiple(true); }, 'StaffAm3' => function($record, $column, $grid) use ($staffMap) { return ListboxField::create($column, 'AM', $staffMap)->setMultiple(true); }, 'StaffPm3' => function($record, $column, $grid) use ($staffMap) { return ListboxField::create($column, 'PM', $staffMap)->setMultiple(true); }, 'StaffAm4' => function($record, $column, $grid) use ($staffMap) { return ListboxField::create($column, 'AM', $staffMap)->setMultiple(true); }, 'StaffPm4' => function($record, $column, $grid) use ($staffMap) { return ListboxField::create($column, 'PM', $staffMap)->setMultiple(true); } )); // Adjust the WeeklyRoster gridfield $grid = GridField::create( 'WeeklyRosters', sprintf('Weekly Roster for %s - %s', $this->dbObject('StartDate')->Format('D jS M'), $this->dbObject('EndDate')->Format('D jS M')), $this->WeeklyRosters(), GridFieldConfig::create() ->addComponent(new GridFieldToolbarHeader()) ->addComponent(new RosterGridFieldTitleHeader($this->dbObject('StartDate'), $this->getHolidayArray())) ->addComponent($editableColumns) )->addExtraClass('roster-gridfield'); $fields->addFieldToTab('Root.Main', $grid); } else { $fields->addFieldToTab('Root.Main', LiteralField::create('', sprintf( '<div class="message notice"><p>%s</p></div>', _t('Roster.SaveFirstNotice', 'Choose a starting date, then press the green "Save" button at the bottom of the screen.') ) )); $this->WeeklyRosters()->addMany($roles); } /** ----------------------------------------- * Staff Leave -------------------------------------------*/ if ($this->StaffLeave()->count()) { $editableColumns = new GridFieldEditableColumns(); $editableColumns->setDisplayFields(array( 'Title' => array( 'title' => 'Staff Member', 'field' => 'ReadonlyField' ), 'Leave' => function($record, $column, $grid) use ($staffMap, $startDate, $endDate) { return MultiDateField::create($column) ->setConfig('dateformat', 'dd-MM-yyyy') ->setConfig('showcalendar', true) ->setConfig('separator',', ') ->setConfig('min', $startDate) ->setConfig('max', $endDate); }, )); $grid = GridField::create( 'StaffLeave', sprintf('Staff Leave for %s - %s', $this->dbObject('StartDate')->Format('D jS M'), $this->dbObject('EndDate')->Format('D jS M')), $this->StaffLeave(), GridFieldConfig::create() ->addComponent(new GridFieldToolbarHeader()) ->addComponent(new GridFieldTitleHeader()) ->addComponent($editableColumns) )->addExtraClass('staff-leave-gridfield'); $fields->addFieldToTab('Root.Main', $grid); } else { $this->StaffLeave()->addMany($staffMembers); } } else { // If no job roles exist, display a warning $fields->addFieldToTab('Root.Main', LiteralField::create('', sprintf( '<div class="message warning"><p>%s</p></div>', _t('Roster.NoRoleWarning', 'Can't create roster; no job roles exist. Add new roles under the "Job Roles" tab.') ) )); } return $fields; } /** * @return string */ public function getTitle() { return sprintf('%s - %s', $this->dbObject('StartDate')->Format('D jS M'), $this->dbObject('EndDate')->Format('D jS M')); } /** * @return Date */ public function calculateEndDate() { $date = new Date(); $date->setValue(date('Y-m-d', strtotime("+4 days", strtotime($this->StartDate)))); return $date; } /** * @return array */ public function getHolidayArray() { return explode(',', $this->Holidays); } /** * Creates default Staff Member group */ public function requireDefaultRecords() { $staffGroup = Group::get()->filter(array('Code' => 'staff-members')); if (!$staffGroup->count()) { /** @var Group $staffGroup */ $staffGroup = Group::create( array( 'Title' => _t('Roster.DefaultGroupTitleStaffMembers', 'Staff Members'), 'Code' => 'staff-members' ) ); $staffGroup->write(); Permission::grant($staffGroup->ID, 'VIEW_ROSTER'); DB::alteration_message(_t('Roster.GroupCreated', 'Staff Members group created'), 'created'); } } /** * @return DataObject */ public static function getCurrentRoster() { return self::getRosterForDate(SS_Datetime::now()->Format('Y-m-d')); } /** * Uses the default sort on Roster to return the most recent one * * @return DataObject */ public static function getLatestRoster() { return DataObject::get_one('Roster'); } /** * Return a roster for a particular date * * @param $date * @return DataObject */ public static function getRosterForDate($date) { $roster = Roster::get()->filter(array( 'StartDate:LessThanOrEqual' => $date, 'EndDate:GreaterThanOrEqual' => $date )); return $roster->first(); } /** * Render with a custom template * * @return HTMLText */ public function forTemplate() { return $this->renderWith('Roster'); } /** * Template helper - Returns the start date, then the rest of the columns' dates * * @return ArrayList */ public function getHeaderItems() { /** @var ArrayList $data */ $data = ArrayList::create(); $data->push(ArrayData::create(array( 'Date' => $this->dbObject('StartDate') ))); for ($i = 0; $i < 5; $i++) { $date = new Date(); $thisDateString = date('d-m-Y', strtotime('+' . $i . ' days', strtotime($this->StartDate))); $date->setValue($thisDateString); $data->push(new ArrayData(array( 'Date' => $date, 'HolidayClass' => $this->getIterationHolidayClass($i), 'ActiveClass' => $this->getIterationActiveClass($i), ))); } return $data; } /** * Roster row display for template * * Don't looks at my Big O notation, senpai * * @return ArrayList */ public function getRows() { $rows = $this->WeeklyRosters(); /** @var ArrayList $data */ $data = ArrayList::create(); /** @var JobRole $role */ foreach ($rows->getIterator() as $role) { /** @var ArrayList $thisRow */ $thisRow = ArrayList::create(); $thisRow->push(ArrayData::create(array( 'Item' => $role->Title ))); for ($i = 0; $i < 5; $i++) { $thisRow->push(ArrayData::create(array( 'Item' => implode(', ', Member::get()->filter(array('ID' => explode(',', $role->{"StaffAm{$i}"})))->Column('FirstName')), 'HolidayClass' => $this->getIterationHolidayClass($i), 'ActiveClass' => $this->getIterationActiveClass($i) ))); $thisRow->push(ArrayData::create(array( 'Item' => implode(', ', Member::get()->filter(array('ID' => explode(',', $role->{"StaffPm{$i}"})))->Column('FirstName')), 'HolidayClass' => $this->getIterationHolidayClass($i), 'ActiveClass' => $this->getIterationActiveClass($i) ))); } $data->push(ArrayData::create(array('Items' => $thisRow))); } $dateArray = array(); // Calculate and add staff leave /** @var Member $member */ foreach ($this->StaffLeave()->getIterator() as $member) { $thisLeave = explode(',', $member->Leave); foreach ($thisLeave as $date) { if (isset($dateArray[$date])) { $dateArray[$date] = array_merge($dateArray[$date], array($member->ID)); } else { $dateArray[$date] = array($member->ID); } } } /** @var ArrayList $leaveRow */ $leaveRow = ArrayList::create(); $leaveRow->push(ArrayData::create(array( 'Item' => 'Staff Leave' ))); for ($i = 0; $i < 5; $i++) { $thisDateString = date('Y-m-d', strtotime('+' . $i . ' days', strtotime($this->StartDate))); if (isset($dateArray[$thisDateString])) { $leaveRow->push(ArrayData::create(array( 'Item' => implode(', ', Member::get()->filter(array('ID' => $dateArray[$thisDateString]))->Column('FirstName')), 'HolidayClass' => $this->getIterationHolidayClass($i), 'ActiveClass' => $this->getIterationActiveClass($i) ))); $leaveRow->push(ArrayData::create(array( 'Item' => implode(', ', Member::get()->filter(array('ID' => $dateArray[$thisDateString]))->Column('FirstName')), 'HolidayClass' => $this->getIterationHolidayClass($i), 'ActiveClass' => $this->getIterationActiveClass($i) ))); } else { $leaveRow->push(ArrayData::create(array( 'Item' => '', 'HolidayClass' => $this->getIterationHolidayClass($i), 'ActiveClass' => $this->getIterationActiveClass($i) ))); $leaveRow->push(ArrayData::create(array( 'Item' => '', 'HolidayClass' => $this->getIterationHolidayClass($i), 'ActiveClass' => $this->getIterationActiveClass($i) ))); } } $data->push(ArrayData::create(array('Items' => $leaveRow))); return $data; } /** * Returns either 'holiday' or '' for use in Template * * @param int $i Iteration of days * @return string */ private function getIterationHolidayClass($i) { $date = new Date(); $thisDateString = date('d-m-Y', strtotime('+' . $i . ' days', strtotime($this->StartDate))); $date->setValue($thisDateString); return (in_array($date->Format('Y-m-d'), $this->getHolidayArray())) ? 'holiday' : ''; } /** * Returns either 'active' or '' for use in Template * * @param int $i Iteration of days * @return string */ private function getIterationActiveClass($i) { $thisDateString = date('d-m-Y', strtotime('+' . $i . ' days', strtotime($this->StartDate))); return (SS_Datetime::now()->Format('d-m-Y') == $thisDateString) ? 'active' : ''; } /** * Set the end date */ public function onBeforeWrite() { parent::onBeforeWrite(); if ($this->isChanged('StartDate') || $this->getField('EndDate') == '') { $this->setField('EndDate', $this->calculateEndDate()); } } /** * @return array */ public function providePermissions() { return array( 'MODIFY_ROSTER' => array( 'category' => _t('Roster.RosterPermissions', 'Roster Permissions'), 'name' => _t('Roster.ModifyRoster', 'Modify roster'), 'help' => _t('Roster.ModifyRosterHelp', 'User can create, edit, and delete rosters.') ), 'VIEW_ROSTER' => array( 'category' => _t('Roster.RosterPermissions', 'Roster Permissions'), 'name' => _t('Roster.ViewRoster', 'View Roster'), 'help' => _t('Roster.ViewRosterHelp', 'User can view the roster') ) ); } public function canCreate($member = null) { return Permission::check('MODIFY_ROSTER', 'any', $member); } public function canEdit($member = null) { return Permission::check('MODIFY_ROSTER', 'any', $member); } public function canDelete($member = null) { return Permission::check('MODIFY_ROSTER', 'any', $member); } public function canView($member = null) { return Permission::check('VIEW_ROSTER', 'any', $member); } } |