From 37be253f324c40fb9230a2d5851a0a04b52b5573 Mon Sep 17 00:00:00 2001 From: Josh Date: Wed, 28 Aug 2024 00:28:12 +0000 Subject: [PATCH] Fix superuser requirement for Award Recommendations (#121), added Modify by and date to kanban Z(#116), new reports for "to be processed" (#104), "To be Scheduled", and "To be GIven" (#105) --- .../src/Controller/EventsController.php | 4 +- .../Controller/RecommendationsController.php | 320 ++++++++++++------ .../Awards/src/Event/CallForNavHandler.php | 73 +++- .../src/Model/Entity/Recommendation.php | 25 ++ .../Awards/src/Model/Table/EventsTable.php | 8 + .../src/Model/Table/RecommendationsTable.php | 5 + .../src/Policy/RecommendationPolicy.php | 26 +- app/plugins/Awards/templates/Events/view.php | 12 +- .../templates/Recommendations/board.php | 9 +- .../templates/Recommendations/index.php | 10 +- .../templates/Recommendations/to_be_given.php | 221 ++++++++++++ .../Recommendations/to_be_processed_board.php | 80 +++++ 12 files changed, 669 insertions(+), 124 deletions(-) create mode 100644 app/plugins/Awards/templates/Recommendations/to_be_given.php create mode 100644 app/plugins/Awards/templates/Recommendations/to_be_processed_board.php diff --git a/app/plugins/Awards/src/Controller/EventsController.php b/app/plugins/Awards/src/Controller/EventsController.php index 32f4fd0f..058aaf2e 100644 --- a/app/plugins/Awards/src/Controller/EventsController.php +++ b/app/plugins/Awards/src/Controller/EventsController.php @@ -51,8 +51,8 @@ public function view($id = null) 'Branches' => function ($q) { return $q->select(['id', 'name']); }, - 'Recommendations' => function ($q) { - return $q->contain(['Awards'])->select(['id', 'member_sca_name', 'award_id', 'specialty', 'call_into_court', 'court_availability', 'status', 'Awards.name'])->orderBy(['member_sca_name' => 'ASC']); + 'RecommendationsToGive' => function ($q) { + return $q->contain(['Awards'])->select(['id', 'event_id', 'member_sca_name', 'award_id', 'specialty', 'call_into_court', 'court_availability', 'status', 'Awards.abbreviation'])->orderBy(['member_sca_name' => 'ASC']); } ]) ->first(); diff --git a/app/plugins/Awards/src/Controller/RecommendationsController.php b/app/plugins/Awards/src/Controller/RecommendationsController.php index 7e074105..501c037a 100644 --- a/app/plugins/Awards/src/Controller/RecommendationsController.php +++ b/app/plugins/Awards/src/Controller/RecommendationsController.php @@ -27,6 +27,24 @@ public function beforeFilter(\Cake\Event\EventInterface $event) } public function index() + { + $filter = []; + $this->runIndexPage("Index", $filter, Recommendation::getStatues()); + } + + public function toBeProcessed() + { + $filter = ["Recommendations.status not IN" => [Recommendation::STATUS_DECLINED, Recommendation::STATUS_NEED_TO_SCHEDULE, Recommendation::STATUS_SCHEDULED, Recommendation::STATUS_GIVEN]]; + $this->runIndexPage("To_Be_Processed", $filter, Recommendation::getToBeProcessedStatues()); + } + + public function toBeScheduled() + { + $filter = ["Recommendations.status not IN" => [Recommendation::STATUS_DECLINED, Recommendation::STATUS_SUBMITTED, Recommendation::STATUS_IN_CONSIDERATION, Recommendation::STATUS_AWAITING_FEEDBACK, Recommendation::STATUS_GIVEN]]; + $this->runIndexPage("To_Be_Scheduled", $filter, Recommendation::getToBeProcessedStatues()); + } + + public function toBeGiven() { $recommendations = $this->Recommendations->find() ->contain([ @@ -43,7 +61,7 @@ public function index() 'Awards.Domains' => function ($q) { return $q->select(['id', 'name']); }, - 'Events' => function ($q) { + 'AssignedEvent' => function ($q) { return $q->select(['id', 'name', 'start_date', 'end_date']); }, 'Notes' => function ($q) { @@ -53,7 +71,6 @@ public function index() return $q->select(['id', 'sca_name']); } ]); - if ($this->request->getQuery("award_id")) { $recommendations->where(["award_id" => $this->request->getQuery("award_id")]); } @@ -75,15 +92,16 @@ public function index() if ($this->request->getQuery("domain_id")) { $recommendations->where(["Awards.domain_id" => $this->request->getQuery("domain_id")]); } - if ($this->request->getQuery("status")) { - $recommendations->where(["Recommendations.status" => $this->request->getQuery("status")]); + if ($this->request->getQuery("event_id")) { + $recommendations->where(["event_id" => $this->request->getQuery("event_id")]); } - $statuses = Recommendation::getStatues(); - $awards = $this->Recommendations->Awards->find('list', limit: 200, keyField: 'id', valueField: 'abbreviation'); - if ($this->request->getQuery("domain_id")) { - $awards->where(["domain_id" => $this->request->getQuery("domain_id")]); - } - $awards = $awards->all(); + $recommendations->where(["Recommendations.status" => Recommendation::STATUS_SCHEDULED]); + $awards = $this->Recommendations->Awards->find( + 'list', + limit: 200, + keyField: 'id', + valueField: 'abbreviation' + )->all(); $domains = $this->Recommendations->Awards->Domains->find('list', limit: 200)->all(); $branches = $this->Recommendations->Branches ->find("treeList", spacer: "--", keyPath: function ($entity) { @@ -100,138 +118,134 @@ public function index() foreach ($courtAvailabilityOptions as $option) { $courtAvailability[$option] = $option; } + $events = $this->Recommendations->Events->find('list', limit: 200) + ->where(["start_date >" => DateTime::now()]) + ->all(); $this->paginate = [ 'sortableFields' => [ 'Branches.name', 'Awards.name', 'Domains.name', 'member_sca_name', - 'created', - 'status', 'call_into_court', 'court_availability', 'requester_sca_name', 'contact_email', - 'contact_phone', 'status_date', + 'Event.start_date', ], ]; - $recommendations = $this->paginate($recommendations); - $this->set(compact('recommendations', 'statuses', 'awards', 'domains', 'branches', 'callIntoCourt', 'courtAvailability')); + if ($this->request->getQuery("csv") == "true") { + $csvData = []; + $csvData[] = ['Name', 'Award', 'Court Availability', 'Call Into Court', 'Event', 'Status']; + $recommendations = $recommendations->toArray(); + foreach ($recommendations as $rec) { + $csvData[] = [ + $rec->member_sca_name, + $rec->award->abbreviation . ($rec->specialty ? " (" . $rec->specialty . ")" : ""), + $rec->court_availability, + $rec->call_into_court, + $rec->assigned_event->name, + $rec->status + ]; + } + $csv = StaticHelpers::arrayToCsv($csvData); + $this->response = $this->response->withType("csv")->withDownload("recommendations.csv")->withStringBody($csv); + return $this->response; + } else { + $recommendations = $this->paginate($recommendations); + $this->set(compact('recommendations', 'awards', 'domains', 'branches', 'callIntoCourt', 'courtAvailability', 'events')); + } } - public function toBeProcessed() + /** + * board view + * + * @return \Cake\Http\Response|null|void Renders view + */ + public function toBeProcessedBoard() { + + $emptyRecommendation = $this->Recommendations->newEmptyEntity(); + $this->Authorization->authorize($emptyRecommendation, 'toBeProcessedBoard'); + $recommendations = $this->Recommendations->find() - ->where(["Recommendations.status not IN" => [Recommendation::STATUS_DECLINED, Recommendation::STATUS_NEED_TO_SCHEDULE, Recommendation::STATUS_SCHEDULED, Recommendation::STATUS_GIVEN]]) - ->contain([ - 'Requesters' => function ($q) { - return $q->select(['id', 'sca_name']); - }, - 'Members', - 'Branches' => function ($q) { - return $q->select(['id', 'name']); - }, - 'Awards' => function ($q) { - return $q->select(['id', 'name']); - }, - 'Awards.Domains' => function ($q) { - return $q->select(['id', 'name']); - }, - 'Events' => function ($q) { - return $q->select(['id', 'name', 'start_date', 'end_date']); - }, - 'Notes' => function ($q) { - return $q->select(['id', 'topic_id', 'subject', 'body', 'created']); - }, - 'Notes.Authors' => function ($q) { - return $q->select(['id', 'sca_name']); - } + ->contain(['Requesters', 'Members', 'Awards'])->orderBy(['Recommendations.status', 'stack_rank']) + ->select([ + 'Recommendations.id', + 'Recommendations.member_sca_name', + 'Recommendations.reason', + 'Recommendations.stack_rank', + 'Recommendations.status', + 'Recommendations.modified', + 'Members.sca_name', + 'Awards.abbreviation', + 'ModifiedByMembers.sca_name' + ]) + ->join([ + 'table' => 'members', + 'alias' => 'ModifiedByMembers', + 'type' => 'LEFT', + 'conditions' => 'Recommendations.modified_by = ModifiedByMembers.id' ]); - - if ($this->request->getQuery("award_id")) { - $recommendations->where(["award_id" => $this->request->getQuery("award_id")]); - } - if ($this->request->getQuery("branch_id")) { - $recommendations->where(["Recommendations.branch_id" => $this->request->getQuery("branch_id")]); - } - if ($this->request->getQuery("for")) { - $recommendations->where(["member_sca_name LIKE" => "%" . $this->request->getQuery("for") . "%"]); - } - if ($this->request->getQuery("call_into_court")) { - $recommendations->where(["call_into_court" => $this->request->getQuery("call_into_court")]); - } - if ($this->request->getQuery("court_avail")) { - $recommendations->where(["court_availability" => $this->request->getQuery("court_avail")]); - } - if ($this->request->getQuery("requester_sca_name")) { - $recommendations->where(["requester_sca_name" => $this->request->getQuery("requester_sca_name")]); - } - if ($this->request->getQuery("domain_id")) { - $recommendations->where(["Awards.domain_id" => $this->request->getQuery("domain_id")]); - } - $statuses = Recommendation::getStatues(); - $awards = $this->Recommendations->Awards->find('list', limit: 200)->all(); - $domains = $this->Recommendations->Awards->Domains->find('list', limit: 200)->all(); - $branches = $this->Recommendations->Branches - ->find("treeList", spacer: "--", keyPath: function ($entity) { - return $entity->id . '|' . ($entity->can_have_members == 1 ? "true" : "false"); - }) - ->orderBy(["name" => "ASC"])->toArray(); - $callIntoCourtOptions = explode(",", StaticHelpers::getAppSetting("Awards.CallIntoCourtOptions", "Never,With Notice,Without Notice")); - $callIntoCourt = []; - foreach ($callIntoCourtOptions as $option) { - $callIntoCourt[$option] = $option; + //if get30DaysDenied is true + if ($this->request->getQuery('includeDeclined') == 'true') { + $recommendations = + $recommendations->where([ + 'OR' => [ + "Recommendations.status not IN" => [Recommendation::STATUS_DECLINED, Recommendation::STATUS_NEED_TO_SCHEDULE, Recommendation::STATUS_SCHEDULED, Recommendation::STATUS_GIVEN], + 'AND' => ['Recommendations.modified >=' => DateTime::now()->subDays(30), 'Recommendations.status' => Recommendation::STATUS_DECLINED] + ] + ]); + } else { + $recommendations = $recommendations->where(["Recommendations.status not IN" => [Recommendation::STATUS_DECLINED, Recommendation::STATUS_NEED_TO_SCHEDULE, Recommendation::STATUS_SCHEDULED, Recommendation::STATUS_GIVEN]]); } - $courtAvailabilityOptions = explode(",", StaticHelpers::getAppSetting("Awards.CourtAvailabilityOptions", "None,Morning,Evening,Any")); - $courtAvailability = []; - foreach ($courtAvailabilityOptions as $option) { - $courtAvailability[$option] = $option; + $recommendations = $recommendations->all(); + $statuses = Recommendation::getToBeProcessedStatues(); + $statuses[Recommendation::STATUS_NEED_TO_SCHEDULE] = "Need to Schedule"; + $statuses[Recommendation::STATUS_DECLINED] = "Declined"; + + $statusNames = $statuses; + + foreach ($recommendations as $recommendation) { + if (!is_array($statuses[$recommendation->status])) { + $statuses[$recommendation->status] = []; + } + $statuses[$recommendation->status][] = $recommendation; } - $this->paginate = [ - 'sortableFields' => [ - 'Branches.name', - 'Awards.name', - 'Domains.name', - 'member_sca_name', - 'created', - 'status', - 'call_into_court', - 'court_availability', - 'requester_sca_name', - 'contact_email', - 'contact_phone', - 'status_date', - ], - ]; - $recommendations = $this->paginate($recommendations); - $this->set(compact('recommendations', 'statuses', 'awards', 'domains', 'branches', 'callIntoCourt', 'courtAvailability')); - $this->render("index"); + $viewAction = "To_Be_Processed"; + $this->set(compact('recommendations', 'statuses', 'viewAction', 'statusNames')); } - /** * board view * * @return \Cake\Http\Response|null|void Renders view */ - public function board() + public function toBeScheduledBoard() { $emptyRecommendation = $this->Recommendations->newEmptyEntity(); - $this->Authorization->authorize($emptyRecommendation, 'board'); + $this->Authorization->authorize($emptyRecommendation, 'toBeScheduledBoard'); $recommendations = $this->Recommendations->find() + ->where(["Recommendations.status not IN" => [Recommendation::STATUS_DECLINED, Recommendation::STATUS_AWAITING_FEEDBACK, Recommendation::STATUS_IN_CONSIDERATION, Recommendation::STATUS_SUBMITTED]]) ->contain(['Requesters', 'Members', 'Branches', 'Awards'])->orderBy(['Recommendations.status', 'stack_rank'])->all(); - $statuses = Recommendation::getStatues(); + $statuses = Recommendation::getToBeScheduledStatues(); + + $statuses[Recommendation::STATUS_GIVEN] = "Given"; + $statusNames = $statuses; + foreach ($recommendations as $recommendation) { if (!is_array($statuses[$recommendation->status])) { $statuses[$recommendation->status] = []; } $statuses[$recommendation->status][] = $recommendation; } - $this->set(compact('recommendations', 'statuses')); + $viewAction = "To_Be_Scheduled"; + $this->set(compact('recommendations', 'statuses', 'viewAction', 'statusNames')); + $this->render('board'); } public function memberSubmissions($id) @@ -582,6 +596,104 @@ public function turboEditForm($id = null) $courtAvailabilityOptions = explode(",", StaticHelpers::getAppSetting("Awards.CourtAvailabilityOptions", "None,Morning,Evening,Any")); $this->set(compact('recommendation', 'branches', 'awards', 'eventList', 'awardsDomains', 'awardsLevels', 'statusList', 'callIntoCourtOptions', 'courtAvailabilityOptions')); } - #endregion -} \ No newline at end of file + + protected function runIndexPage($action, $filterArray, $pageStatuses) + { + $recommendations = $this->Recommendations->find() + ->contain([ + 'Requesters' => function ($q) { + return $q->select(['id', 'sca_name']); + }, + 'Members', + 'Branches' => function ($q) { + return $q->select(['id', 'name']); + }, + 'Awards' => function ($q) { + return $q->select(['id', 'abbreviation']); + }, + 'Awards.Domains' => function ($q) { + return $q->select(['id', 'name']); + }, + 'Events' => function ($q) { + return $q->select(['id', 'name', 'start_date', 'end_date']); + }, + 'Notes' => function ($q) { + return $q->select(['id', 'topic_id', 'subject', 'body', 'created']); + }, + 'Notes.Authors' => function ($q) { + return $q->select(['id', 'sca_name']); + } + ]); + if ($filterArray) { + $recommendations->where($filterArray); + } + if ($this->request->getQuery("award_id")) { + $recommendations->where(["award_id" => $this->request->getQuery("award_id")]); + } + if ($this->request->getQuery("branch_id")) { + $recommendations->where(["Recommendations.branch_id" => $this->request->getQuery("branch_id")]); + } + if ($this->request->getQuery("for")) { + $recommendations->where(["member_sca_name LIKE" => "%" . $this->request->getQuery("for") . "%"]); + } + if ($this->request->getQuery("call_into_court")) { + $recommendations->where(["call_into_court" => $this->request->getQuery("call_into_court")]); + } + if ($this->request->getQuery("court_avail")) { + $recommendations->where(["court_availability" => $this->request->getQuery("court_avail")]); + } + if ($this->request->getQuery("requester_sca_name")) { + $recommendations->where(["requester_sca_name" => $this->request->getQuery("requester_sca_name")]); + } + if ($this->request->getQuery("domain_id")) { + $recommendations->where(["Awards.domain_id" => $this->request->getQuery("domain_id")]); + } + if ($this->request->getQuery("status")) { + $recommendations->where(["Recommendations.status" => $this->request->getQuery("status")]); + } + $statuses = $pageStatuses; + $awards = $this->Recommendations->Awards->find( + 'list', + limit: 200, + keyField: 'id', + valueField: 'abbreviation' + )->all(); + $domains = $this->Recommendations->Awards->Domains->find('list', limit: 200)->all(); + $branches = $this->Recommendations->Branches + ->find("treeList", spacer: "--", keyPath: function ($entity) { + return $entity->id . '|' . ($entity->can_have_members == 1 ? "true" : "false"); + }) + ->orderBy(["name" => "ASC"])->toArray(); + $callIntoCourtOptions = explode(",", StaticHelpers::getAppSetting("Awards.CallIntoCourtOptions", "Never,With Notice,Without Notice")); + $callIntoCourt = []; + foreach ($callIntoCourtOptions as $option) { + $callIntoCourt[$option] = $option; + } + $courtAvailabilityOptions = explode(",", StaticHelpers::getAppSetting("Awards.CourtAvailabilityOptions", "None,Morning,Evening,Any")); + $courtAvailability = []; + foreach ($courtAvailabilityOptions as $option) { + $courtAvailability[$option] = $option; + } + $this->paginate = [ + 'sortableFields' => [ + 'Branches.name', + 'Awards.name', + 'Domains.name', + 'member_sca_name', + 'created', + 'status', + 'call_into_court', + 'court_availability', + 'requester_sca_name', + 'contact_email', + 'contact_phone', + 'status_date', + ], + ]; + $viewAction = $action; + $recommendations = $this->paginate($recommendations); + $this->set(compact('recommendations', 'statuses', 'awards', 'domains', 'branches', 'callIntoCourt', 'courtAvailability', 'viewAction')); + $this->render("index"); + } +} diff --git a/app/plugins/Awards/src/Event/CallForNavHandler.php b/app/plugins/Awards/src/Event/CallForNavHandler.php index 4203401d..0ba1e027 100644 --- a/app/plugins/Awards/src/Event/CallForNavHandler.php +++ b/app/plugins/Awards/src/Event/CallForNavHandler.php @@ -50,13 +50,13 @@ public function callForNav($event) ], [ "type" => "link", - "mergePath" => ["Award Recs."], - "label" => "Kanban Board", - "order" => 30, + "mergePath" => ["Award Recs.", "Recommendations"], + "label" => "To Be Processed Board", + "order" => 1, "url" => [ "controller" => "Recommendations", "plugin" => "Awards", - "action" => "board", + "action" => "toBeProcessedBoard", "model" => "Awards.Recommendations", ], "icon" => "bi-kanban", @@ -64,11 +64,70 @@ public function callForNav($event) "awards/Recommendations/view/*", ] ], + [ + "type" => "link", + "mergePath" => ["Award Recs.", "Recommendations"], + "label" => "To Be Scheduled Board", + "order" => 5, + "url" => [ + "controller" => "Recommendations", + "plugin" => "Awards", + "action" => "toBeScheduledBoard", + "model" => "Awards.Recommendations", + ], + "icon" => "bi-kanban-fill", + "activePaths" => [ + "awards/Recommendations/view/*", + ] + ], + [ + "type" => "link", + "mergePath" => ["Award Recs.", "Recommendations"], + "label" => "To Be Processed List", + "order" => 10, + "url" => [ + "controller" => "Recommendations", + "plugin" => "Awards", + "action" => "ToBeProcessed", + "model" => "Awards.Recommendations", + ], + "icon" => "bi-file-earmark-check", + + + ], + [ + "type" => "link", + "mergePath" => ["Award Recs.", "Recommendations"], + "label" => "To Be Scheduled List", + "order" => 11, + "url" => [ + "controller" => "Recommendations", + "plugin" => "Awards", + "action" => "ToBeScheduled", + "model" => "Awards.Recommendations", + ], + "icon" => "bi-clipboard-heart", + + + ], + [ + "type" => "link", + "mergePath" => ["Award Recs.", "Recommendations"], + "label" => "To Be Given", + "order" => 12, + "url" => [ + "controller" => "Recommendations", + "plugin" => "Awards", + "action" => "ToBeGiven", + "model" => "Awards.Recommendations", + ], + "icon" => "bi-emoji-heart-eyes", + ], [ "type" => "link", "mergePath" => ["Award Recs.", "Recommendations"], "label" => "New Recommendation", - "order" => 0, + "order" => 20, "url" => [ "controller" => "Recommendations", "plugin" => "Awards", @@ -166,7 +225,7 @@ public function callForNav($event) ], [ "type" => "link", - "mergePath" => ["Config"], + "mergePath" => ["Award Recs."], "label" => "Award Events", "order" => 33, "url" => [ @@ -182,7 +241,7 @@ public function callForNav($event) ], [ "type" => "link", - "mergePath" => ["Config", "Award Events"], + "mergePath" => ["Award Recs.", "Award Events"], "label" => "New Award Events", "order" => 0, "url" => [ diff --git a/app/plugins/Awards/src/Model/Entity/Recommendation.php b/app/plugins/Awards/src/Model/Entity/Recommendation.php index c8e30bdd..ffcf3e64 100644 --- a/app/plugins/Awards/src/Model/Entity/Recommendation.php +++ b/app/plugins/Awards/src/Model/Entity/Recommendation.php @@ -52,6 +52,31 @@ public static function getStatues(): array ]; } + public static function getToBeProcessedStatues(): array + { + return [ + self::STATUS_SUBMITTED => "Submitted", + self::STATUS_IN_CONSIDERATION => "In Consideration", + self::STATUS_AWAITING_FEEDBACK => "Awaiting Feedback", + ]; + } + + public static function getToBeScheduledStatues(): array + { + return [ + self::STATUS_NEED_TO_SCHEDULE => "Need to Schedule", + self::STATUS_SCHEDULED => "Scheduled", + ]; + } + + public static function getTerminalStatues(): array + { + return [ + self::STATUS_DECLINED => "Declined", + self::STATUS_GIVEN => "Given", + ]; + } + /** * Fields that can be mass assigned using newEntity() or patchEntity(). * diff --git a/app/plugins/Awards/src/Model/Table/EventsTable.php b/app/plugins/Awards/src/Model/Table/EventsTable.php index fd2ad7ed..0d31f123 100644 --- a/app/plugins/Awards/src/Model/Table/EventsTable.php +++ b/app/plugins/Awards/src/Model/Table/EventsTable.php @@ -52,6 +52,12 @@ public function initialize(array $config): void 'className' => 'Branches', ]); + $this->hasMany('RecommendationsToGive', [ + 'foreignKey' => 'event_id', + 'joinType' => 'LEFT', + 'className' => 'Awards.Recommendations', + ]); + $this->belongsToMany("Recommendations", [ "joinTable" => "awards_recommendations_events", "foreignKey" => "event_id", @@ -59,6 +65,8 @@ public function initialize(array $config): void "className" => "Awards.Recommendations", ]); + + $this->addBehavior("Timestamp"); $this->addBehavior('Muffin/Footprint.Footprint'); $this->addBehavior("Muffin/Trash.Trash"); diff --git a/app/plugins/Awards/src/Model/Table/RecommendationsTable.php b/app/plugins/Awards/src/Model/Table/RecommendationsTable.php index 699a3c9d..4cbfd955 100644 --- a/app/plugins/Awards/src/Model/Table/RecommendationsTable.php +++ b/app/plugins/Awards/src/Model/Table/RecommendationsTable.php @@ -84,6 +84,11 @@ public function initialize(array $config): void "targetForeignKey" => "event_id", "className" => "Awards.Events", ]); + $this->belongsTo("AssignedEvent", [ + 'foreignKey' => 'event_id', + 'joinType' => 'LEFT', + "className" => "Awards.Events", + ]); $this->hasMany("Notes", [ "foreignKey" => "topic_id", "className" => "Notes", diff --git a/app/plugins/Awards/src/Policy/RecommendationPolicy.php b/app/plugins/Awards/src/Policy/RecommendationPolicy.php index 0efa58a2..7bf1fc57 100644 --- a/app/plugins/Awards/src/Policy/RecommendationPolicy.php +++ b/app/plugins/Awards/src/Policy/RecommendationPolicy.php @@ -12,13 +12,35 @@ */ class RecommendationPolicy extends BasePolicy { - protected string $REQUIRED_PERMISSION = "Can Manage Recommendations"; + protected string $REQUIRED_PERMISSION = "Can View Recommendations"; - public function canBoard(IdentityInterface $user, $entity) + public function canToBeProcessedBoard(IdentityInterface $user, $entity) { return $this->_hasNamedPermission($user, $this->REQUIRED_PERMISSION); } + public function canToBeScheduledBoard(IdentityInterface $user, $entity) + { + return $this->_hasNamedPermission($user, $this->REQUIRED_PERMISSION); + } + + + public function canToBeProcessed(IdentityInterface $user, $entity) + { + return $this->_hasNamedPermission($user, $this->REQUIRED_PERMISSION); + } + + public function canToBeScheduled(IdentityInterface $user, $entity) + { + return $this->_hasNamedPermission($user, $this->REQUIRED_PERMISSION); + } + + public function canToBeGiven(IdentityInterface $user, $entity) + { + return $this->_hasNamedPermission($user, $this->REQUIRED_PERMISSION); + } + + public function canAdd(IdentityInterface $user, $entity) { return true; diff --git a/app/plugins/Awards/templates/Events/view.php b/app/plugins/Awards/templates/Events/view.php index e0d40b8e..f9582025 100644 --- a/app/plugins/Awards/templates/Events/view.php +++ b/app/plugins/Awards/templates/Events/view.php @@ -55,13 +55,13 @@ KMP->startBlock("tabContent") ?> -

No Recommendations

+

No Awards Scheduled

KMP->endBlock() ?> diff --git a/app/plugins/Awards/templates/Recommendations/board.php b/app/plugins/Awards/templates/Recommendations/board.php index 96d0105b..3bf9dc78 100644 --- a/app/plugins/Awards/templates/Recommendations/board.php +++ b/app/plugins/Awards/templates/Recommendations/board.php @@ -1,5 +1,7 @@ KMP->endBlock(); ?>

Award Recommendations + + : +

$status) : ?> - + @@ -52,6 +57,8 @@

Text->autoParagraph( h($this->Text->truncate($recommendation->reason, 100)), ) ?>

+ Last Modified: modified->format('m/d/Y') ?> by + ModifiedByMembers['sca_name'] ?>

Award Recommendations + + : +

- Form->create(null, ["url" => ["action" => "index"], "type" => "get", "data-turbo-frame" => "recommendationList", "data-controller" => "filter-grid"]) ?> + Form->create(null, ["url" => ["action" => $viewAction], "type" => "get", "data-turbo-frame" => "recommendationList", "data-controller" => "filter-grid"]) ?> Form->hidden("sort", ["value" => $this->request->getQuery("sort")]) ?> Form->hidden("direction", ["value" => $this->request->getQuery("direction")]) ?>
@@ -169,7 +174,8 @@ - +
contact_email) ?> contact_phone) ?> award->domain->name) ?>award->abbreviation) ?>award->abbreviation) . ($recommendation->specialty ? " (" . $recommendation->specialty . ")" : "") ?> + Text->autoParagraph($recommendation->reason) ?>
    diff --git a/app/plugins/Awards/templates/Recommendations/to_be_given.php b/app/plugins/Awards/templates/Recommendations/to_be_given.php new file mode 100644 index 00000000..a05a38ac --- /dev/null +++ b/app/plugins/Awards/templates/Recommendations/to_be_given.php @@ -0,0 +1,221 @@ +extend("/layout/TwitterBootstrap/dashboard"); + + echo $this->KMP->startBlock("title"); + echo $this->KMP->getAppSetting("KMP.ShortSiteTitle", "KMP") . ': Award Recommendations'; + $this->KMP->endBlock(); +} +$recommendation = []; +?> + +

    + Award Recommendations : To Be Given +

    + + + + request->getRequestTarget(); + //if current url includes ? then append & else append ? + $exportUrl = strpos($currentUrl, "?") ? $currentUrl . "&csv=true" : $currentUrl . "?csv=true"; + ?> +
    + Export +
    + Form->create(null, ["url" => ["action" => "ToBeGiven"], "type" => "get", "data-turbo-frame" => "recommendationList", "data-controller" => "filter-grid"]) ?> + Form->hidden("sort", ["value" => $this->request->getQuery("sort")]) ?> + Form->hidden("direction", ["value" => $this->request->getQuery("direction")]) ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Paginator->sort("created", "Submitted") ?>Paginator->sort("member_sca_name", "For") ?> + Form->control("for", [ + "type" => "text", + "label" => false, + "placeholder" => "For", + "value" => $this->request->getQuery("for"), + "data-action" => "change->filter-grid#submitForm", + ]) ?> + Paginator->sort("Branches.name", "Branch") ?> + Form->control("branch_id", [ + "type" => "select", + "label" => false, + "value" => $this->request->getQuery("branch_id"), + "options" => $branches, + "empty" => true, + "data-action" => "change->filter-grid#submitForm", + ]) ?> + Paginator->sort("call_into_court") ?> + Form->control("call_into_court", [ + "type" => "select", + "label" => false, + "value" => $this->request->getQuery("call_into_court"), + "options" => $callIntoCourt, + "empty" => true, + "data-action" => "change->filter-grid#submitForm", + ]) ?> + Paginator->sort("Court Avail.") ?> + Form->control("court_avail", [ + "type" => "select", + "label" => false, + "value" => $this->request->getQuery("court_avail"), + "options" => $courtAvailability, + "empty" => true, + "data-action" => "change->filter-grid#submitForm", + ]) ?> + Paginator->sort("requester_sca_name", "Submitted By") ?> + Form->control("requester_sca_name", [ + "type" => "text", + "label" => false, + "placeholder" => "Submitted By", + "value" => $this->request->getQuery("requester_sca_name"), + "data-action" => "change->filter-grid#submitForm", + ]) ?> + Paginator->sort("Contact Email") ?>Paginator->sort("Domains.name", "Domain") ?> + Form->control("domain_id", [ + "type" => "select", + "label" => false, + "value" => $this->request->getQuery("domain_id"), + "options" => $domains, + "empty" => true, + "data-action" => "change->filter-grid#submitForm", + ]) ?> + Paginator->sort("Awards.name", "Award") ?> + Form->control("award_id", [ + "type" => "select", + "label" => false, + "placeholder" => "Award", + "value" => $this->request->getQuery("award_id"), + "options" => $awards, + "empty" => true, + "data-action" => "change->filter-grid#submitForm", + ]) ?> + Paginator->sort("Event.start_date", "Events") ?> + Form->control("event_id", [ + "type" => "select", + "label" => false, + "placeholder" => "Events", + "value" => $this->request->getQuery("event_id"), + "options" => $events, + "empty" => true, + "data-action" => "change->filter-grid#submitForm", + ]) ?> + EventsPaginator->sort("Status Date") ?> + Form->button('Filter', ["id" => "filter_btn", "class" => "d-show"]); ?> +
    created) ?>member_id) { + echo $this->Html->link( + h($recommendation->member_sca_name), + ["controller" => "Members", "plugin" => null, "action" => "view", $recommendation->member_id], + ["title" => __("View"), "data-turbo-frame" => "_top"], + ); + } else { + echo h($recommendation->member_sca_name); + } + ?>branch->name) ?>call_into_court) ?>court_availability) ?>requester_id) { + echo $this->Html->link( + h($recommendation->requester_sca_name), + ["controller" => "Members", "plugin" => null, "action" => "view", $recommendation->requester_id], + ["title" => __("View"), "data-turbo-frame" => "_top"], + ); + } else { + echo h($recommendation->requester_sca_name); + } + ?>contact_email) ?>award->domain->name) ?>award->abbreviation) . ($recommendation->specialty ? " (" . $recommendation->specialty . ")" : "") ?> + + Html->link( + h($recommendation->assigned_event->name), + ["controller" => "Events", "action" => "view", $recommendation->assigned_event->id], + ["title" => __("View"), "data-turbo-frame" => "_top"], + ) ?>: +
    assigned_event->start_date->toDateString()) ?> - + assigned_event->end_date->toDateString()) ?> +
    +
      + notes as $note) : ?> +
    • created->toDateTimeString()) ?> : + Text->autoParagraph($note->body) ?>
    • + +
    status_date ? h($recommendation->status_date->toDateString()) : h($recommendation->created->toDateString()) ?> + + + Html->link( + __("View"), + ["action" => "view", $recommendation->id], + ["title" => __("View"), "class" => "btn btn-secondary btn-sm", "data-turbo-frame" => "_top"], + ) ?> +
    + Form->end() ?> +
    +
      + Paginator->first("«", ["label" => __("First")]) ?> + Paginator->prev("‹", [ + "label" => __("Previous"), + ]) ?> + Paginator->numbers() ?> + Paginator->next("›", ["label" => __("Next")]) ?> + Paginator->last("»", ["label" => __("Last")]) ?> +
    +

    Paginator->counter( + __( + "Page {{page}} of {{pages}}, showing {{current}} record(s) out of {{count}} total", + ), + ) ?>

    +
    +
    + +KMP->startBlock("modals"); ?> + +element('recommendationEditModal') ?> + + +KMP->endBlock(); ?> \ No newline at end of file diff --git a/app/plugins/Awards/templates/Recommendations/to_be_processed_board.php b/app/plugins/Awards/templates/Recommendations/to_be_processed_board.php new file mode 100644 index 00000000..568eb9dd --- /dev/null +++ b/app/plugins/Awards/templates/Recommendations/to_be_processed_board.php @@ -0,0 +1,80 @@ + +extend("/layout/TwitterBootstrap/dashboard"); + +echo $this->KMP->startBlock("title"); +echo $this->KMP->getAppSetting("KMP.ShortSiteTitle", "KMP") . ': Award Recommendations'; +$recommendation = []; +$this->KMP->endBlock(); ?> +

    + Award Recommendations + + : + +

    +
    + + + + + $status) : ?> + + + + + + + $status) : ?> + + + +
    + + +
    +
    +
    + Html->link($recommendation->award->abbreviation, ['action' => 'view', $recommendation->id]) ?> + +
    +
    member_sca_name ?> +
    +

    Text->autoParagraph( + h($this->Text->truncate($recommendation->reason, 100)), + ) ?>

    + Last Modified: modified->format('m/d/Y') ?> by + ModifiedByMembers['sca_name'] ?> +
    +
    + +
    +
    +KMP->startBlock("modals"); ?> + +element('recommendationEditModal') ?> + +KMP->endBlock(); ?> \ No newline at end of file