Odyssey
sCalendarNotify.i
1 <?php
2 /**
3  * function GetProgramName()
4  * Gets the name of the program for the banking calendar.
5  */
6 function GetProgramName() {
7  return "aBankingCalendar";
8 }
9 
10 /**
11  * function GetEmailRole()
12  *
13  * @return the email role to use for sending the email(s).
14  */
15 function GetEmailRole() {
16  return "hcunotice";
17 }
18 
19 /**
20  * function GetCaringDate($currentYear)
21  *
22  * @param $currentYear -- the current year in YYYY format.
23  * @return the date in the current year that we start notifying the Credit Union if they haven't yet set up next year's calendar.
24  */
25 function GetCaringDate($currentYear) {
26  return "$currentYear-11-01";
27 }
28 
29 /**
30  * function GetDeleteAfterYears()
31  *
32  * @return how many years pass before removing a calendar record from the database.
33  */
34 function GetDeleteAfterYears() {
35  return 2;
36 }
37 
38 /**
39  * function GetCuEmailBody($cu, $nextYear)
40  *
41  * @param $cu -- the credit union
42  * @param $nextYear -- the next year in YYYY format.
43  * @return an email body to send to each credit union employee in the email role.
44  */
45 function GetCuEmailBody($cu, $nextYear) {
46  return "<html>
47  <body>
48  <p>
49  <img src=\"https://s3.amazonaws.com/cucommon/homecu/images/HomeCULogo_Color_Small_Trans.png\"/>
50  </p>
51  <br/>
52  <p>
53  Dear HomeCU Digital Banking Customer,
54  </p>
55  <p>
56  You are receiving this message as part of the HomeCU Admin Portal for Digital Banking.
57  HomeCU has added the ability to set Credit Union dates in the Banking Calendar.
58  $cu has not yet entered dates for the next year ($nextYear).
59  Please enter these dates at your earliest convenience by going to Administrative Maintenance > Banking Calendar in the Admin Portal.
60  This automated reminder will stop when dates are added to the calendar.
61  </p>
62  <p>
63  Thank you!
64  <br/>
65  Your HomeCU Support Team
66  </p>
67  </body>
68  </html>";
69 
70 }
71 
72 /**
73  * function RetrieveCUEmailList($dbh, $thisYear, $nextYear)
74  * Gets a list of CUs that (possibly) need to be notified to update their calendars for next year.
75  * This is a list of CU and the last notify date that fit the criteria:
76  * - Credit Union has the current year set up
77  * - Credit Union is active
78  * - Banking calendar program is active
79  * - Credit Union does not have the next year set up
80  *
81  * @param $dbh -- the database connection
82  * @param $thisYear -- the current year (YYYY)
83  * @param $nextYear -- the next year (YYYY)
84  *
85  * @return $status -- "000" if successful, nonzero otherwise
86  * @return $error -- "" if successful, nonempty otherwise
87  * @return $data.lastNotifyList -- a list of CUs and last notified date.
88  */
89 function RetrieveCUEmailList($dbh, $thisYear, $nextYear) {
90  $SYS_TYPE_CLOSED = 64; // From cu_top. In the future, this should be a function in cu_flagconst.i.
91  try {
92  if (!isset($thisYear) || trim($thisYear) == "") {
93  throw new exception ("This year is not valid.", 3);
94  }
95  if (!isset($nextYear) || trim($nextYear) == "") {
96  throw new exception ("Next year is not valid.", 4);
97  }
98  $thisYear = intval($thisYear);
99  $nextYear = intval($nextYear);
100  if ($thisYear < 1000 || $thisYear > 9999) {
101  throw new exception ("This year is not valid.", 5);
102  }
103  if ($nextYear < 1000 || $nextYear > 9999) {
104  throw new exception ("Next year is not valid.", 6);
105  }
106 
107  $sql = "select a.cu, c.dates::json->>'lastnotify' as lastnotify
108  from cuadmin a
109  inner join cu_calendar d on a.cu = d.cu and d.year = '$thisYear' and d.dates::json->>0 is not null " . // Credit Union has the current year set up
110  "inner join cuinfo i on lower(a.cu) = i.user_name and (i.system_options & $SYS_TYPE_CLOSED) = 0 " . // Credit Union is active
111  "left join cu_calendar c on a.cu = c.cu and c.year = '$nextYear'
112  left join cuadminexclude e on a.cu = e.cu and e.program = '" . GetProgramName() . "'
113  where e.cu is null " . // Exclude records where the banking calendar program is not used.
114  "and (c.cu is null or c.dates::json->>0 is null) " . // Only records where there is no calendar record for next year or the dates aren't already set up.
115  "order by a.cu";
116 
117  $sth = db_query($sql, $dbh);
118  if (!$sth) {
119  throw new exception ("Query is not valid.", 1);
120  }
121  $lastNotifyList = db_fetch_all($sth);
122  $lastNotifyList = $lastNotifyList === false ? array() : $lastNotifyList;
123 
124  $sql = "select cu, email from cuadmnotify where role = '" . GetEmailRole() . "' order by cu";
125  $sth = db_query($sql, $dbh);
126  if (!$sth) {
127  throw new exception ("Query is not valid.", 2);
128  }
129  $emailList = db_fetch_all($sth);
130  $emailMap = array();
131  if ($emailList !== false) {
132  foreach($emailList as $emailRow) {
133  $cuEmailList = isset($emailRow["email"]) ? trim($emailRow["email"]) : "";
134  if ($cuEmailList != "") {
135  $emailMap[trim($emailRow["cu"])] = $cuEmailList;
136  }
137  }
138  }
139 
140  foreach($lastNotifyList as $i => $lastNotifyRow) {
141  $cu = trim($lastNotifyRow["cu"]);
142  if (HCU_array_key_exists($cu, $emailMap)) {
143  $lastNotifyList[$i]["emails"] = $emailMap[$cu];
144  } else {
145  $lastNotifyList[$i]["emails"] = "";
146  }
147  }
148 
149  $returnArray = array("status" => "000", "error" => "", "data" => array("lastNotifyList" => $lastNotifyList));
150  } catch (exception $e) {
151  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage());
152  }
153  return $returnArray;
154 }
155 
156 /**
157  * function VerifyOpts($commandOptions)
158  * This function verify the command line options
159  *
160  * @param $commandOptions -- this is an array of options from the commandline.
161  *
162  * @return $status -- "000" if successful, nonzero otherwise
163  * @return $error -- "" if successful, nonempty otherwise
164  * @return $opts.date -- if set, then it is the date set after being verified. If not set, then it is the current date.
165  * @return $opts.dryrun -- if set, then it is true. If not set, then it is false.
166  */
167 function VerifyOpts($commandOptions) {
168  $date = null;
169  try {
170 
171  if ($commandOptions === false) {
172  throw new exception ("getopt is invalid.", -1);
173  }
174 
175  if (HCU_array_key_exists("help", $commandOptions)) {
176  throw new exception ("Help is set.", -2);
177  }
178 
179  if (HCU_array_key_exists("d", $commandOptions)) {
180  $date = $commandOptions["d"];
181  if (!isset($date) || trim($date) == "") {
182  throw new exception ("Date is invalid.", 3);
183  }
184  $date = DateTime::createFromFormat("Y-m-d|", $commandOptions["d"]);
185  if ($date === false) {
186  throw new exception ("Date is invalid.", 4);
187  }
188  } else {
189  $date = new DateTime();
190  }
191  $date = $date->format("Y-m-d");
192 
193  $dryrun = HCU_array_key_exists("dryrun", $commandOptions);
194 
195  $returnArray = array("status" => "000", "error" => "", "opts" => array("date" => $date, "dryrun" => $dryrun));
196  } catch (exception $e) {
197  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage());
198  }
199  return $returnArray;
200 }
201 
202 /**
203  * function DoICare($currentDate)
204  * A function showing if I care or not. (I care if the current date is the same or after a particular date.)
205  *
206  * @param $currentDate -- the current date (YYYY-mm-dd).
207  *
208  * @return $status -- "000" if successful, nonzero otherwise
209  * @return $error -- "" if successful, nonempty otherwise
210  * @return $doICare -- true if the current date is the same or after a particular date.
211  */
212 function DoICare($currentDate) {
213  $doI = false;
214  try {
215  if (!isset($currentDate) || trim($currentDate) == "") {
216  throw new exception ("Please enter the current date.", 1);
217  }
218  $currentDate = DateTime::createFromFormat("Y-m-d|", $currentDate);
219  if ($currentDate === false) {
220  throw new exception ("Current date is invalid.", 2);
221  }
222 
223  $currentYear = $currentDate->format("Y");
224  $caringDate = DateTime::createFromFormat("Y-m-d|", GetCaringDate($currentYear));
225 
226  $doI = $currentDate >= $caringDate;
227 
228  $returnArray = array("status" => "000", "error" => "", "doICare" => $doI);
229  } catch (exception $e) {
230  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage());
231  }
232  return $returnArray;
233 }
234 
235 /**
236  * function ShouldISendEmail($currentDate, $lastNotifiedDate)
237  * The main logic function for determining when to send email.
238  *
239  * @param $currentDate -- the current date. This is a string in the form of "YYYY-mm-dd".
240  * @param $lastNotifiedDate -- the last time that the Credit Union received a reminder email. This is also in form "YYYY-mm-dd".
241  * The last notified date can be null or empty string. In this case, the Credit Union has not received a reminder email.
242  *
243  * @return $status -- "000" if successful, nonzero otherwise
244  * @return $error -- "" if successful, nonempty otherwise
245  * @return $shouldISendEmail -- true if there has been no email sent ($lastNotifiedDate is null) or $currentDate is past the date where it should be notified.
246  * During the month of November, send an email if the last notified date is two weeks ago (or more)
247  * During the month of December, send an email if the last notified date is one week ago (or more)
248  */
249 function ShouldISendEmail($currentDate, $lastNotifiedDate) {
250  $shouldI = false;
251  try {
252  if (!isset($currentDate) || trim($currentDate) == "") {
253  throw new exception ("Please enter the current date.", 1);
254  }
255  $currentDate = DateTime::createFromFormat("Y-m-d|", $currentDate);
256  if ($currentDate === false) {
257  throw new exception ("Current date is invalid.", 2);
258  }
259 
260  $currentYear = $currentDate->format("Y");
261 
262  if (!isset($lastNotifiedDate) || trim($lastNotifiedDate) == "") {
263  $shouldI = true; // No email has been previous sent. So send one.
264  } else {
265  $lastNotifiedDate = DateTime::createFromFormat("Y-m-d|", $lastNotifiedDate);
266 
267  if ($lastNotifiedDate === false) {
268  throw new exception ("Last notified date is invalid.", 3);
269  }
270 
271  $currentU = intval($currentDate->format("U"));
272  $lastU = intval($lastNotifiedDate->format("U"));
273  $dayDiff = ($currentU - $lastU) / 86400;
274 
275  if ($dayDiff < 0) {
276  throw new exception ("Last notified date cannot be after the current date.", 4);
277  }
278 
279  /***************
280  Logic: In November, notify every two weeks. In December, notify every week.
281  ****************/
282 
283  $novemberOne = DateTime::createFromFormat("Y-m-d|", "$currentYear-11-01");
284  $decemberOne = DateTime::createFromFormat("Y-m-d|", "$currentYear-12-01");
285 
286  if ($currentDate >= $decemberOne) {
287  $shouldI = $dayDiff >= 7;
288  } else if ($currentDate >= $novemberOne) {
289  $shouldI = $dayDiff >= 14;
290  }
291  }
292 
293  $returnArray = array("status" => "000", "error" => "", "shouldISendEmail" => $shouldI);
294  } catch (exception $e) {
295  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage());
296  }
297  return $returnArray;
298 }
299 
300 /**
301  * function SendCuEmail($cu, $emails, $nextYear)
302  * Sends an email to notify the CU
303  *
304  * @param $cu -- the credit union
305  * @param $emails -- what emails to send it to?
306  * @param $nextYear -- the next year (YYYY)
307  *
308  * @return $status -- "000" if successful, nonzero otherwise
309  * @return $error -- "" if successful, nonempty otherwise
310  */
311 function SendCuEmail($cu, $emails, $nextYear) {
312  try {
313  if (!isset($cu) || trim($cu) == "") {
314  throw new exception ("Cu is required.", 1);
315  }
316 
317  if (!isset($nextYear)) {
318  throw new exception ("Next Year is required.", 2);
319  }
320  $nextYear = intval($nextYear);
321 
322  if ($nextYear < 1000 || $nextYear > 9999) {
323  throw new exception ("Next Year is invalid.", 3);
324  }
325  $body = GetCuEmailBody($cu, $nextYear);
326  $subject = "Please set up your calendar";
327 
328  // Send email
329  $notify = new ErrorMail;
330  $notify->mailto = $emails;
331  $notify->subject = $subject;
332  $notify->htmlMsgbody = $body;
333  $notify->callingfunction = __FUNCTION__;
334  $notify->file = __FILE__;
335  $notify->cu = $cu;
336  $notify->SendMail();
337 
338  $returnArray = array("status" => "000", "error" => "");
339  } catch (exception $e) {
340  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage());
341  }
342  return $returnArray;
343 }
344 
345 /**
346  * UpdateCuCalendar($dbh, $cu, $nextYear)
347  * This function updates the database after email(s) are sent to the Credit Union.
348  * The lastnotify attribute is set inside the dates column.
349  *
350  * @param $dbh -- the database connection
351  * @param $cu -- the credit union
352  * @param $nextYear -- the next year (YYYY)
353  * @param $currentDate -- the current date (YYYY-mm-dd)
354  *
355  * @return $status -- "000" if successful, nonzero otherwise
356  * @return $error -- "" if successful, nonempty otherwise
357  */
358 function UpdateCuCalendar($dbh, $cu, $nextYear, $currentDate) {
359  try {
360  if (!isset($cu) || trim($cu) == "") {
361  throw new exception ("Cu is required.", 1);
362  }
363 
364  if (!isset($nextYear)) {
365  throw new exception ("Next Year is required.", 2);
366  }
367 
368  if (!isset($currentDate) || trim($currentDate) == "") {
369  throw new exception ("Date is required.", 6);
370  }
371 
372  $nextYear = intval($nextYear);
373 
374  if ($nextYear < 1000 || $nextYear > 9999) {
375  throw new exception ("Next Year is invalid.", 3);
376  }
377 
378  $currentDate = DateTime::createFromFormat("Y-m-d|", $currentDate);
379  if ($currentDate === false) {
380  throw new exception ("Current date is invalid.", 7);
381  }
382 
383  $currentDate = $currentDate->format("Y-m-d");
384 
385  $dates = HCU_JsonEncode(array("lastnotify" => $currentDate));
386 
387  $sql = "select 'FOUND' from cu_calendar where cu = '" . prep_save($cu, 10) . "' and year = '" . prep_save($nextYear, 4) . "'";
388  $sth = db_query($sql, $dbh);
389  if (!$sth) {
390  throw new exception ("Query failed.", 4);
391  }
392 
393  if (db_num_rows($sth) > 0) {
394  $sql = "update cu_calendar set dates = '" . prep_save($dates) . "' where cu = '" . prep_save($cu, 10) . "' and year = '" . prep_save($nextYear, 4) . "'";
395  } else {
396  $sql = "insert into cu_calendar (cu, year, dates) values ('" . prep_save($cu, 10) . "', '" . prep_save($nextYear, 4) . "', '" . prep_save($dates) . "')";
397  }
398  $sth = db_query($sql, $dbh);
399  if (!$sth) {
400  throw new exception ("Query failed.", 5);
401  }
402 
403  $returnArray = array("status" => "000", "error" => "");
404  } catch (exception $e) {
405  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage());
406  }
407  return $returnArray;
408 }
409 
410 /**
411  * function RemoveOldCalendars($dbh, $currentYear)
412  * Remove old calendar records from the database
413  *
414  * @param $dbh -- the database connection
415  * @param $currentYear -- the current year (YYYY)
416  *
417  * @return $status -- "000" if successful, nonzero otherwise
418  * @return $error -- "" if successful, nonempty otherwise
419  */
420 function RemoveOldCalendars($dbh, $currentYear) {
421  try {
422  if (!isset($currentYear) || trim($currentYear) == "") {
423  throw new exception ("Current year is not valid.", 3);
424  }
425  $currentYear = intval($currentYear);
426  if ($currentYear < 1000 || $currentYear > 9999) {
427  throw new exception ("Current year is not valid.", 5);
428  }
429 
430  $removalYear = $currentYear - GetDeleteAfterYears();
431 
432  $sql = "delete from cu_calendar where year <= '" . prep_save($removalYear, 4) . "'";
433  $sth = db_query($sql, $dbh);
434  if (!$sth) {
435  throw new exception ("Delete failed.", 6);
436  }
437 
438  $returnArray = array("status" => "000", "error" => "");
439  } catch (exception $e) {
440  $returnArray = array("status" => $e->getCode(), "error" => $e->getMessage());
441  }
442  return $returnArray;
443 }