Subversion Repositories PEEPS

Rev

Rev 19 | Rev 28 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#!/usr/bin/perl
2
 
3
# Redirect error messages to a log of my choosing. (it's annoying to filter for errors in the shared env)
4
#my $error_log_path = $ENV{SERVER_NAME} eq "volunteers.rollercon.com" ? "/home3/rollerco/logs/" : "/tmp/";
5
#close STDERR;
6
#open STDERR, '>>', $error_log_path.'vorc_error.log' or warn "Failed to open redirected logfile ($0): $!";
7
#warn "Redirecting errors to ${error_log_path}vorc_error.log";
8
 
9
use strict;
10
use PEEPS;
11
use CGI qw/param header start_html url/;
12
use CGI::Cookie;
22 - 13
use tableViewer qw/ notInArray /;
2 - 14
our $h = HTML::Tiny->new( mode => 'html' );
15
my $dbh = getRCDBH ();
4 - 16
$ENV{HTTPS} = 'ON' if $ENV{SERVER_NAME} =~ /^peeps/;
2 - 17
$dbh->{PrintError} = 1;
18
 
19
my $cookie_string = authenticate (1) || die;
20
my ($EML, $PWD, $LVL) = split /&/, $cookie_string;
21
my $user = $ORCUSER;
22
#my $activated = $ORCUSER->{access};
23
 
24
 
25
use DateTime;
26
#use DateTime::Format::Strptime;
27
my $dt = DateTime->today;
28
$dt =~ s/T00\:00\:00$//;
29
 
22 - 30
#$user->{policy} = isPersonCovered ($user->{id});
31
#if ($user->{policy}) {
32
#  my $daysremaining = remainingPolicyDays ($user->{id}, $user->{policy});
33
#
34
#  ERROR ("Not Eligible for Renewal",
35
#         "You're currently covered by policy $user->{policy}, which has $daysremaining days remaining. You can only renew within the last 90 days of your current policy.",
36
#         "Viewed Purchase Confirmation page but wasn't eligible to renew.");
37
#}
2 - 38
 
39
## Check for DRAFT payments for the user, get the last one...
40
 
22 - 41
my $order_id = WebDB::trim scalar param ("order_id") // ERROR ("No OrderID Provided", "No OrderID provided to confirmation page.", "No OrderID provided to confirmation page.");
2 - 42
 
22 - 43
#my $checkout = $dbh->selectrow_hashref ("SELECT * FROM wftdi_peeps.square_order where status = ? and person_id = ? order by created desc limit 1", undef, "DRAFT", $user->{id});
44
my $checkout = $dbh->selectrow_hashref ("SELECT * FROM wftdi_peeps.square_order where status = ? and order_id = ? order by created desc limit 1", undef, "DRAFT", $order_id);
45
 
2 - 46
if (!$checkout->{square_id}) {
22 - 47
  ERROR ("Open Order Not Found",
48
         "There are no open orders or pending payments found with OrderID: $order_id",
49
         "Viewed Purchase Confirmation page with OrderID [$order_id] but didn't have any open payments.");
2 - 50
}
51
 
22 - 52
# Once we're here, we've found an order_id in DRAFT status. We should make sure it belongs to the user (or their league)
53
 
54
if ($checkout->{person_id} ne $user->{person_id} and notInArray ($checkout->{organization_id}, isLeagueAdmin ($user->{person_id}))) {
55
  # invalid OrderID for user.
56
  ERROR ("Invalid User for Order",
57
         "The provided OrderID does not belong to you or for a league that you have Administrative access.",
58
         "Attempted to view Confirmation page with someone else's OrderID [$order_id]");
59
}
60
 
2 - 61
use REST::Client;
62
use JSON;
63
use Data::Dumper;
64
 
65
my $client = REST::Client->new();
66
 
67
my $headers = {
68
  "Authorization" => 'Bearer '.getSetting ("SQUARE_AUTH_TOKEN"),
69
  "Content-Type" => "application/json",
70
};
71
 
72
$client->setHost (getSetting ("SQUARE_API_HOST"));
73
 
74
$client->GET(
75
  '/v2/orders/'.$checkout->{order_id},
76
  $headers
77
);
78
my $response = from_json($client->responseContent());
79
#warn Dumper($response);
80
 
81
 
82
if ($response->{order}->{state} eq "DRAFT") {
22 - 83
  # Checkout isn't complete yet...
84
  ERROR ("Open Payment",
85
         "It looks like you haven't completed check out at Square yet. ".$h->a ({href=>$checkout->{url}}, "[Click Here]")." to complete your payment.",
86
         "Viewed Confirmation page with an open payment.");
2 - 87
} elsif ($response->{order}->{state} eq "OPEN") {
88
  # Checkout completed...
89
  # create start and end dates based on the user's timezone
90
  my $user_tz = $response->{order}->{tenders}->[0]->{note} || 'America/Chicago';
91
#  warn $user_tz;
92
  # Parse the UTC timestamp and set its timezone to 'UTC'
93
  use DateTime::Format::Strptime qw( );
94
  my $format = DateTime::Format::Strptime->new(
95
    pattern   => '%Y-%m-%dT%H:%M:%SZ',
96
    strict    => 1,
97
    time_zone => "UTC",
98
#    on_error  => "croak",
99
  );
100
  my $dt = $format->parse_datetime( $response->{order}->{tenders}->[0]->{created_at} );
101
  $dt->set_time_zone( $user_tz );
102
  my $adjusted_created_at = $dt->strftime( '%Y-%m-%d %H:%M:%S' );
103
 
104
  # "Fix" UTC format for MySQL
105
  $response->{order}->{tenders}->[0]->{created_at} =~ s/T/ /;
106
  $response->{order}->{tenders}->[0]->{created_at} =~ s/Z$//;
107
 
108
  # Update the square order status and add the exact time of payment.
109
  $dbh->do ("update square_order set status = ?, payment_id = ?, payment_time = ? where square_id = ?", undef,
110
    "PAID",
111
    $response->{order}->{tenders}->[0]->{id},
112
    $response->{order}->{tenders}->[0]->{created_at},
113
    $checkout->{square_id}
114
  );
115
 
22 - 116
  # Here's where it gets complicated.  We have to figure out what kind of policy it is to know how to update the coverage records...
117
 
118
  if ($checkout->{policy_id} eq "1") { # Personal Accident Medical
119
    my $policy_id = isPersonCovered ($user->{id});
120
    if ($policy_id) {
121
      # extend existing coverage
122
      $dbh->do ("update coverage set end = date_add(end, INTERVAL 1 YEAR) where id = ?", undef, $policy_id);
123
    } else {
124
      # insert new coverage
125
      my ($new_policy_id) = $dbh->selectrow_array ("select max(id)+1 from coverage");
126
      $dbh->do ("insert into coverage (id, person_id, policy_id, policy_name, fee, created, start, end, active) values (?, ?, ?, ?, ?, ?, date(?), date_add(date(?), INTERVAL 1 YEAR), ?)", undef,
127
        $new_policy_id,
128
        $user->{id},
129
        $checkout->{policy_id},
130
        $response->{order}->{line_items}->[0]->{name},
131
        $response->{order}->{tenders}->[0]->{amount_money}->{amount} / 100,
132
        $response->{order}->{tenders}->[0]->{created_at},
133
        $adjusted_created_at,
134
        $adjusted_created_at,
135
        1
136
      );
137
      $dbh->do ("replace into full_person select * from v_person where id = ?", undef, $user->{id});
138
      $policy_id = isPersonCovered ($user->{id});
139
    }
140
 
141
    if ($policy_id) {
142
      my $daysremaining = remainingPolicyDays ($user->{id}, $policy_id);
143
      communicateConfirmation ({ to => $user->{email},
144
                                 policy => $response->{order}->{line_items}->[0]->{name},
145
                                 message => "You're currently covered by policy $policy_id, which has $daysremaining days remaining." });
146
    } else {
147
      ERROR ("Unknown Error Confirming Purchase",
148
             "It seemed like you successfully purchased insurance, but then there was an issue updating our records. You should probably email peeps\@wftdi.com and tell them to investigate.",
149
             "ERROR: Checkout complete, but PEEPS coverage failed to update.");
150
    }
151
  } elsif ($checkout->{policy_id} eq "2") { # League General Liability
152
    my $policy_id = isLeagueCovered ($checkout->{organization_id});
153
    if ($policy_id) {
154
      # extend existing coverage
155
      $dbh->do ("update org_coverage set end = date_add(end, INTERVAL 1 YEAR) where id = ?", undef, $policy_id);
156
    } else {
157
      # insert new coverage
158
      my ($new_policy_id) = $dbh->selectrow_array ("select max(id)+1 from org_coverage");
159
      $dbh->do ("insert into org_coverage (id, organization_id, policy_id, policy_name, fee, created, start, end, active) values (?, ?, ?, ?, ?, ?, date(?), date_add(date(?), INTERVAL 1 YEAR), ?)", undef,
160
        $new_policy_id,
161
        $checkout->{organization_id},
162
        $checkout->{policy_id},
163
        $response->{order}->{line_items}->[0]->{name},
164
        $response->{order}->{tenders}->[0]->{amount_money}->{amount} / 100,
165
        $response->{order}->{tenders}->[0]->{created_at},
166
        $adjusted_created_at,
167
        $adjusted_created_at,
168
        1
169
      );
170
      $policy_id = isLeagueCovered ($user->{id});
171
    }
172
 
173
    if ($policy_id) {
174
      my $daysremaining = remainingOrgPolicyDays ($checkout->{organization_id}, $policy_id);
175
      communicateConfirmation ({ to => $user->{email},
176
                                 policy => $response->{order}->{line_items}->[0]->{name},
177
                                 message => "Your league is currently covered by policy $policy_id, which has $daysremaining days remaining.",
178
                                 orgid => $checkout->{organization_id} });
179
    } else {
180
      ERROR ("Unknown Error Confirming Purchase",
181
             "It seemed like you successfully purchased insurance, but then there was an issue updating our records. You should probably email peeps\@wftdi.com and tell them to investigate.",
182
             "ERROR: Checkout complete, but PEEPS coverage failed to update.");
183
    }
184
  } elsif ($checkout->{policy_id} eq "3") { # League Alcohol Liability
185
    my $policy_id = isLeagueCovered ($checkout->{organization_id}, undef, "WFTDA League Alcohol Liability");
186
    if ($policy_id) {
187
      # extend existing coverage
188
      $dbh->do ("update org_coverage set end = date_add(end, INTERVAL 1 YEAR) where id = ?", undef, $policy_id);
189
    } else {
190
      # insert new coverage
191
      my ($new_policy_id) = $dbh->selectrow_array ("select max(id)+1 from org_coverage");
192
      $dbh->do ("insert into org_coverage (id, organization_id, policy_id, policy_name, fee, created, start, end, active) values (?, ?, ?, ?, ?, ?, date(?), MAKEDATE(YEAR(CURDATE()), 365), ?)", undef,
193
        $new_policy_id,
194
        $checkout->{organization_id},
195
        $checkout->{policy_id},
196
        $response->{order}->{line_items}->[0]->{name},
197
        $response->{order}->{tenders}->[0]->{amount_money}->{amount} / 100,
198
        $response->{order}->{tenders}->[0]->{created_at},
199
        $adjusted_created_at,
200
        1
201
      );
202
      $policy_id = isLeagueCovered ($user->{id});
203
    }
204
 
205
    if ($policy_id) {
206
      my $daysremaining = remainingOrgPolicyDays ($checkout->{organization_id}, $policy_id);
207
      communicateConfirmation ({ to => $user->{email},
208
                                 policy => $response->{order}->{line_items}->[0]->{name},
209
                                 message => "Your league is currently covered by policy $policy_id, which has $daysremaining days remaining.",
210
                                 orgid => $checkout->{organization_id} });
211
    } else {
212
      ERROR ("Unknown Error Confirming Purchase",
213
             "It seemed like you successfully purchased insurance, but then there was an issue updating our records. You should probably email peeps\@wftdi.com and tell them to investigate.",
214
             "ERROR: Checkout complete, but PEEPS coverage failed to update.");
215
    }
216
  } elsif ($checkout->{policy_id} eq "4") { # RollerCon
2 - 217
    # insert new coverage
218
    my ($new_policy_id) = $dbh->selectrow_array ("select max(id)+1 from coverage");
22 - 219
    $dbh->do ("insert into coverage (id, person_id, policy_id, policy_name, fee, created, start, end, active) values (?, ?, ?, ?, ?, ?, ?, ?, ?)", undef,
220
      $new_policy_id,
2 - 221
      $user->{id},
22 - 222
      $checkout->{policy_id},
2 - 223
      $response->{order}->{line_items}->[0]->{name},
224
      $response->{order}->{tenders}->[0]->{amount_money}->{amount} / 100,
225
      $response->{order}->{tenders}->[0]->{created_at},
22 - 226
      "2026-07-09",
227
      "2026-07-11",
2 - 228
      1
229
    );
22 - 230
    my $policy_id = $new_policy_id;
231
 
2 - 232
    if ($policy_id) {
22 - 233
      communicateConfirmation ({ to => $user->{email},
234
                                 policy => $response->{order}->{line_items}->[0]->{name},
235
                                 message => "You are covered for RollerCon on-site event skating activities by policy $policy_id, July 9-11, 2026." });
2 - 236
    } else {
22 - 237
      ERROR ("Unknown Error Confirming Purchase",
238
             "It seemed like you successfully purchased insurance, but then there was an issue updating our records. You should probably email peeps\@wftdi.com and tell them to investigate.",
239
             "ERROR: Checkout complete, but PEEPS coverage failed to update.");
2 - 240
    }
241
  }
242
} else {
22 - 243
  # Something weird happened.
244
  ERROR ();
2 - 245
}
246
 
5 - 247
 
19 - 248
sub emailConfirmation {
249
  my $target = shift // return;
250
  my $subject = "WFTDA Insurance Coverage Confirmation";
251
  my $message = $h->p ($h->br ()).
252
                $h->p ({ style => "text-align: center;" }, $h->img ({ alt => "", src => "https://peeps.gadell.org/images/wftda-insurance-logo.svg", style => "width: 300px; height: 97px;"})).
253
                $h->p (
254
                         $h->br (),
255
                         ["Greetings", $h->br (), $h->br ()],
256
                         "Thank you for enrolling in WFTDA Insurance! This email confirms your coverage is in effect for 12 months, please retain it for your records. For additional resources, forms and information, please visit ".$h->a ({ href => "https://wftdi.com" }, "wftdi.com").'.  ',
257
                         $h->br (),
258
                         "WFTDA Insurance",
259
                         $h->br ()
260
                       );
261
 
262
  use PEEPSMailer;
22 - 263
  EmailUser ($target, $subject, $message);
264
}
19 - 265
 
22 - 266
 
267
sub communicateConfirmation {
268
  my $parameter = shift // return;
269
  my $target = $parameter->{to};
270
  my $policy = $parameter->{policy};
271
  my $message = $parameter->{message};
272
  my $orgid = $parameter->{orgid} // "";
19 - 273
 
22 - 274
  my @league_admins = $orgid ? map { $_->[0] } @{ $dbh->selectall_arrayref ("select distinct email from person left join role on person.id = role.person_id where role = ? and member_org_id = ? and person.id <> ?", undef, "League Admin", $orgid, $user->{person_id}) } : ();
275
 
276
  my $subject = $policy." Coverage Confirmation";
277
 
278
  print header (-cookie=>CGI::Cookie->new(-name=>'PEEPSAUTH',-value=>"$cookie_string"));
279
  printRCHeader("Insurance Purchase Confirmation");
280
  print $h->close ("table");
281
 
282
  print $h->h2 ($subject);
283
  print $h->div ({ style=>"max-width:450px;" }, "You have successfully purchased $policy coverage.", $message, "&nbsp;");
284
  print $h->button ({onclick => "window.location.href='/';"}, "Home");
285
  print $h->close ("BODY", "HTML");
286
 
287
  my $message = $h->p ($h->br ()).
288
                $h->p ({ style => "text-align: center;" }, $h->img ({ alt => "", src => "https://peeps.gadell.org/images/wftda-insurance-logo.svg", style => "width: 300px; height: 97px;"})).
289
                $h->p (
290
                         $h->br (),
291
                         ["Greetings", $h->br (), $h->br ()],
292
                         ["You have successfully purchased $policy coverage.", $message, $h->br (), $h->br ()],
293
                         "Thank you for enrolling in WFTDA Insurance! This email confirms your coverage is in effect, please retain it for your records. For additional resources, forms and information, please visit ".$h->a ({ href => "https://wftdi.com" }, "wftdi.com").'. &nbsp;',
294
                         $h->br (),
295
                         "WFTDA Insurance",
296
                         $h->br ()
297
                       );
298
 
299
  if ($orgid) {
300
    orglogit ($user->{id}, $orgid, "Successfully purchased $policy coverage");
301
    logit ($user->{id}, "Successfully purchased $policy coverage for ".getLeagueName ($orgid).".");
302
  } else {
303
    logit ($user->{id}, "Successfully purchased $policy coverage.")
304
  }
305
 
306
  use PEEPSMailer;
307
  if (scalar @league_admins) {
308
    EmailMultipleUsers ({ to => [$target], cc => \@league_admins, subject => $subject, body => $message });
309
  } else {
310
    EmailUser ($target, $subject, $message);
311
  }
312
 
313
  exit;
19 - 314
}
22 - 315
 
316
 
317
sub ERROR {
318
  my $header = shift // "Unknown Error";
319
  my $text   = shift // "Something unexpectedly bad happened.";
320
  my $logmsg = shift // "Unknown Error happened while viewing the Confirmation page";
321
 
322
  print header (-cookie=>CGI::Cookie->new(-name=>'PEEPSAUTH',-value=>"$cookie_string"));
323
  printRCHeader("Confirmation");
324
  print $h->close ("table");
325
  print $h->h2 ($header);
326
  print $h->div ({ style=>"max-width:450px;" }, $text, "&nbsp;");
327
  print $h->button ({onclick => "window.location.href='/';"}, "Home");
328
  print $h->close ("BODY", "HTML");
329
  logit ($user->{id}, $logmsg);
330
 
331
  exit;
332
}