From 167c8a8281fb6451058d6625867aa162696c48db Mon Sep 17 00:00:00 2001 From: kylemcshea Date: Wed, 10 Jul 2024 17:12:03 -0400 Subject: [PATCH 01/22] feat: ability for zapier to poll by comments --- app/Domain/Comments/Repositories/Comments.php | 21 +++++++++++++++++++ app/Domain/Comments/Services/Comments.php | 5 ++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/app/Domain/Comments/Repositories/Comments.php b/app/Domain/Comments/Repositories/Comments.php index c4f868740..7d9d65b2d 100644 --- a/app/Domain/Comments/Repositories/Comments.php +++ b/app/Domain/Comments/Repositories/Comments.php @@ -261,5 +261,26 @@ public function editComment($text, $id): bool $stmn->closeCursor(); return $result; } + + public function getAllAccountComments(): array|false + { + $sql = "SELECT comment.id, + comment.module, + comment.text, + comment.date, + comment.moduleId, + comment.userId, + comment.commentParent, + comment.status + FROM zp_comment as comment"; + + $stmn = $this->db->database->prepare($sql); + + $stmn->execute(); + $values = $stmn->fetchAll(); + $stmn->closeCursor(); + + return $values; + } } } diff --git a/app/Domain/Comments/Services/Comments.php b/app/Domain/Comments/Services/Comments.php index b62ef433a..bee0836a7 100644 --- a/app/Domain/Comments/Services/Comments.php +++ b/app/Domain/Comments/Services/Comments.php @@ -139,6 +139,9 @@ public function deleteComment($commentId): bool return $this->commentRepository->deleteComment($commentId); } + public function pollComments(): array | false + { + return $this->commentRepository->getAllAccountComments(); + } } - } From 75218328e32d30093baa2d76088510125c72103a Mon Sep 17 00:00:00 2001 From: kylemcshea Date: Wed, 10 Jul 2024 17:12:29 -0400 Subject: [PATCH 02/22] feat: ability for zapier to poll by goals and check for updated goals --- .../Goalcanvas/Repositories/Goalcanvas.php | 65 +++++++++++++++++-- app/Domain/Goalcanvas/Services/Goalcanvas.php | 24 +++++-- 2 files changed, 81 insertions(+), 8 deletions(-) diff --git a/app/Domain/Goalcanvas/Repositories/Goalcanvas.php b/app/Domain/Goalcanvas/Repositories/Goalcanvas.php index 14403236b..3a5d839d0 100644 --- a/app/Domain/Goalcanvas/Repositories/Goalcanvas.php +++ b/app/Domain/Goalcanvas/Repositories/Goalcanvas.php @@ -61,11 +61,11 @@ class Goalcanvas extends Canvas * @var array */ protected array $dataLabels = [ - 1 => ['title' => 'label.what_are_you_measuring', 'field' => 'assumptions', 'type' => 'string', 'active' => true], - 2 => ['title' => 'label.current_value', 'field' => 'data', 'type' => 'int', 'active' => true], - 3 => ['title' => 'label.goal_value', 'field' => 'conclusion', 'type' => 'int', 'active' => true], + 1 => ['title' => 'label.what_are_you_measuring', 'field' => 'assumptions', 'type' => 'string', 'active' => true], + 2 => ['title' => 'label.current_value', 'field' => 'data', 'type' => 'int', 'active' => true], + 3 => ['title' => 'label.goal_value', 'field' => 'conclusion', 'type' => 'int', 'active' => true], - ]; + ]; /** @@ -159,5 +159,62 @@ public function getSingleCanvas($canvasId): false|array return $values; } + + /** + * Gets all goals related to a milestone + * + * @return array|false + */ + public function getAllAccountGoals(): false|array + { + $sql = "SELECT + zp_canvas_items.id, + zp_canvas_items.description, + zp_canvas_items.title, + zp_canvas_items.assumptions, + zp_canvas_items.data, + zp_canvas_items.conclusion, + zp_canvas_items.box, + zp_canvas_items.author, + zp_canvas_items.created, + zp_canvas_items.modified, + zp_canvas_items.canvasId, + zp_canvas_items.sortindex, + zp_canvas_items.status, + zp_canvas_items.relates, + zp_canvas_items.milestoneId, + zp_canvas_items.kpi, + zp_canvas_items.data1, + zp_canvas_items.data2, + zp_canvas_items.data3, + zp_canvas_items.data4, + zp_canvas_items.data5, + zp_canvas_items.startDate, + zp_canvas_items.endDate, + zp_canvas_items.setting, + zp_canvas_items.metricType, + zp_canvas_items.startValue, + zp_canvas_items.currentValue, + zp_canvas_items.endValue, + zp_canvas_items.impact, + zp_canvas_items.effort, + zp_canvas_items.probability, + zp_canvas_items.action, + zp_canvas_items.assignedTo, + zp_canvas_items.parent, + zp_canvas_items.tags + FROM + zp_canvas_items + + WHERE zp_canvas_items.box = 'goal' + + "; + + $stmn = $this->db->database->prepare($sql); + $stmn->execute(); + $values = $stmn->fetchAll(); + $stmn->closeCursor(); + return $values; + } } } diff --git a/app/Domain/Goalcanvas/Services/Goalcanvas.php b/app/Domain/Goalcanvas/Services/Goalcanvas.php index 4da3c9396..8a274c7bb 100644 --- a/app/Domain/Goalcanvas/Services/Goalcanvas.php +++ b/app/Domain/Goalcanvas/Services/Goalcanvas.php @@ -172,19 +172,35 @@ public function getGoalsByMilestone($milestoneId): array return $goals; } - public function updateGoalboard($values) { + public function updateGoalboard($values) + { return $this->goalRepository->updateCanvas($values); } - public function createGoalboard($values) { + public function createGoalboard($values) + { return $this->goalRepository->addCanvas($values); } - public function getSingleCanvas($id) { + public function getSingleCanvas($id) + { return $this->goalRepository->getSingleCanvas($id); } + public function pollGoals() + { + return $this->goalRepository->getAllAccountGoals(); + } - } + public function pollForUpdatedGoals(): array|false + { + $goals = $this->goalRepository->getAllAccountGoals(); + + foreach ($goals as $key => $goal) { + $goals[$key]['id'] = $goal['id'] . '-' . $goal['modified']; + } + return $goals; + } + } } From bdaf7838912af49d7bc4e0522136ebd918fb7698 Mon Sep 17 00:00:00 2001 From: kylemcshea Date: Wed, 10 Jul 2024 17:12:50 -0400 Subject: [PATCH 03/22] feat: ability for zapier to poll by new ideas and updated ideas --- app/Domain/Ideas/Repositories/Ideas.php | 35 +++++++++++++++++++++++++ app/Domain/Ideas/Services/Ideas.php | 32 ++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 app/Domain/Ideas/Services/Ideas.php diff --git a/app/Domain/Ideas/Repositories/Ideas.php b/app/Domain/Ideas/Repositories/Ideas.php index c75b969ea..b06e5255f 100644 --- a/app/Domain/Ideas/Repositories/Ideas.php +++ b/app/Domain/Ideas/Repositories/Ideas.php @@ -626,5 +626,40 @@ public function bulkUpdateIdeaStatus($params): bool return true; } + + /** + * @return array|false + */ + public function getAllIdeas(): array|false + { + + // TODO: make this not select * and identify what fields we want back. + + $sql = "SELECT zp_canvas_items.id, + zp_canvas_items.description, + zp_canvas_items.assumptions, + zp_canvas_items.data, + zp_canvas_items.conclusion, + zp_canvas_items.box, + zp_canvas_items.author, + zp_canvas_items.created, + zp_canvas_items.modified, + zp_canvas_items.canvasId, + zp_canvas_items.sortindex, + zp_canvas_items.status, + zp_canvas_items.tags, + zp_canvas_items.milestoneId + FROM zp_canvas_items + LEFT JOIN zp_canvas AS canvasBoard ON zp_canvas_items.canvasId = canvasBoard.id + WHERE canvasBoard.type = 'idea'"; + + $stmn = $this->db->database->prepare($sql); + + $stmn->execute(); + $values = $stmn->fetchAll(PDO::FETCH_ASSOC); + $stmn->closeCursor(); + + return $values; + } } } diff --git a/app/Domain/Ideas/Services/Ideas.php b/app/Domain/Ideas/Services/Ideas.php new file mode 100644 index 000000000..0707adfe2 --- /dev/null +++ b/app/Domain/Ideas/Services/Ideas.php @@ -0,0 +1,32 @@ +ideasRepository = $ideasRepository; + } + + public function pollIdeas(): array + { + return $this->ideasRepository->getAllIdeas(); + } + + public function pollForUpdatedIdeas(): array + { + $ideas = $this->ideasRepository->getAllIdeas(); + + foreach ($ideas as $key => $idea) { + $ideas[$key]['id'] = $idea['id'] . '-' . $idea['modified']; + } + + return $ideas; + } + } +} From 5cddaca89e7d47af19b0388c6c81bfa23b06b9b9 Mon Sep 17 00:00:00 2001 From: kylemcshea Date: Wed, 10 Jul 2024 17:13:21 -0400 Subject: [PATCH 04/22] feat: ability for zapier to poll by updated projects --- app/Domain/Projects/Services/Projects.php | 48 +++++++++++++++-------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/app/Domain/Projects/Services/Projects.php b/app/Domain/Projects/Services/Projects.php index fabd8fe75..a158f61bf 100644 --- a/app/Domain/Projects/Services/Projects.php +++ b/app/Domain/Projects/Services/Projects.php @@ -180,7 +180,7 @@ public function getProjectProgress($projectId): array } - $returnValue = array("percent" => $finalPercent, "estimatedCompletionDate" => $completionDate , "plannedCompletionDate" => ''); + $returnValue = array("percent" => $finalPercent, "estimatedCompletionDate" => $completionDate, "plannedCompletionDate" => ''); if ($numberOfClosedTickets < 10) { $returnValue['estimatedCompletionDate'] = " Complete more To-Dos to see that!"; } elseif ($finalPercent == 100) { @@ -614,7 +614,7 @@ public function setCurrentProject(): void //If last project setting is set use that $lastProject = $this->settingsRepo->getSetting("usersettings." . session("userdata.id") . ".lastProject"); if ( - ! empty($lastProject) + !empty($lastProject) && $this->changeCurrentSessionProject($lastProject) ) { return; @@ -1053,26 +1053,26 @@ public function duplicateProject(int $projectId, int $clientId, string $projectN //Ideas $this->duplicateCanvas( - repository:IdeaRepository::class, + repository: IdeaRepository::class, originalProjectId: $projectId, newProjectId: $newProjectId ); $this->duplicateCanvas( - repository:GoalcanvaRepository::class, + repository: GoalcanvaRepository::class, originalProjectId: $projectId, newProjectId: $newProjectId ); $this->duplicateCanvas( - repository:Wiki::class, + repository: Wiki::class, originalProjectId: $projectId, newProjectId: $newProjectId, canvasTypeName: "wiki" ); $this->duplicateCanvas( - repository:LeancanvaRepository::class, + repository: LeancanvaRepository::class, originalProjectId: $projectId, newProjectId: $newProjectId ); @@ -1241,19 +1241,19 @@ public function getProjectSetupChecklist($projectId): array "status" => "", "link" => BASE_URL . "/projects/showProject/" . session("currentProject") . "", "description" => "checklist.define.tasks.description", - ), + ), "defineTeam" => array( "title" => "label.defineTeam", "status" => "", "link" => BASE_URL . "/projects/showProject/" . session("currentProject") . "#team", "description" => "checklist.define.tasks.defineTeam", - ), + ), "createBlueprint" => array( "title" => "label.createBlueprint", "status" => "", "link" => BASE_URL . "/strategy/showBoards/", "description" => "checklist.define.tasks.createBlueprint", - ), + ), ), "status" => '', ), @@ -1266,7 +1266,7 @@ public function getProjectSetupChecklist($projectId): array "status" => "", "link" => BASE_URL . "/goalcanvas/dashboard", "description" => "checklist.goals.tasks.setGoals", - ), + ), ), "status" => '', ), @@ -1279,7 +1279,7 @@ public function getProjectSetupChecklist($projectId): array "status" => "", "link" => BASE_URL . "/tickets/roadmap", "description" => "checklist.timeline.tasks.createMilestones", - ), + ), ), "status" => '', @@ -1292,13 +1292,13 @@ public function getProjectSetupChecklist($projectId): array "title" => "label.createTasks", "status" => "", "link" => BASE_URL . "/tickets/showAll", "description" => "checklist.implementation.tasks.createTasks ", - ), + ), "finish80percent" => array( "title" => "label.finish80percent", "status" => "", "link" => BASE_URL . "/reports/show", "description" => "checklist.implementation.tasks.finish80percent", - ), + ), ), "status" => '', ), @@ -1344,7 +1344,7 @@ public function getProjectSetupChecklist($projectId): array } //Add overrides - if (! $stepsCompleted = $this->settingsRepo->getSetting("projectsettings.$projectId.stepsComplete")) { + if (!$stepsCompleted = $this->settingsRepo->getSetting("projectsettings.$projectId.stepsComplete")) { $stepsCompleted = []; } else { $stepsCompleted = unserialize($stepsCompleted); @@ -1390,7 +1390,7 @@ public function getProjectSetupChecklist($projectId): array // otherwise, set the step as completed $progressSteps[$name]['status'] = 'done'; if ( - ! in_array($previousValue['stepType'] ?? null, ['current', '']) + !in_array($previousValue['stepType'] ?? null, ['current', '']) || $name == array_key_first($progressSteps) ) { $progressSteps[$name]['stepType'] = 'complete'; @@ -1443,7 +1443,8 @@ public function updateProjectProgress($stepsComplete, $projectId): void * @param array $projects An array of project IDs to be assigned to the user. * @return bool Returns true if the project relations were successfully edited, false otherwise. */ - public function editUserProjectRelations($id, $projects): bool { + public function editUserProjectRelations($id, $projects): bool + { return $this->projectRepository->editUserProjectRelations($id, $projects); } @@ -1559,6 +1560,19 @@ public function getAll(bool $showClosedProjects = false): array { return $this->projectRepository->getAll($showClosedProjects); } - } + /** + * @return array + */ + public function pollForUpdatedProjects(): array + { + $projects = $this->projectRepository->getAll(false); + + foreach ($projects as $key => $project) { + $projects[$key]['id'] = $project['id'] . '-' . $project['modified']; + } + + return $projects; + } + } } From 4329be5ea01709fd730e99d536862e389a4a89bc Mon Sep 17 00:00:00 2001 From: kylemcshea Date: Wed, 10 Jul 2024 17:13:49 -0400 Subject: [PATCH 05/22] fix: ensure date attribute in tickets table gets updated when updating ticket --- app/Domain/Tickets/Repositories/Tickets.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Domain/Tickets/Repositories/Tickets.php b/app/Domain/Tickets/Repositories/Tickets.php index 3e39f729a..1907e4f37 100644 --- a/app/Domain/Tickets/Repositories/Tickets.php +++ b/app/Domain/Tickets/Repositories/Tickets.php @@ -693,7 +693,6 @@ public function simpleTicketQuery(?int $userId, ?int $projectId): array|false $stmn->closeCursor(); return $values; - } public function getScheduledTasks(CarbonImmutable $dateFrom, CarbonImmutable $dateTo, ?int $userId = null) @@ -1792,6 +1791,7 @@ public function updateTicket(array $values, $id): bool description=:description, projectId=:projectId, status = :status, + date = :date, dateToFinish = :dateToFinish, sprint = :sprint, storypoints = :storypoints, @@ -1814,6 +1814,7 @@ public function updateTicket(array $values, $id): bool $stmn->bindValue(':description', $values['description'], PDO::PARAM_STR); $stmn->bindValue(':projectId', $values['projectId'], PDO::PARAM_STR); $stmn->bindValue(':status', $values['status'], PDO::PARAM_STR); + $stmn->bindValue(':date', $values['date'], PDO::PARAM_STR); $stmn->bindValue(':dateToFinish', $values['dateToFinish'], PDO::PARAM_STR); $stmn->bindValue(':sprint', $values['sprint'], PDO::PARAM_STR); $stmn->bindValue(':storypoints', $values['storypoints'], PDO::PARAM_STR); @@ -2064,5 +2065,4 @@ public function delMilestone($id): bool return true; } } - } From 940175a7a4cc8bb6d00726125d9361657dd60de0 Mon Sep 17 00:00:00 2001 From: kylemcshea Date: Wed, 10 Jul 2024 17:14:32 -0400 Subject: [PATCH 06/22] feat: ability for zapier to poll by new milestones and updated milestones --- app/Domain/Tickets/Services/Tickets.php | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/app/Domain/Tickets/Services/Tickets.php b/app/Domain/Tickets/Services/Tickets.php index 469979abc..1a7a81cfa 100644 --- a/app/Domain/Tickets/Services/Tickets.php +++ b/app/Domain/Tickets/Services/Tickets.php @@ -2059,6 +2059,28 @@ public function prepareTicketDates(&$values) return $values; } - } + public function pollForNewAccountMilestones(): array | false + { + return $this->ticketRepository->getAllBySearchCriteria( + ["type" => "milestone"], + 'date' + ); + } + + // since the date attribute of milestones gets updated when the milestone is updated we need to poll for updated milestones + // using that date attribute + public function pollForUpdatedAccountMilestones(): array|false + { + $milestones = $this->ticketRepository->getAllBySearchCriteria( + ["type" => "milestone"], + 'date' + ); + + foreach ($milestones as $key => $milestone) { + $milestones[$key]['id'] = $milestone['id'] . '-' . $milestone['date']; + } + + return $milestones; + } } From 63dca5610226224638b79ff5eb5297f4e5e9f761 Mon Sep 17 00:00:00 2001 From: kylemcshea Date: Wed, 10 Jul 2024 17:15:04 -0400 Subject: [PATCH 07/22] feat: ability for zapier to poll by new todo's and updated todo's --- app/Domain/Tickets/Services/Tickets.php | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/app/Domain/Tickets/Services/Tickets.php b/app/Domain/Tickets/Services/Tickets.php index 1a7a81cfa..fbf712cf4 100644 --- a/app/Domain/Tickets/Services/Tickets.php +++ b/app/Domain/Tickets/Services/Tickets.php @@ -2083,4 +2083,29 @@ public function pollForUpdatedAccountMilestones(): array|false return $milestones; } + + // TODO: update this to be todo and update zapier as well + public function pollForNewAccountTickets(): array|false + { + return $this->ticketRepository->getAllBySearchCriteria( + ["excludeType" => "milestone"], + 'date' + ); + } + + // Since the date attribute of todos gets updated when the todo is updated we need to poll for updated todos + // using that date attribute + public function pollForUpdatedAccountTodos(): array|false + { + $todos = $this->ticketRepository->getAllBySearchCriteria( + ["excludeType" => "milestone"], + 'date' + ); + + foreach ($todos as $key => $todo) { + $todos[$key]['id'] = $todo['id'] . '-' . $todo['date']; + } + + return $todos; + } } From 676461fc3e84262573b1fedb9549cd31c9d41bd1 Mon Sep 17 00:00:00 2001 From: kylemcshea Date: Wed, 10 Jul 2024 17:18:03 -0400 Subject: [PATCH 08/22] feat: zapier actions to 1 - create todo 2 - create milestone 3 - update todo --- app/Domain/Tickets/Services/Tickets.php | 122 ++++++++++++++++++++++-- 1 file changed, 114 insertions(+), 8 deletions(-) diff --git a/app/Domain/Tickets/Services/Tickets.php b/app/Domain/Tickets/Services/Tickets.php index fbf712cf4..0ae0e29b3 100644 --- a/app/Domain/Tickets/Services/Tickets.php +++ b/app/Domain/Tickets/Services/Tickets.php @@ -399,8 +399,8 @@ public function simpleTicketCounter(?int $userId = null, ?int $project = null, s $projectStatusLabels[$ticket['projectId']][$ticket['status']]["statusType"] !== "DONE" ) ) { - $ticketCounter++; - continue; + $ticketCounter++; + continue; } if ( @@ -590,7 +590,7 @@ public function getAllGrouped($searchCriteria): array case "priority": case "storypoints": $ticketGroups = array_sort($ticketGroups, 'id'); - // no break + // no break default: $ticketGroups = array_sort($ticketGroups, 'label'); break; @@ -808,10 +808,10 @@ public function getOpenUserTicketsByPriority($userId, $projectId): array } else { // If the priority is not set, the label for priority not defined is used. if (empty($this->ticketRepository->priority[$row['priority']])) { - $label =$this->language->__("label.priority_not_defined"); + $label = $this->language->__("label.priority_not_defined"); } $tickets[$row['priority']] = array( - "labelName" =>$label, + "labelName" => $label, "tickets" => array($row), "groupValue" => $row['time'], ); @@ -1232,14 +1232,16 @@ public function quickAddMilestone($params): array|bool|int */ public function addTicket($values) { + $userId = $values['userId'] ?? session("userdata.id"); + $values = array( 'id' => '', 'headline' => $values['headline'] ?? "", 'type' => $values['type'] ?? "task", 'description' => $values['description'] ?? "", - 'projectId' => $values['projectId'] ?? session("currentProject") , + 'projectId' => $values['projectId'] ?? session("currentProject"), 'editorId' => $values['editorId'] ?? "", - 'userId' => session("userdata.id"), + 'userId' => $userId, 'date' => gmdate("Y-m-d H:i:s"), 'dateToFinish' => $values['dateToFinish'] ?? "", 'timeToFinish' => $values['timeToFinish'] ?? "", @@ -1259,7 +1261,7 @@ public function addTicket($values) 'milestoneid' => $values['milestoneid'] ?? "", ); - if (!$this->projectService->isUserAssignedToProject(session("userdata.id"), $values['projectId'])) { + if (!$this->projectService->isUserAssignedToProject($userId, $values['projectId'])) { return array("msg" => "notifications.ticket_save_error_no_access", "type" => "error"); } @@ -2108,4 +2110,108 @@ public function pollForUpdatedAccountTodos(): array|false return $todos; } + + public function createTodoUsingZapier($values): array|bool + { + $values = array( + 'headline' => $values['headline'] ?? "", + 'userId' => $values['userId'] ?? "", + 'type' => $values['type'] ?? "", + 'description' => $values['description'] ?? "", + 'projectId' => $values['projectId'] ?? session("currentProject"), + 'editorId' => $values['editorId'] ?? "", + 'date' => dtHelper()->userNow()->formatDateTimeForDb(), + 'dateToFinish' => $values['dateToFinish'] ?? "", + 'timeToFinish' => $values['timeToFinish'] ?? "", + 'status' => $values['status'] ?? "", + 'planHours' => $values['planHours'] ?? "", + 'tags' => $values['tags'] ?? "", + 'sprint' => $values['sprint'] ?? "", + 'storypoints' => $values['storypoints'] ?? "", + 'hourRemaining' => $values['hourRemaining'] ?? "", + 'priority' => $values['priority'] ?? "", + 'acceptanceCriteria' => $values['acceptanceCriteria'] ?? "", + 'editFrom' => $values['editFrom'] ?? "", + 'editTo' => $values['editTo'] ?? "", + 'dependingTicketId' => $values['dependingTicketId'] ?? "", + 'milestoneid' => $values['milestoneid'] ?? "", + ); + + return $this->addTicket($values); + } + + public function updateTodoUsingZapier($values): array + { + if (!isset($values['ticketId'])) { + error_log('we dont have a ticket ..'); + return [ + "message" => "Missing ticketId", + "status" => "error", + ]; + } + + $currentTicket = $this->getTicket($values['ticketId']); + + if (!$currentTicket) { + return [ + "message" => "We do not have a ticket for id " . $values['ticketId'], + "status" => "error", + ]; + } + + $values = array( + 'id' => $values['ticketId'], + 'headline' => $currentTicket->headline, + 'editorId' => $values['editorId'] ?? "", + 'status' => $values['status'] ?? "", + 'milestoneid' => $values['milestoneid'] ?? "", + ); + + try { + $sucessfullyUpdated = $this->updateTicket($values); + if ($sucessfullyUpdated) { + return [ + "message" => "Ticket updated successfully", + "status" => "success", + ]; + } else { + return [ + "message" => "Ticket could not be updated", + "status" => "error", + ]; + } + } catch (\Exception $e) { + return [ + "message" => "Ticket could not be updated. Reason: " . $e->getMessage(), + "status" => "error", + ]; + } + } + + public function createMilestoneUsingZapier($values): array|bool + { + $values = array( + 'status' => $values['status'] ?? "", + 'description' => $values['description'] ?? "", + 'projectId' => $values['projectId'] ?? session("currentProject"), + 'editorId' => $values['editorId'] ?? "", + 'date' => dtHelper()->userNow()->formatDateTimeForDb(), + 'dateToFinish' => $values['dateToFinish'] ?? "", + 'timeToFinish' => $values['timeToFinish'] ?? "", + 'planHours' => $values['planHours'] ?? "", + 'tags' => $values['tags'] ?? "", + 'sprint' => $values['sprint'] ?? "", + 'storypoints' => $values['storypoints'] ?? "", + 'hourRemaining' => $values['hourRemaining'] ?? "", + 'priority' => $values['priority'] ?? "", + 'acceptanceCriteria' => $values['acceptanceCriteria'] ?? "", + 'editFrom' => $values['editFrom'] ?? "", + 'editTo' => $values['editTo'] ?? "", + 'dependingTicketId' => $values['dependingTicketId'] ?? "", + 'milestoneid' => $values['milestoneid'] ?? "", + ); + + return $this->addTicket($values); + } + } } From 8b2c7ec2902fb65f70e1f30c5c88b5d7b517a862 Mon Sep 17 00:00:00 2001 From: kylemcshea Date: Wed, 10 Jul 2024 17:19:41 -0400 Subject: [PATCH 09/22] feat: ability for zapier to poll by new timesheets and updated timesheets --- app/Domain/Install/Repositories/Install.php | 14 +-- .../Timesheets/Repositories/Timesheets.php | 93 ++++++++++++++++--- app/Domain/Timesheets/Services/Timesheets.php | 17 ++++ 3 files changed, 105 insertions(+), 19 deletions(-) diff --git a/app/Domain/Install/Repositories/Install.php b/app/Domain/Install/Repositories/Install.php index b31dfd6f7..ce2264067 100644 --- a/app/Domain/Install/Repositories/Install.php +++ b/app/Domain/Install/Repositories/Install.php @@ -613,7 +613,7 @@ private function sqlPrep(): string ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; insert into `zp_tickets`(`id`,`projectId`,`headline`,`description`,`acceptanceCriteria`,`date`,`dateToFinish`,`priority`,`status`,`userId`,`os`,`browser`,`resolution`,`component`,`version`,`url`,`milestoneid`,`editFrom`,`editTo`,`editorId`,`planHours`,`hourRemaining`,`type`,`production`,`staging`,`storypoints`,`sprint`,`sortindex`,`kanbanSortIndex`) values - (9,3,'Getting Started with Leantime', '".$gettingStartedDescription."','','".date("Y-m-d")."','".date("Y-m-d")."',2,3,1,NULL,NULL,NULL,NULL,'',NULL,NULL,'1969-12-31 00:00:00','1969-12-31 00:00:00',1,0,0,'Story',0,0,0,0,NULL,NULL); + (9,3,'Getting Started with Leantime', '" . $gettingStartedDescription . "','','" . date("Y-m-d") . "','" . date("Y-m-d") . "',2,3,1,NULL,NULL,NULL,NULL,'',NULL,NULL,'1969-12-31 00:00:00','1969-12-31 00:00:00',1,0,0,'Story',0,0,0,0,NULL,NULL); CREATE TABLE `zp_timesheets` ( `id` int(255) NOT NULL AUTO_INCREMENT, @@ -630,6 +630,7 @@ private function sqlPrep(): string `rate` varchar(255) DEFAULT NULL, `paid` int(2) DEFAULT NULL, `paidDate` datetime DEFAULT NULL, + `modified` datetime DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `Unique` (`userId`,`ticketId`,`workDate`,`kind`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; @@ -1310,11 +1311,11 @@ private function update_sql_20111(): bool|array "UPDATE zp_projects SET menuType = '" . MenuRepository::DEFAULT_MENU . "'", "ALTER TABLE zp_canvas_items ADD relates VARCHAR(255) null", "UPDATE zp_canvas_items INNER JOIN zp_canvas ON zp_canvas.id = zp_canvas_items.id " . - "SET zp_canvas_items.status = 'draft' WHERE zp_canvas_items.status = 'danger' AND zp_canvas.type = 'leancanvas'", + "SET zp_canvas_items.status = 'draft' WHERE zp_canvas_items.status = 'danger' AND zp_canvas.type = 'leancanvas'", "UPDATE zp_canvas_items INNER JOIN zp_canvas ON zp_canvas.id = zp_canvas_items.id " . - "SET zp_canvas_items.status = 'valid' WHERE zp_canvas_items.status = 'sucess' AND zp_canvas.type = 'leancanvas'", + "SET zp_canvas_items.status = 'valid' WHERE zp_canvas_items.status = 'sucess' AND zp_canvas.type = 'leancanvas'", "UPDATE zp_canvas_items INNER JOIN zp_canvas ON zp_canvas.id = zp_canvas_items.id " . - "SET zp_canvas_items.status = 'invalid' WHERE zp_canvas_items.status = 'info' AND zp_canvas.type = 'leancanvas'", + "SET zp_canvas_items.status = 'invalid' WHERE zp_canvas_items.status = 'info' AND zp_canvas.type = 'leancanvas'", "UPDATE zp_canvas SET zp_canvas.type = 'retroscanvas' WHERE zp_canvas.type = 'retrospective'", ]; @@ -1903,7 +1904,8 @@ public function update_sql_20407(): bool|array } } - public function update_sql_30002(): bool|array { + public function update_sql_30002(): bool|array + { $errors = array(); @@ -1924,8 +1926,6 @@ public function update_sql_30002(): bool|array { return true; - } - } } diff --git a/app/Domain/Timesheets/Repositories/Timesheets.php b/app/Domain/Timesheets/Repositories/Timesheets.php index b33818c6c..020f59197 100644 --- a/app/Domain/Timesheets/Repositories/Timesheets.php +++ b/app/Domain/Timesheets/Repositories/Timesheets.php @@ -82,6 +82,7 @@ public function getAll(?int $id, ?string $kind, ?CarbonInterface $dateFrom, ?Car zp_tickets.headline, zp_tickets.planHours, zp_tickets.tags, + zp_tickets.modified, milestone.headline as milestone FROM zp_timesheets @@ -231,6 +232,7 @@ public function getWeeklyTimesheets(int $projectId, CarbonInterface $fromDate, i zp_timesheets.paid, zp_timesheets.paidDate, zp_timesheets.kind, + zp_timesheets.modified, zp_tickets.headline, zp_tickets.planHours, zp_projects.name, @@ -329,7 +331,8 @@ public function addTime(array $values): void invoicedCompDate, rate, paid, - paidDate + paidDate, + modified ) VALUES ( :userId, :ticket, @@ -343,7 +346,8 @@ public function addTime(array $values): void :invoicedCompDate, :rate, :paid, - :paidDate + :paidDate, + :modified ) ON DUPLICATE KEY UPDATE hours = hours + :hours, description = CONCAT(:date, '\n', :description, '\n', '--', '\n\n', description)"; @@ -367,6 +371,7 @@ public function addTime(array $values): void $call->bindValue(':hours', $values['hours']); $call->bindValue(':paid', $values['paid'] ?? ''); $call->bindValue(':paidDate', $values['paidDate'] ?? ''); + $call->bindValue(':modified', date("Y-m-d H:i:s"), PDO::PARAM_STR); $call->execute(); @@ -396,7 +401,8 @@ public function upsertTimesheetEntry(array $values): void invoicedCompDate, rate, paid, - paidDate + paidDate, + modified ) VALUES ( :userId, :ticket, @@ -409,7 +415,8 @@ public function upsertTimesheetEntry(array $values): void :invoicedCompDate, :rate, :paid, - :paidDate + :paidDate, + :modified ) ON DUPLICATE KEY UPDATE hours = :hours"; @@ -431,6 +438,7 @@ public function upsertTimesheetEntry(array $values): void $call->bindValue(':hours', $values['hours']); $call->bindValue(':paid', $values['paid'] ?? ''); $call->bindValue(':paidDate', $values['paidDate'] ?? ''); + $call->bindValue(':modified', date("Y-m-d H:i:s"), PDO::PARAM_STR); $call->execute(); @@ -460,7 +468,8 @@ public function getTimesheet(int $id): mixed zp_timesheets.invoicedEmplDate, zp_timesheets.invoicedCompDate, zp_timesheets.paid, - zp_timesheets.paidDate + zp_timesheets.paidDate, + zp_timesheets.modified FROM zp_timesheets LEFT JOIN zp_tickets ON zp_timesheets.ticketId = zp_tickets.id @@ -498,7 +507,8 @@ public function updateTime(array $values): void invoicedEmplDate =:invoicedEmplDate, invoicedCompDate =:invoicedCompDate, paid =:paid, - paidDate =:paidDate + paidDate =:paidDate, + modified =:modified WHERE id = :id"; @@ -517,6 +527,7 @@ public function updateTime(array $values): void $call->bindValue(':paid', $values['paid']); $call->bindValue(':paidDate', $values['paidDate']); $call->bindValue(':id', $values['id']); + $call->bindValue(':modified', date("Y-m-d H:i:s"), PDO::PARAM_STR); $call->execute(); @@ -537,7 +548,8 @@ public function updateHours(array $values): void $query = "UPDATE zp_timesheets SET - hours = :hours + hours = :hours, + modified =:modified WHERE userId = :userId AND ticketId = :ticketId @@ -555,6 +567,7 @@ public function updateHours(array $values): void $call->bindValue(':userId', $values['userId']); $call->bindValue(':ticketId', $values['ticket']); $call->bindValue(':kind', $values['kind']); + $call->bindValue(':modified', date("Y-m-d H:i:s"), PDO::PARAM_STR); $call->execute(); @@ -658,8 +671,8 @@ public function getLoggedHoursForTicket(int $ticketId): array } else { $utc = dtHelper()->dbNow()->format("Y-m-d"); $returnValues[$utc] = [ - 'utc' => $utc, - 'summe' => 0, + 'utc' => $utc, + 'summe' => 0, ]; } @@ -716,13 +729,15 @@ public function updateInvoices(array $invEmpl, array $invComp = [], array $paid foreach ($invEmpl as $row1) { $query = "UPDATE zp_timesheets SET invoicedEmpl = 1, - invoicedEmplDate = :date + invoicedEmplDate = :date, + modified = :modified WHERE id = :id "; $invEmplCall = $this->dbcall(func_get_args(), ['dbcall_key' => 'inv_empl']); $invEmplCall->prepare($query); $invEmplCall->bindValue(':id', $row1); $invEmplCall->bindValue(':date', Carbon::now(session("usersettings.timezone"))->setTimezone('UTC')); + $invEmplCall->bindValue(':modified', date('Y-m-d H:i:s'), PDO::PARAM_STR); $invEmplCall->execute(); unset($invEmplCall); @@ -731,13 +746,15 @@ public function updateInvoices(array $invEmpl, array $invComp = [], array $paid foreach ($invComp as $row2) { $query2 = "UPDATE zp_timesheets SET invoicedComp = 1, - invoicedCompDate = :date + invoicedCompDate = :date, + modified = :modified WHERE id = :id "; $invCompCall = $this->dbcall(func_get_args(), ['dbcall_key' => 'inv_comp']); $invCompCall->prepare($query2); $invCompCall->bindValue(':id', $row2); $invCompCall->bindValue(':date', Carbon::now(session("usersettings.timezone"))->setTimezone('UTC')); + $invCompCall->bindValue(':modified', date('Y-m-d H:i:s'), PDO::PARAM_STR); $invCompCall->execute(); unset($invCompCall); @@ -746,13 +763,15 @@ public function updateInvoices(array $invEmpl, array $invComp = [], array $paid foreach ($paid as $row3) { $query3 = "UPDATE zp_timesheets SET paid = 1, - paidDate = :date + paidDate = :date, + modified = :modified WHERE id = :id "; $paidCol = $this->dbcall(func_get_args(), ['dbcall_key' => 'paid']); $paidCol->prepare($query3); $paidCol->bindValue(':id', $row3); $paidCol->bindValue(':date', Carbon::now(session("usersettings.timezone"))->setTimezone('UTC')); + $paidCol->bindValue(':modified', date('Y-m-d H:i:s'), PDO::PARAM_STR); $paidCol->execute(); unset($paidCol); @@ -905,5 +924,55 @@ public function isClocked(int $id): false|array return $onTheClock; } + public function getAllAccountTimesheets(): array|false + { + $query = "SELECT + zp_timesheets.id, + zp_timesheets.userId, + zp_timesheets.ticketId, + zp_timesheets.workDate, + zp_timesheets.hours, + zp_timesheets.description, + zp_timesheets.kind, + zp_projects.name, + zp_projects.id AS projectId, + zp_clients.name AS clientName, + zp_clients.id AS clientId, + zp_timesheets.invoicedEmpl, + zp_timesheets.invoicedComp, + zp_timesheets.invoicedEmplDate, + zp_timesheets.invoicedCompDate, + zp_timesheets.paid, + zp_timesheets.paidDate, + zp_timesheets.modified, + zp_user.firstname, + zp_user.lastname, + zp_tickets.id as ticketId, + zp_tickets.headline, + zp_tickets.planHours, + zp_tickets.tags, + milestone.headline as milestone + FROM + zp_timesheets + LEFT JOIN zp_user ON zp_timesheets.userId = zp_user.id + LEFT JOIN zp_tickets ON zp_timesheets.ticketId = zp_tickets.id + LEFT JOIN zp_projects ON zp_tickets.projectId = zp_projects.id + LEFT JOIN zp_clients ON zp_projects.clientId = zp_clients.id + LEFT JOIN zp_tickets milestone ON zp_tickets.milestoneid = milestone.id"; + + $query .= " GROUP BY + zp_timesheets.id, + zp_timesheets.userId, + zp_timesheets.ticketId, + zp_timesheets.workDate, + zp_timesheets.hours, + zp_timesheets.description, + zp_timesheets.kind"; + + $call = $this->dbcall(func_get_args()); + + $call->prepare($query); + return $call->fetchAll(); + } } diff --git a/app/Domain/Timesheets/Services/Timesheets.php b/app/Domain/Timesheets/Services/Timesheets.php index 746d91391..7268f3541 100644 --- a/app/Domain/Timesheets/Services/Timesheets.php +++ b/app/Domain/Timesheets/Services/Timesheets.php @@ -452,4 +452,21 @@ public function getBookedHourTypes(): array { return $this->timesheetsRepo->kind; } + + public function pollTimesheets(): array|false + { + return $this->timesheetsRepo->getAllAccountTimesheets(); + } + + public function pollForUpdatedTimesheets(): array|false + { + $timesheets = $this->timesheetsRepo->getAllAccountTimesheets(); + + foreach ($timesheets as $key => $timesheet) { + $timesheets[$key]['id'] = $timesheet['id'] . '-' . $timesheet['modified']; + } + + return $timesheets; + } + } From bdc885f26aabe1aba18678b1d44ddbf40749a72e Mon Sep 17 00:00:00 2001 From: kylemcshea Date: Wed, 10 Jul 2024 17:19:57 -0400 Subject: [PATCH 10/22] feat: zapier able to create timesheets via actions --- app/Domain/Timesheets/Services/Timesheets.php | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/app/Domain/Timesheets/Services/Timesheets.php b/app/Domain/Timesheets/Services/Timesheets.php index 7268f3541..63e3cd7dc 100644 --- a/app/Domain/Timesheets/Services/Timesheets.php +++ b/app/Domain/Timesheets/Services/Timesheets.php @@ -2,6 +2,7 @@ namespace Leantime\Domain\Timesheets\Services; +use Carbon\Carbon; use Carbon\CarbonInterface; use Illuminate\Contracts\Container\BindingResolutionException; use Leantime\Core\Support\FromFormat; @@ -469,4 +470,42 @@ public function pollForUpdatedTimesheets(): array|false return $timesheets; } + /** + * Create a timesheet entry via Zapier. + * + * @param array $values { + * @type int $ticketId The I?D of the ticket. + * @type int? $userId Th?e ID of the user. + * @type string $date The date in 'YYYY-MM-DD' format. + * @type string $kind The type of work done (e.g., 'DEVELOPMENT'). + * @type int $hours The number of hours worked. + * @type float? $rate The rate of pay. + * @type string? $description A description of the work done. + * @type bool? $paid Whether the time has been paid. + * } + * + * @return array { + * @type bool $success Whether the timesheet entry was created successfully. + * } + * + * @throws InvalidArgumentException if required parameters are missing. + */ + public function createTimesheetViaZapierAction($values): array + { + if (isset($values['date'])) { + $values['date'] = Carbon::parse($values['date']); + } + + $success = $this->logTime($values['ticketId'], $values); + + if ($success) { + return [ + 'success' => true, + ]; + } else { + return [ + 'success' => false, + ]; + } + } } From e2dac9a8ca42b09ef102568a861c1ee173502621 Mon Sep 17 00:00:00 2001 From: kylemcshea Date: Tue, 23 Jul 2024 23:32:16 -0400 Subject: [PATCH 11/22] fix: utilize user session with api key call --- app/Domain/Tickets/Services/Tickets.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/Domain/Tickets/Services/Tickets.php b/app/Domain/Tickets/Services/Tickets.php index 0ae0e29b3..f67566f03 100644 --- a/app/Domain/Tickets/Services/Tickets.php +++ b/app/Domain/Tickets/Services/Tickets.php @@ -1232,8 +1232,6 @@ public function quickAddMilestone($params): array|bool|int */ public function addTicket($values) { - $userId = $values['userId'] ?? session("userdata.id"); - $values = array( 'id' => '', 'headline' => $values['headline'] ?? "", @@ -1241,7 +1239,7 @@ public function addTicket($values) 'description' => $values['description'] ?? "", 'projectId' => $values['projectId'] ?? session("currentProject"), 'editorId' => $values['editorId'] ?? "", - 'userId' => $userId, + 'userId' => session("userdata.id"), 'date' => gmdate("Y-m-d H:i:s"), 'dateToFinish' => $values['dateToFinish'] ?? "", 'timeToFinish' => $values['timeToFinish'] ?? "", @@ -1261,7 +1259,7 @@ public function addTicket($values) 'milestoneid' => $values['milestoneid'] ?? "", ); - if (!$this->projectService->isUserAssignedToProject($userId, $values['projectId'])) { + if (!$this->projectService->isUserAssignedToProject(session("userdata.id"), $values['projectId'])) { return array("msg" => "notifications.ticket_save_error_no_access", "type" => "error"); } From 2c6ba5ed6ce8559e2beef9f46d4f71c8bb90ddaf Mon Sep 17 00:00:00 2001 From: kylemcshea Date: Tue, 23 Jul 2024 23:39:00 -0400 Subject: [PATCH 12/22] fix: remove `headline` requirement for updating ticket --- app/Domain/Tickets/Services/Tickets.php | 71 +++++++------------------ 1 file changed, 19 insertions(+), 52 deletions(-) diff --git a/app/Domain/Tickets/Services/Tickets.php b/app/Domain/Tickets/Services/Tickets.php index f67566f03..776b6a886 100644 --- a/app/Domain/Tickets/Services/Tickets.php +++ b/app/Domain/Tickets/Services/Tickets.php @@ -1354,34 +1354,30 @@ public function updateTicket($values): array|bool return array("msg" => "notifications.ticket_save_error_no_access", "type" => "error"); } - if ($values['headline'] === '') { - return array("msg" => "notifications.ticket_save_error_no_headline", "type" => "error"); - } else { - $values = $this->prepareTicketDates($values); + $values = $this->prepareTicketDates($values); - //Update Ticket - if ($this->ticketRepository->updateTicket($values, $values['id']) === true) { - $subject = sprintf($this->language->__("email_notifications.todo_update_subject"), $values['id'], $values['headline']); - $actual_link = BASE_URL . "/dashboard/home#/tickets/showTicket/" . $values['id']; - $message = sprintf($this->language->__("email_notifications.todo_update_message"), session("userdata.name"), $values['headline']); + //Update Ticket + if ($this->ticketRepository->updateTicket($values, $values['id']) === true) { + $subject = sprintf($this->language->__("email_notifications.todo_update_subject"), $values['id'], $values['headline']); + $actual_link = BASE_URL . "/dashboard/home#/tickets/showTicket/" . $values['id']; + $message = sprintf($this->language->__("email_notifications.todo_update_message"), session("userdata.name"), $values['headline']); - $notification = app()->make(NotificationModel::class); - $notification->url = array( - "url" => $actual_link, - "text" => $this->language->__("email_notifications.todo_update_cta"), - ); - $notification->entity = $values; - $notification->module = "tickets"; - $notification->projectId = session("currentProject"); - $notification->subject = $subject; - $notification->authorId = session("userdata.id"); - $notification->message = $message; + $notification = app()->make(NotificationModel::class); + $notification->url = array( + "url" => $actual_link, + "text" => $this->language->__("email_notifications.todo_update_cta"), + ); + $notification->entity = $values; + $notification->module = "tickets"; + $notification->projectId = session("currentProject"); + $notification->subject = $subject; + $notification->authorId = session("userdata.id"); + $notification->message = $message; - $this->projectService->notifyProjectUsers($notification); + $this->projectService->notifyProjectUsers($notification); - return true; - } + return true; } @@ -2109,35 +2105,6 @@ public function pollForUpdatedAccountTodos(): array|false return $todos; } - public function createTodoUsingZapier($values): array|bool - { - $values = array( - 'headline' => $values['headline'] ?? "", - 'userId' => $values['userId'] ?? "", - 'type' => $values['type'] ?? "", - 'description' => $values['description'] ?? "", - 'projectId' => $values['projectId'] ?? session("currentProject"), - 'editorId' => $values['editorId'] ?? "", - 'date' => dtHelper()->userNow()->formatDateTimeForDb(), - 'dateToFinish' => $values['dateToFinish'] ?? "", - 'timeToFinish' => $values['timeToFinish'] ?? "", - 'status' => $values['status'] ?? "", - 'planHours' => $values['planHours'] ?? "", - 'tags' => $values['tags'] ?? "", - 'sprint' => $values['sprint'] ?? "", - 'storypoints' => $values['storypoints'] ?? "", - 'hourRemaining' => $values['hourRemaining'] ?? "", - 'priority' => $values['priority'] ?? "", - 'acceptanceCriteria' => $values['acceptanceCriteria'] ?? "", - 'editFrom' => $values['editFrom'] ?? "", - 'editTo' => $values['editTo'] ?? "", - 'dependingTicketId' => $values['dependingTicketId'] ?? "", - 'milestoneid' => $values['milestoneid'] ?? "", - ); - - return $this->addTicket($values); - } - public function updateTodoUsingZapier($values): array { if (!isset($values['ticketId'])) { From 5623801ec74e81a742a33f251e906329b2b6e647 Mon Sep 17 00:00:00 2001 From: kylemcshea Date: Wed, 24 Jul 2024 00:16:26 -0400 Subject: [PATCH 13/22] chore: default to previous headline of ticket if headline not sent to update function --- app/Domain/Tickets/Services/Tickets.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/Domain/Tickets/Services/Tickets.php b/app/Domain/Tickets/Services/Tickets.php index 776b6a886..6f8831da5 100644 --- a/app/Domain/Tickets/Services/Tickets.php +++ b/app/Domain/Tickets/Services/Tickets.php @@ -1323,6 +1323,15 @@ public function addTicket($values) * - 'time*/ public function updateTicket($values): array|bool { + if (!isset($values["headline"])) { + $currentTicket = $this->getTicket($values['id']); + + if (!$currentTicket) { + return array("msg" => "This ticket id does not exist within your leantime account.", "type" => "error"); + } + + $values["headline"] = $currentTicket->headline; + } $values = array( 'id' => $values['id'], From 77acbfdcce379c7e15bffd4b66a5f6b508f9acaf Mon Sep 17 00:00:00 2001 From: kylemcshea Date: Wed, 24 Jul 2024 00:16:38 -0400 Subject: [PATCH 14/22] chore: remove unneccesary todo comment --- app/Domain/Ideas/Repositories/Ideas.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/Domain/Ideas/Repositories/Ideas.php b/app/Domain/Ideas/Repositories/Ideas.php index b06e5255f..834bd1442 100644 --- a/app/Domain/Ideas/Repositories/Ideas.php +++ b/app/Domain/Ideas/Repositories/Ideas.php @@ -632,9 +632,6 @@ public function bulkUpdateIdeaStatus($params): bool */ public function getAllIdeas(): array|false { - - // TODO: make this not select * and identify what fields we want back. - $sql = "SELECT zp_canvas_items.id, zp_canvas_items.description, zp_canvas_items.assumptions, From 0303b90e49ef45f5e267caa3df08e45ccad7b7f0 Mon Sep 17 00:00:00 2001 From: kylemcshea Date: Wed, 24 Jul 2024 00:17:24 -0400 Subject: [PATCH 15/22] enhance: make function name for polling new idea clearer --- app/Domain/Ideas/Services/Ideas.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Domain/Ideas/Services/Ideas.php b/app/Domain/Ideas/Services/Ideas.php index 0707adfe2..898f9fcea 100644 --- a/app/Domain/Ideas/Services/Ideas.php +++ b/app/Domain/Ideas/Services/Ideas.php @@ -13,7 +13,7 @@ public function __construct(IdeasRepository $ideasRepository) $this->ideasRepository = $ideasRepository; } - public function pollIdeas(): array + public function pollForNewIdeas(): array { return $this->ideasRepository->getAllIdeas(); } From 9489f4af2b138567022a6747c7ac6ee34bee6f2d Mon Sep 17 00:00:00 2001 From: kylemcshea Date: Wed, 24 Jul 2024 00:17:35 -0400 Subject: [PATCH 16/22] chore: remove unneeded comment --- app/Domain/Projects/Services/Projects.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/Domain/Projects/Services/Projects.php b/app/Domain/Projects/Services/Projects.php index a158f61bf..13b75585c 100644 --- a/app/Domain/Projects/Services/Projects.php +++ b/app/Domain/Projects/Services/Projects.php @@ -1561,9 +1561,6 @@ public function getAll(bool $showClosedProjects = false): array return $this->projectRepository->getAll($showClosedProjects); } - /** - * @return array - */ public function pollForUpdatedProjects(): array { $projects = $this->projectRepository->getAll(false); From 7b6950e71ec9c1004d4a8429cb572bd6a2704fe6 Mon Sep 17 00:00:00 2001 From: kylemcshea Date: Wed, 24 Jul 2024 00:18:01 -0400 Subject: [PATCH 17/22] fix: utilize `logTime` instead of making new zapier function for action --- app/Domain/Timesheets/Services/Timesheets.php | 39 ------------------- 1 file changed, 39 deletions(-) diff --git a/app/Domain/Timesheets/Services/Timesheets.php b/app/Domain/Timesheets/Services/Timesheets.php index 63e3cd7dc..5c6367e15 100644 --- a/app/Domain/Timesheets/Services/Timesheets.php +++ b/app/Domain/Timesheets/Services/Timesheets.php @@ -469,43 +469,4 @@ public function pollForUpdatedTimesheets(): array|false return $timesheets; } - - /** - * Create a timesheet entry via Zapier. - * - * @param array $values { - * @type int $ticketId The I?D of the ticket. - * @type int? $userId Th?e ID of the user. - * @type string $date The date in 'YYYY-MM-DD' format. - * @type string $kind The type of work done (e.g., 'DEVELOPMENT'). - * @type int $hours The number of hours worked. - * @type float? $rate The rate of pay. - * @type string? $description A description of the work done. - * @type bool? $paid Whether the time has been paid. - * } - * - * @return array { - * @type bool $success Whether the timesheet entry was created successfully. - * } - * - * @throws InvalidArgumentException if required parameters are missing. - */ - public function createTimesheetViaZapierAction($values): array - { - if (isset($values['date'])) { - $values['date'] = Carbon::parse($values['date']); - } - - $success = $this->logTime($values['ticketId'], $values); - - if ($success) { - return [ - 'success' => true, - ]; - } else { - return [ - 'success' => false, - ]; - } - } } From 1c9dbc9cb4024ad6b16b14f07f31e22f769d59a0 Mon Sep 17 00:00:00 2001 From: kylemcshea Date: Wed, 24 Jul 2024 00:20:07 -0400 Subject: [PATCH 18/22] enhance: utilize `updateTicket` instead of making a new zapier function for update todo action --- app/Domain/Tickets/Services/Tickets.php | 48 ------------------------- 1 file changed, 48 deletions(-) diff --git a/app/Domain/Tickets/Services/Tickets.php b/app/Domain/Tickets/Services/Tickets.php index 6f8831da5..2fc537bd5 100644 --- a/app/Domain/Tickets/Services/Tickets.php +++ b/app/Domain/Tickets/Services/Tickets.php @@ -2114,54 +2114,6 @@ public function pollForUpdatedAccountTodos(): array|false return $todos; } - public function updateTodoUsingZapier($values): array - { - if (!isset($values['ticketId'])) { - error_log('we dont have a ticket ..'); - return [ - "message" => "Missing ticketId", - "status" => "error", - ]; - } - - $currentTicket = $this->getTicket($values['ticketId']); - - if (!$currentTicket) { - return [ - "message" => "We do not have a ticket for id " . $values['ticketId'], - "status" => "error", - ]; - } - - $values = array( - 'id' => $values['ticketId'], - 'headline' => $currentTicket->headline, - 'editorId' => $values['editorId'] ?? "", - 'status' => $values['status'] ?? "", - 'milestoneid' => $values['milestoneid'] ?? "", - ); - - try { - $sucessfullyUpdated = $this->updateTicket($values); - if ($sucessfullyUpdated) { - return [ - "message" => "Ticket updated successfully", - "status" => "success", - ]; - } else { - return [ - "message" => "Ticket could not be updated", - "status" => "error", - ]; - } - } catch (\Exception $e) { - return [ - "message" => "Ticket could not be updated. Reason: " . $e->getMessage(), - "status" => "error", - ]; - } - } - public function createMilestoneUsingZapier($values): array|bool { $values = array( From 85fd91f4a4f08530daabd16b3b7017a7d2837144 Mon Sep 17 00:00:00 2001 From: kylemcshea Date: Wed, 24 Jul 2024 00:21:49 -0400 Subject: [PATCH 19/22] chore: clean up function name to encapsulate for todo and not generic ticket --- app/Domain/Tickets/Services/Tickets.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/Domain/Tickets/Services/Tickets.php b/app/Domain/Tickets/Services/Tickets.php index 2fc537bd5..51189347d 100644 --- a/app/Domain/Tickets/Services/Tickets.php +++ b/app/Domain/Tickets/Services/Tickets.php @@ -2089,8 +2089,7 @@ public function pollForUpdatedAccountMilestones(): array|false return $milestones; } - // TODO: update this to be todo and update zapier as well - public function pollForNewAccountTickets(): array|false + public function pollForNewAccountTodos(): array|false { return $this->ticketRepository->getAllBySearchCriteria( ["excludeType" => "milestone"], From d4a7356c3cc12732de11603dcef0b753030645b6 Mon Sep 17 00:00:00 2001 From: kylemcshea Date: Wed, 24 Jul 2024 00:33:34 -0400 Subject: [PATCH 20/22] fix: utilize addTicket for new milestone --- app/Domain/Tickets/Services/Tickets.php | 26 ------------------------- 1 file changed, 26 deletions(-) diff --git a/app/Domain/Tickets/Services/Tickets.php b/app/Domain/Tickets/Services/Tickets.php index 51189347d..9dbdfba2c 100644 --- a/app/Domain/Tickets/Services/Tickets.php +++ b/app/Domain/Tickets/Services/Tickets.php @@ -2112,31 +2112,5 @@ public function pollForUpdatedAccountTodos(): array|false return $todos; } - - public function createMilestoneUsingZapier($values): array|bool - { - $values = array( - 'status' => $values['status'] ?? "", - 'description' => $values['description'] ?? "", - 'projectId' => $values['projectId'] ?? session("currentProject"), - 'editorId' => $values['editorId'] ?? "", - 'date' => dtHelper()->userNow()->formatDateTimeForDb(), - 'dateToFinish' => $values['dateToFinish'] ?? "", - 'timeToFinish' => $values['timeToFinish'] ?? "", - 'planHours' => $values['planHours'] ?? "", - 'tags' => $values['tags'] ?? "", - 'sprint' => $values['sprint'] ?? "", - 'storypoints' => $values['storypoints'] ?? "", - 'hourRemaining' => $values['hourRemaining'] ?? "", - 'priority' => $values['priority'] ?? "", - 'acceptanceCriteria' => $values['acceptanceCriteria'] ?? "", - 'editFrom' => $values['editFrom'] ?? "", - 'editTo' => $values['editTo'] ?? "", - 'dependingTicketId' => $values['dependingTicketId'] ?? "", - 'milestoneid' => $values['milestoneid'] ?? "", - ); - - return $this->addTicket($values); - } } } From 1e1a5532f98ca87e6788502ab7244ad1f18d182f Mon Sep 17 00:00:00 2001 From: kylemcshea Date: Wed, 24 Jul 2024 00:36:52 -0400 Subject: [PATCH 21/22] chore: switch to more specific function naming `pollForNewTimesheets` --- app/Domain/Timesheets/Services/Timesheets.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Domain/Timesheets/Services/Timesheets.php b/app/Domain/Timesheets/Services/Timesheets.php index 5c6367e15..fac241ccf 100644 --- a/app/Domain/Timesheets/Services/Timesheets.php +++ b/app/Domain/Timesheets/Services/Timesheets.php @@ -454,7 +454,7 @@ public function getBookedHourTypes(): array return $this->timesheetsRepo->kind; } - public function pollTimesheets(): array|false + public function pollForNewTimesheets(): array|false { return $this->timesheetsRepo->getAllAccountTimesheets(); } From 78d62232d183e06a8fef77944a54c61e2156df92 Mon Sep 17 00:00:00 2001 From: kylemcshea Date: Wed, 24 Jul 2024 00:37:04 -0400 Subject: [PATCH 22/22] chore: remove unneeded comment --- app/Domain/Ideas/Repositories/Ideas.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/Domain/Ideas/Repositories/Ideas.php b/app/Domain/Ideas/Repositories/Ideas.php index 834bd1442..f782e783e 100644 --- a/app/Domain/Ideas/Repositories/Ideas.php +++ b/app/Domain/Ideas/Repositories/Ideas.php @@ -627,9 +627,6 @@ public function bulkUpdateIdeaStatus($params): bool return true; } - /** - * @return array|false - */ public function getAllIdeas(): array|false { $sql = "SELECT zp_canvas_items.id,