Subversion Repositories PEEPS

Rev

Rev 22 | 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");
28 - 126
      $dbh->do ("insert into coverage (id, person_id, policy_id, policy_name, fee, square_id, created, start, end, active) values (?, ?, ?, ?, ?, ?, ?, date(?), date_add(date(?), INTERVAL 1 YEAR), ?)", undef,
22 - 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,
28 - 132
        $response->{order}->{tenders}->[0]->{id},
22 - 133
        $response->{order}->{tenders}->[0]->{created_at},
134
        $adjusted_created_at,
135
        $adjusted_created_at,
136
        1
137
      );
138
      $dbh->do ("replace into full_person select * from v_person where id = ?", undef, $user->{id});
139
      $policy_id = isPersonCovered ($user->{id});
140
    }
141
 
142
    if ($policy_id) {
143
      my $daysremaining = remainingPolicyDays ($user->{id}, $policy_id);
144
      communicateConfirmation ({ to => $user->{email},
145
                                 policy => $response->{order}->{line_items}->[0]->{name},
146
                                 message => "You're currently covered by policy $policy_id, which has $daysremaining days remaining." });
147
    } else {
148
      ERROR ("Unknown Error Confirming Purchase",
149
             "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.",
150
             "ERROR: Checkout complete, but PEEPS coverage failed to update.");
151
    }
152
  } elsif ($checkout->{policy_id} eq "2") { # League General Liability
153
    my $policy_id = isLeagueCovered ($checkout->{organization_id});
154
    if ($policy_id) {
155
      # extend existing coverage
156
      $dbh->do ("update org_coverage set end = date_add(end, INTERVAL 1 YEAR) where id = ?", undef, $policy_id);
157
    } else {
158
      # insert new coverage
159
      my ($new_policy_id) = $dbh->selectrow_array ("select max(id)+1 from org_coverage");
28 - 160
      $dbh->do ("insert into org_coverage (id, organization_id, policy_id, policy_name, fee, square_id, created, start, end, active) values (?, ?, ?, ?, ?, ?, ?, date(?), date_add(date(?), INTERVAL 1 YEAR), ?)", undef,
22 - 161
        $new_policy_id,
162
        $checkout->{organization_id},
163
        $checkout->{policy_id},
164
        $response->{order}->{line_items}->[0]->{name},
165
        $response->{order}->{tenders}->[0]->{amount_money}->{amount} / 100,
28 - 166
        $response->{order}->{tenders}->[0]->{id},
22 - 167
        $response->{order}->{tenders}->[0]->{created_at},
168
        $adjusted_created_at,
169
        $adjusted_created_at,
170
        1
171
      );
172
      $policy_id = isLeagueCovered ($user->{id});
173
    }
174
 
175
    if ($policy_id) {
176
      my $daysremaining = remainingOrgPolicyDays ($checkout->{organization_id}, $policy_id);
177
      communicateConfirmation ({ to => $user->{email},
178
                                 policy => $response->{order}->{line_items}->[0]->{name},
179
                                 message => "Your league is currently covered by policy $policy_id, which has $daysremaining days remaining.",
180
                                 orgid => $checkout->{organization_id} });
181
    } else {
182
      ERROR ("Unknown Error Confirming Purchase",
183
             "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.",
184
             "ERROR: Checkout complete, but PEEPS coverage failed to update.");
185
    }
186
  } elsif ($checkout->{policy_id} eq "3") { # League Alcohol Liability
187
    my $policy_id = isLeagueCovered ($checkout->{organization_id}, undef, "WFTDA League Alcohol Liability");
188
    if ($policy_id) {
189
      # extend existing coverage
190
      $dbh->do ("update org_coverage set end = date_add(end, INTERVAL 1 YEAR) where id = ?", undef, $policy_id);
191
    } else {
192
      # insert new coverage
193
      my ($new_policy_id) = $dbh->selectrow_array ("select max(id)+1 from org_coverage");
28 - 194
      $dbh->do ("insert into org_coverage (id, organization_id, policy_id, policy_name, fee, square_id, created, start, end, active) values (?, ?, ?, ?, ?, ?, ?, date(?), MAKEDATE(YEAR(CURDATE()), 365), ?)", undef,
22 - 195
        $new_policy_id,
196
        $checkout->{organization_id},
197
        $checkout->{policy_id},
198
        $response->{order}->{line_items}->[0]->{name},
199
        $response->{order}->{tenders}->[0]->{amount_money}->{amount} / 100,
28 - 200
        $response->{order}->{tenders}->[0]->{id},
22 - 201
        $response->{order}->{tenders}->[0]->{created_at},
202
        $adjusted_created_at,
203
        1
204
      );
205
      $policy_id = isLeagueCovered ($user->{id});
206
    }
207
 
208
    if ($policy_id) {
209
      my $daysremaining = remainingOrgPolicyDays ($checkout->{organization_id}, $policy_id);
210
      communicateConfirmation ({ to => $user->{email},
211
                                 policy => $response->{order}->{line_items}->[0]->{name},
212
                                 message => "Your league is currently covered by policy $policy_id, which has $daysremaining days remaining.",
213
                                 orgid => $checkout->{organization_id} });
214
    } else {
215
      ERROR ("Unknown Error Confirming Purchase",
216
             "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.",
217
             "ERROR: Checkout complete, but PEEPS coverage failed to update.");
218
    }
219
  } elsif ($checkout->{policy_id} eq "4") { # RollerCon
2 - 220
    # insert new coverage
221
    my ($new_policy_id) = $dbh->selectrow_array ("select max(id)+1 from coverage");
28 - 222
    $dbh->do ("insert into coverage (id, person_id, policy_id, policy_name, fee, square_id, created, start, end, active) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", undef,
22 - 223
      $new_policy_id,
2 - 224
      $user->{id},
22 - 225
      $checkout->{policy_id},
2 - 226
      $response->{order}->{line_items}->[0]->{name},
227
      $response->{order}->{tenders}->[0]->{amount_money}->{amount} / 100,
28 - 228
      $response->{order}->{tenders}->[0]->{id},
2 - 229
      $response->{order}->{tenders}->[0]->{created_at},
22 - 230
      "2026-07-09",
231
      "2026-07-11",
2 - 232
      1
233
    );
22 - 234
    my $policy_id = $new_policy_id;
235
 
2 - 236
    if ($policy_id) {
22 - 237
      communicateConfirmation ({ to => $user->{email},
238
                                 policy => $response->{order}->{line_items}->[0]->{name},
239
                                 message => "You are covered for RollerCon on-site event skating activities by policy $policy_id, July 9-11, 2026." });
2 - 240
    } else {
22 - 241
      ERROR ("Unknown Error Confirming Purchase",
242
             "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.",
243
             "ERROR: Checkout complete, but PEEPS coverage failed to update.");
2 - 244
    }
245
  }
246
} else {
22 - 247
  # Something weird happened.
248
  ERROR ();
2 - 249
}
250
 
5 - 251
 
19 - 252
sub emailConfirmation {
253
  my $target = shift // return;
254
  my $subject = "WFTDA Insurance Coverage Confirmation";
255
  my $message = $h->p ($h->br ()).
256
                $h->p ({ style => "text-align: center;" }, $h->img ({ alt => "", src => "https://peeps.gadell.org/images/wftda-insurance-logo.svg", style => "width: 300px; height: 97px;"})).
257
                $h->p (
258
                         $h->br (),
259
                         ["Greetings", $h->br (), $h->br ()],
260
                         "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").'.  ',
261
                         $h->br (),
262
                         "WFTDA Insurance",
263
                         $h->br ()
264
                       );
265
 
266
  use PEEPSMailer;
22 - 267
  EmailUser ($target, $subject, $message);
268
}
19 - 269
 
22 - 270
 
271
sub communicateConfirmation {
272
  my $parameter = shift // return;
273
  my $target = $parameter->{to};
274
  my $policy = $parameter->{policy};
275
  my $message = $parameter->{message};
276
  my $orgid = $parameter->{orgid} // "";
19 - 277
 
22 - 278
  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}) } : ();
279
 
280
  my $subject = $policy." Coverage Confirmation";
281
 
282
  print header (-cookie=>CGI::Cookie->new(-name=>'PEEPSAUTH',-value=>"$cookie_string"));
283
  printRCHeader("Insurance Purchase Confirmation");
284
  print $h->close ("table");
285
 
286
  print $h->h2 ($subject);
287
  print $h->div ({ style=>"max-width:450px;" }, "You have successfully purchased $policy coverage.", $message, "&nbsp;");
288
  print $h->button ({onclick => "window.location.href='/';"}, "Home");
289
  print $h->close ("BODY", "HTML");
290
 
291
  my $message = $h->p ($h->br ()).
292
                $h->p ({ style => "text-align: center;" }, $h->img ({ alt => "", src => "https://peeps.gadell.org/images/wftda-insurance-logo.svg", style => "width: 300px; height: 97px;"})).
293
                $h->p (
294
                         $h->br (),
295
                         ["Greetings", $h->br (), $h->br ()],
296
                         ["You have successfully purchased $policy coverage.", $message, $h->br (), $h->br ()],
297
                         "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;',
298
                         $h->br (),
299
                         "WFTDA Insurance",
300
                         $h->br ()
301
                       );
302
 
303
  if ($orgid) {
304
    orglogit ($user->{id}, $orgid, "Successfully purchased $policy coverage");
305
    logit ($user->{id}, "Successfully purchased $policy coverage for ".getLeagueName ($orgid).".");
306
  } else {
307
    logit ($user->{id}, "Successfully purchased $policy coverage.")
308
  }
309
 
310
  use PEEPSMailer;
311
  if (scalar @league_admins) {
312
    EmailMultipleUsers ({ to => [$target], cc => \@league_admins, subject => $subject, body => $message });
313
  } else {
314
    EmailUser ($target, $subject, $message);
315
  }
316
 
317
  exit;
19 - 318
}
22 - 319
 
320
 
321
sub ERROR {
322
  my $header = shift // "Unknown Error";
323
  my $text   = shift // "Something unexpectedly bad happened.";
324
  my $logmsg = shift // "Unknown Error happened while viewing the Confirmation page";
325
 
326
  print header (-cookie=>CGI::Cookie->new(-name=>'PEEPSAUTH',-value=>"$cookie_string"));
327
  printRCHeader("Confirmation");
328
  print $h->close ("table");
329
  print $h->h2 ($header);
330
  print $h->div ({ style=>"max-width:450px;" }, $text, "&nbsp;");
331
  print $h->button ({onclick => "window.location.href='/';"}, "Home");
332
  print $h->close ("BODY", "HTML");
333
  logit ($user->{id}, $logmsg);
334
 
335
  exit;
336
}