6 function getCCWhenDone() {
10 function GetImageLocation() {
11 return "/home/homecu/images/logo.png";
16 return $SYSENV[
"devmode"] == 1;
19 function GetEditPath() {
20 $editFile =
"cuissues_edit.prg";
22 $editPath = GetIsDev() ?
"http://localhost:8000/hcuadm/$editFile" :
"https://my.homecu.net/hcuadm/$editFile";
43 function SetupWorkflow($dbh, $productId, $productText, $featureDetailId, $cu, $cuName, $staffId) {
45 $workflowCreated =
false;
46 $taskEmails = array();
47 $issueEmails = array();
49 $cu = strtolower($cu);
50 $sql =
"select 'FOUND' as found from cutrack where billing_feature_id = $featureDetailId";
51 $sth = db_query($sql, $dbh);
53 throw new exception(
"Found query failed.", 1);
55 if (db_num_rows($sth) > 0) {
56 throw new exception(
"Workflow already exists.", 2);
59 $sql =
"select nextval('cutrackitem_trackitem_id_seq'::text::regclass) as next_item, nextval('cutrack_track_id_seq'::text::regclass) as next_track";
60 $sth = db_query($sql, $dbh);
62 throw new exception(
"nextval query failed.", 4);
64 $row = db_fetch_row($sth, 0);
65 $nextTaskId = intval($row[0]);
66 $issueId = intval($row[1]);
69 $sql =
"select i.issue_id, i.code, i.owner, ii.item_id, ii.title, ii.item_desc, ii.view_order, ii.owner as task_owner, ii.parent, ii.sales_item_id 71 left join cuissuesitem ii on i.issue_id = ii.issue_id 72 where i.gen_for_product = '$productId' 74 $sthList = db_query($sql, $dbh);
76 throw new exception(
"Issue select failed.", 3);
78 $issueResults = array();
80 $insertIssueSQL =
"insert into cutrack 81 (track_id, issue, assigned_to, billing_feature_id, previous_task_owner, user_name, status, target_date_type, entry_date, 82 last_activity_date, issue_id)";
83 $insertTasksSQL =
"insert into cutrackitem (trackitem_id, track_id, title, item_desc, view_order, parent, assigned_to, issue_item_id, billing_item_id)";
85 $taskSQLPartArray = array();
86 $subTaskArray = array();
88 $parentTaskId = $nextTaskId;
91 $parentIMap = array();
93 for($i = 0; $row = db_fetch_assoc($sthList, $i); $i++) {
95 $issueOwner = isset($row[
"owner"]) ? trim($row[
"owner"]) : $staffId;
96 $templateIssueId = isset($row[
"issue_id"]) ? trim($row[
"issue_id"]) :
"";
97 $taskOwner = isset($row[
"task_owner"]) ? trim($row[
"task_owner"]) :
"";
98 $issue = isset($row[
"code"]) ? trim($row[
"code"]) :
"";
100 $insertIssueSQL .=
" values ($issueId, '" . prep_save($issue, 90) .
"', '" . prep_save($issueOwner, 30) .
"', $featureDetailId, 101 '" . prep_save($taskOwner, 12) .
"', '" . prep_save($cu, 12) .
"', 'Active', 'TBD', now(), now(), $templateIssueId)";
102 $sth = db_query($insertIssueSQL, $dbh);
104 throw new exception(
"issue insert failed.", 5);
110 $taskId = isset($row[
"item_id"]) ? trim($row[
"item_id"]) :
"";
112 if($taskId !=
"" && $templateIssueId == $row[
"issue_id"]) {
113 $title = isset($row[
"title"]) ? trim($row[
"title"]) :
"";
114 $description = isset($row[
"item_desc"]) ? trim($row[
"item_desc"]) :
"";
115 $viewOrder = isset($row[
"view_order"]) ? intval($row[
"view_order"]) : 0;
116 $owner = isset($row[
"task_owner"]) ? trim($row[
"task_owner"]) :
"";
117 $parent = isset($row[
"parent"]) ? intval($row[
"parent"]) : 0;
118 $taskTemplateId = isset($row[
"item_id"]) ? intval($row[
"item_id"]) : 0;
119 $billingItemId = isset($row[
"sales_item_id"]) ? intval($row[
"sales_item_id"]) : 0;
121 if ($billingItemId != 0) {
122 $sql =
"select fd.id from cubillfeaturedetail fd 123 inner join cubillfeaturedetail wfd 124 on fd.sales_order_detail_id = wfd.sales_order_detail_id and wfd.id = $featureDetailId and fd.billing_status= 1 125 and fd.sales_item_id = $billingItemId and (fd.workflow_completed is null or fd.workflow_completed = 'N') 127 $sth = db_query($sql, $dbh);
129 throw new exception(
"Billing item id query failed.", 6);
131 $billingItemId = db_fetch_row($sth, 0);
132 $billingItemId = intval($billingItemId[0]);
133 $row[
"sales_item_id"] = $billingItemId;
137 $taskSQLPartArray[] =
"($parentTaskId, $issueId, '" . prep_save($title, 80) .
"', '" . prep_save($description) .
"', 138 $viewOrder, 0, '" . prep_save($owner, 12) .
"', $taskTemplateId, $billingItemId)";
139 $parentIMap[$taskTemplateId] = $parentI ++;
142 if (!HCU_array_key_exists($parent, $subTaskArray)) {
143 $subTaskArray[$parent] = array();
145 $subTaskArray[$parent][] = array(
"description" => $description,
"viewOrder" => $viewOrder,
"owner" => $owner,
"taskTemplateId" => $taskTemplateId,
146 "billingItemId" => $billingItemId,
"title" => $title);
151 $issueResults[] = $row;
154 $subTaskId = $parentTaskId;
156 $sql =
"$insertTasksSQL values " . implode(
", ", $taskSQLPartArray);
157 $sth = db_query($sql, $dbh);
159 throw new exception(
"Parent task insert failed.", 8);
162 $taskSQLPartArray = array();
163 foreach($subTaskArray as $parentId => $detailRecords) {
164 foreach($detailRecords as $record) {
165 $parentTaskId = $nextTaskId + $parentIMap[$parentId];
168 $taskSQLPartArray[] =
"($subTaskId, $issueId, '" . prep_save($title, 80) .
"', '" . prep_save($description) .
"', $viewOrder, $parentTaskId, 169 '" . prep_save($owner, 12) .
"', $taskTemplateId, $billingItemId)";
175 if (count($taskSQLPartArray) > 0) {
176 $sql =
"$insertTasksSQL values " . implode(
", ", $taskSQLPartArray);
177 $sth = db_query($sql, $dbh);
179 throw new exception(
"Sub task creation failed.", 9);
183 $sql =
"select setval('cutrackitem_trackitem_id_seq'::text::regclass, $subTaskId, false)";
185 $sth = db_query($sql, $dbh);
187 throw new exception(
"Setval query failed.", 10);
192 $results = CreateToLine($dbh, array(trim($issueOwner)));
193 if ($results[
"status"] !==
"000") {
194 throw new exception ($results[
"error"], 13);
196 $to = $results[
"data"];
197 $subject =
"$productText job has been created.";
198 $text =
"Billing contract for $cu has been set up. Workflow is set up for $productText which is assigned to you.";
199 $issueEmails[] = array(
"to" => $to,
"subject" => $subject,
"text" => $text,
"issueName" => $issueName,
"issueId" => $issueId);
200 $results = NotifyFirstTaskOwner($dbh, $templateIssueId, $issueId, $staffId, $issueOwner);
201 if ($results[
"status"] !==
"000") {
202 throw new exception ($results[
"error"], 14);
204 $taskEmails = array_merge($taskEmails, $results[
"data"][
"taskEmails"]);
205 $workflowCreated =
true;
208 $sql =
"update cubillfeaturedetail set billing_status = case when billing_status = 5 then 5 else 4 end where id = $featureDetailId";
209 $sth = db_query($sql, $dbh);
211 throw new exception(
"update cubillfeaturedetail query failed.", 11);
215 $returnArray = array(
"status" =>
"000",
"error" =>
"",
216 "data" => array(
"workflowCreated" => $workflowCreated,
"taskEmails" => $taskEmails,
"issueEmails" => $issueEmails,
"issueId" => $issueId));
217 }
catch(exception $e) {
218 $returnArray = array(
"status" => $e->getCode(),
"error" => $e->getMessage());
240 function CreateTaskEmail($to, $subject, $text, $issue, $title, $description, $cuName, $cuCode, $issueId = 0, $taskId = 0, $text2 =
"", $completedNotes =
"") {
242 $editPath = GetEditPath();
243 $isOnDev = GetIsDev();
245 $color = $isOnDev ?
"#6A1B13" :
"#016103";
247 $message =
"<table style='border-width:0px;border-collapse:separate;'> 248 <tr><td style='border-bottom:1px solid black; margin-bottom:5px;' colspan=2>$text</td></tr>";
249 $plainMessage = $text;
252 $message .=
"<tr><td colspan=2>$text2</td></tr>";
253 $plainMessage .=
"\n$text2";
256 $message .=
"<tr><td><b>Job:</b></td><td>$issue</td></tr> 257 <tr><td><b>Task:</b></td><td>$title</td></tr> 258 <tr><td><b>Description:</b></td><td>$description</td></tr> 259 <tr><td><b>CU:</b></td><td>$cuName ($cuCode)</td></tr><tr>";
260 $plainMessage .=
"\nJob:\t$issue 262 \nDescription:\t$description 263 \nCU:\t$cuName ($cuCode)";
264 if ($completedNotes !=
"") {
265 $message .=
"<tr><td><b>Notes:</b></td><td>$completedNotes</td></tr>";
266 $plainMessage .=
"\nNotes:\t$completedNotes";
270 $message .=
"<td style=\"padding: 5px;\"><a href='$editPath?trackId=$issueId&trackItemId=$taskId' style=\"background-color: $color; color: #fff; 271 text-decoration: none; padding: 5px 13px; font-size: 16px; display: block;\">View Task</a></td>";
272 $plainMessage .=
"\nView Task <$editPath?trackId=$issueId&trackItemId=$taskId>";
275 $message .=
"<td style=\"padding: 5px;\"><a href='$editPath?trackId=$issueId' style=\"background-color: $color; color: #fff; 276 text-decoration: none; padding: 5px 13px; font-size: 16px; display: block;\">View Job</a></td>";
277 $plainMessage .=
"\nView Job <$editPath?trackId=$issueId>";
279 $message .=
"</tr></table><br><hr>";
280 CreateEmail($to, $subject, $message, $isOnDev);
297 function CreateIssueEmail($to, $subject, $text, $issue, $status, $cuName, $cuCode, $issueId = 0, $text2 =
"", $completedNotes =
"") {
298 $editPath = GetEditPath();
299 $isOnDev = GetIsDev();
301 $color = $isOnDev ?
"#6A1B13" :
"#016103";
303 $message =
"<table style='border-width:0px;border-collapse:separate;'><colgroup><col style='width:150px'><col></colgroup> 304 <tr><td style='border-bottom:1px solid black; margin-bottom:5px;' colspan=2>$text</td></tr>";
307 $message .=
"<tr><td colspan=2>$text2</td></tr>";
310 $message .=
"<tr><td><b>Title:</b></td><td>$issue</td></tr> 311 <tr><td><b>Status:</b></td><td>$status</td></tr> 312 <tr><td><b>CU:</b></td><td>$cuName ($cuCode)</td></tr><tr>";
314 if ($completedNotes !=
"") {
315 $message .=
"<tr><td><b>Notes:</b></td><td>$completedNotes</td></tr>";
319 $message .=
"<td style=\"padding: 5px;\"><a href='$editPath?trackId=$issueId' style=\"background-color: $color; color: #fff; 320 text-decoration: none; padding: 5px 13px; font-size: 16px; display: block;\">View Job</a></td>";
322 $message .=
"</tr></table><br><hr>";
323 CreateEmail($to, $subject, $message, $isOnDev);
337 function CreateEmail($to, $subject, $message, $isOnDev) {
338 $base64 = chunk_split(base64_encode(file_get_contents(GetImageLocation())));
340 $msg =
"$message<br><img src='data:image/png;base64, $base64' alt='HomeCU logo' />";
343 $notify->mailto = $to;
344 $notify->mailfrom = $isOnDev ?
"billingdev@homecu.com" :
"billing@homecu.com";
345 $notify->mailfromname = $isOnDev ?
"Development Billing" :
"Billing";
346 $notify->subject = $subject;
347 $notify->htmlMsgbody = $msg;
348 $notify->callingfunction = __FUNCTION__;
349 $notify->file = __FILE__;
366 function CreateToLine($dbh, $owners) {
371 if (count($owners) > 0) {
373 foreach($owners as $i => $owner) {
374 $owners[$i] = strtolower(prep_save($owner, 12));
377 $sql =
"select user_name, notifyemail from dmsmonitorusers 378 where trim(user_name) in ('" . implode(
"', '", $owners) .
"') and notifyemail is not null and trim(from notifyemail) <> ''";
379 $sth = db_query($sql, $dbh);
381 throw new exception(
"createToLine query failed.", 1);
386 for($i = 0; $row = db_fetch_assoc($sth, $i); $i++) {
387 $username = isset($row[
"user_name"]) ? trim($row[
"user_name"]) :
"";
388 $email = isset($row[
"notifyemail"]) ? trim($row[
"notifyemail"]) :
"";
389 $thisRecord =
"$username <$email>";
390 $toArray[] = $thisRecord;
394 $returnArray = array(
"status" =>
"000",
"error" =>
"",
"data" => $toArray);
395 }
catch (exception $e) {
396 $returnArray = array(
"status" => $e->getCode(),
"error" => $e->getMessage());
402 function NotifyFirstTaskOwner($dbh, $templateId, $issueId, $staffId, $issueOwnerId) {
404 $staffId = trim($staffId);
405 $issueOwnerId = trim($issueOwnerId);
407 $taskEmails = array();
408 $sql =
"with ordered_trackitem as (select ti.issue_id, ti.item_id, ti.owner, ti.parent, ti.title, ti.item_desc, 409 row_number() over (partition by ti.parent order by ti.parent, ti.view_order, ti.item_id) as number 411 where ti.issue_id = $templateId) 412 select sub.owner as sassigned_to, parent.owner as passigned_to, sub.title as stitle, parent.title as ptitle, sub.item_desc as sitem_desc, 413 parent.item_desc as pitem_desc, sub.item_id as strackitem_id, parent.item_id as ptrackitem_id, t.owner, t.code 415 left join ordered_trackitem parent on t.issue_id = parent.issue_id and parent.parent = 0 and parent.number = 1 416 left join ordered_trackitem sub on t.issue_id = sub.issue_id and sub.parent = parent.item_id and sub.number = 1 417 where t.issue_id = $templateId";
418 $sth = db_query($sql, $dbh);
420 throw new exception(
"first task owner query failed.", 1);
424 for($i = 0; $record = db_fetch_assoc($sth, $i); $i++) {
426 $issue = isset($record[
"code"]) ? trim($record[
"code"]) :
"";
428 if ($record[
"strackitem_id"] !=
"") {
429 if (isset($record[
"sassigned_to"])) {
430 $nextTaskOwner = trim($record[
"sassigned_to"]);
431 }
else if (isset($record[
"passigned_to"])) {
432 $nextTaskOwner = trim($record[
"passigned_to"]);
434 $nextTaskOwner = trim($issueOwnerId);
437 $title = $record[
"stitle"];
438 $description = $record[
"sitem_desc"];
439 $taskId = $record[
"strackitem_id"];
441 }
else if ($record[
"ptrackitem_id"] !=
"") {
442 $nextTaskOwner = isset($record[
"passigned_to"]) ? trim($record[
"passigned_to"]) : trim($issueOwnerId);
443 $title = $record[
"ptitle"];
444 $description = $record[
"pitem_desc"];
445 $taskId = $record[
"ptrackitem_id"];
453 $sql =
"update cutrack set previous_task_owner = '$nextTaskOwner' where track_id = $issueId";
454 $sth = db_query($sql, $dbh);
456 throw new exception(
"update cutrack failed.", 2);
459 if ($nextTaskOwner !=
"" && (strtolower($nextTaskOwner) != strtolower($issueOwnerId) || strtolower($nextTaskOwner) != strtolower($staffId))) {
460 $text =
"Job has been created. You are the first task owner.";
461 $results = CreateToLine($dbh, array($nextTaskOwner));
462 $to = $results[
"data"];
464 $subject =
"You are the next task owner.";
466 $taskEmails[] = array(
"to" => $to,
"subject" => $subject,
"text" => $text,
"issue" => $issue,
"title" => $title,
"description" => $description,
467 "issueId" => $issueId);
470 $returnArray = array(
"status" =>
"000",
"error" =>
"",
"data" => array(
"taskEmails" => $taskEmails));
471 }
catch (exception $e) {
472 $returnArray = array(
"status" => $e->getCode(),
"error" => $e->getMessage());
478 function notifyNextTaskOwner($dbh, $issueId, $taskId, $staffId, $mode, $issueOwnerId, &$errors, &$transactionSQLs, &$taskEmails, &$issueEmails,
479 $completeNotes =
"", $forceEmail =
false, $reassigned =
false, $movedTaskId = 0, $movedAfter =
false) {
481 $issueOwnerId = trim($issueOwnerId);
482 $staffId = trim($staffId);
484 $sql =
"select assigned_to, issue from cutrack where track_id = $issueId limit 1";
485 $sth = db_query($sql,$dbh);
486 $newError = trim(dbErrorNoFormatting());
488 if ($newError !=
"") {
489 $errors[] = $newError;
490 db_free_result($sth);
492 $dRecord = db_fetch_row($sth, 0);
493 $issueOwnerId = $dRecord[0];
494 $issue = $dRecord[1];
497 $sql =
"select * from cutrackitem where track_id = $issueId order by parent, view_order, trackitem_id";
498 $sth = db_query($sql,$dbh);
499 $newError = trim(dbErrorNoFormatting());
501 if ($newError !=
"") {
502 $errors[] = $newError;
503 db_free_result($sth);
509 for($i = 0; $dRecord = db_fetch_assoc($sth, $i); $i++) {
510 $addRecord = $dRecord[
"complete_date"] ==
"" && $dRecord[
"task_status"] != 2;
511 $thisTaskId = $dRecord[
"trackitem_id"];
512 $parent = $dRecord[
"parent"];
514 if ($thisTaskId == $taskId) {
520 $taskIndex = $shownIndex;
523 $dRecord[
"parent"] = 0;
524 $promotedRecord = $dRecord;
537 if ($addRecord && $thisTaskId == $movedTaskId) {
538 $moveIndex = $movedAfter ? $shownIndex + 1 : $shownIndex;
542 $records[] = $dRecord;
549 if ($mode ==
"rearranged") {
550 $task = $records[$taskIndex];
551 if ($taskIndex > $moveIndex) {
552 array_splice($records, $taskIndex, 1);
553 array_splice($records, $moveIndex, 0, array($task));
555 array_splice($records, $moveIndex, 0, array($task));
556 array_splice($records, $taskIndex, 1);
558 }
else if ($mode ==
"promoted") {
561 foreach($records as $record) {
562 if ($record[
"parent"] != 0) {
566 if ($record[
"trackitem_id"] == $promotedRecord[
"parent"]) {
567 $promoteIndex = $i + 1;
572 array_splice($records, $promoteIndex, 0, array($promotedRecord));
578 $parentFound =
false;
581 foreach($records as $record) {
582 $parent = intval($record[
"parent"]);
583 $taskId = intval($record[
"trackitem_id"]);
587 $parentTask = $record;
590 }
else if ($parent == $parentId) {
593 $childTask = $record;
597 if ($parentFound && ($childFound || $parent > $parentId)) {
603 $record = isset($childTask) ? $childTask : (isset($parentTask) ? $parentTask :
null);
605 $title = trim($record[
"title"]);
606 $description = trim($record[
"item_desc"]);
607 $taskId = intval($record[
"trackitem_id"]);
609 $nextTaskOwner = trim($childTask[
"assigned_to"]);
610 if ($nextTaskOwner ==
"") {
611 $nextTaskOwner = trim($parentTask[
"assigned_to"]);
613 if ($nextTaskOwner ==
"") {
614 $nextTaskOwner = trim($issueOwnerId);
617 $sql =
"select previous_task_owner from cutrack where track_id = $issueId";
618 $sth = db_query($sql, $dbh);
620 $errors[] =
"Select query failed.";
622 $results = db_fetch_all($sth);
623 $previousTaskOwner = $results ===
false ?
"" : trim($results[0][
"previous_task_owner"]);
626 if (isset($record)) {
627 if ($forceEmail || (strtolower($nextTaskOwner) != strtolower($previousTaskOwner))) {
628 $transactionSQLs[] =
"update cutrack set previous_task_owner = '$nextTaskOwner' where track_id = $issueId";
630 if ($mode ==
"new" && (strtolower($nextTaskOwner) != strtolower($issueOwnerId))) {
631 if ($forceEmail || (strtolower($nextTaskOwner) != strtolower($staffId))) {
632 $text =
"Job has been created. You are the first task owner.";
635 $results = CreateToLine($dbh, array($nextTaskOwner));
636 if ($results[
"status"] !==
"000") {
637 $errors[] = $results[
"error"];
639 $to = $results[
"data"];
640 }
catch(exception $e) {
641 $errors[] =
"createToLine query failed.";
645 }
else if ($mode ==
"rearranged" || $mode ==
"promoted") {
646 $text =
"Tasks were rearranged. $nextTaskOwner is the next task owner, not $previousTaskOwner.";
649 $results = CreateToLine($dbh, array($nextTaskOwner, $previousTaskOwner));
650 if ($results[
"status"] !==
"000") {
651 $errors[] = $results[
"error"];
653 $to = $results[
"data"];
654 }
catch(exception $e) {
655 $errors[] =
"createToLine query failed.";
658 }
else if ($mode ==
"reactivated") {
659 $text =
"A task has been reactivated. $nextTaskOwner is the next task owner, not $previousTaskOwner.";
662 $results = CreateToLine($dbh, array($nextTaskOwner, $previousTaskOwner));
663 if ($results[
"status"] !==
"000") {
664 $errors[] = $results[
"error"];
666 $to = $results[
"data"];
667 }
catch(exception $e) {
668 $errors[] =
"createToLine query failed.";
674 if ($forceEmail || (strtolower($nextTaskOwner) != strtolower($staffId))) {
675 $text =
"The task assigned to $previousTaskOwner has been $mode. " . ($reassigned ?
"The next task was reassigned to you." :
"You are the next active task owner.");
678 $results = CreateToLine($dbh, array($nextTaskOwner));
679 if ($results[
"status"] !==
"000") {
680 $errors[] = $results[
"error"];
682 $to = $results[
"data"];
683 }
catch(exception $e) {
684 $errors[] =
"createToLine query failed.";
690 if (count($errors) == 0 && isset($to)) {
691 $subject =
"You are the next task owner.";
692 $taskEmails[] = array(
"to" => $to,
"subject" => $subject,
"text" => $text,
"issue" => $issue,
"title" => $title,
"description" => $description,
693 "issueId" => $issueId,
"taskId" => $taskId,
"completeNotes" => $completeNotes);
699 if ($forceEmail || ($mode !=
"created" && strtolower($issueOwnerId) != strtolower($staffId))) {
701 $subject =
"Your job is nearly complete.";
704 $results = CreateToLine($dbh, array($issueOwnerId));
705 if ($results[
"status"] !==
"000") {
706 $errors[] = $results[
"error"];
708 $to = $results[
"data"];
709 }
catch(exception $e) {
710 $errors[] =
"createToLine query failed.";
715 if (count($errors) == 0 && isset($to)) {
716 $text =
"Tasks have been completed for your job. Please review and complete this job.";
717 $issueEmails[] = array(
"to" => $to,
"subject" => $subject,
"text" => $text,
"issue" => $issue,
"status" => $status,
"issueId" => $issueId,
"completeNotes" => $completeNotes);