update signutare
[CPE_learningsite] / CPE / CPE.App / CPE.App.Web / Controllers / IndexController.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Configuration;
4 using System.Linq;
5 using System.Net;
6 using System.Net.Mail;
7 using System.Text.RegularExpressions;
8 using System.Web;
9 using System.Web.Mvc;
10 using System.Xml;
11 using CPE.App.Web.Code;
12 using CPE.App.Web.Connect;
13 using CPE.App.Web.Helpers;
14 using CPE.App.Web.Models;
15
16 namespace CPE.App.Web.Controllers {
17     public class IndexController : BaseController {
18         public enum MeetingType {
19             Adobe,
20             Elucidat
21         }
22
23         private bool IsLocal() {
24             var address = Request.UserHostAddress;
25             if (address.StartsWith("192.") || address.StartsWith("10.211") || address == "::1")
26                 return true;
27             return false;
28         }
29
30         private bool IsAdmin(string login, string password)
31         {
32             return Database.Users.Any(t => t.IsAdmin && t.Login == login && t.Password == password);
33         }
34
35         private bool IsAdmin(string password)
36         {
37             return Database.Users.Any(t => t.IsAdmin && t.Password == password);
38         }
39
40         // GET: Index
41         [HttpGet]
42         public ActionResult Index(int? year) {
43             if(Request.Cookies["allowed"] == null && !IsLocal())
44                 return Redirect("http://www.cpeonline.com/webcasts");
45
46             //string systemPassword = ConfigurationManager.AppSettings["password"];
47             if (Request.Cookies["allowed"] != null && !IsAdmin(Request.Cookies["allowed"].Value))
48             {
49                 return Redirect("http://www.cpeonline.com/webcasts");
50             }
51
52             DateTime now = DateTime.UtcNow;
53
54             if(!year.HasValue) {
55                 year = DateTime.Now.Year;
56             }
57
58             List<MeetingSessionsDataResult> meetingSessions = Database.MeetingSessionsData()
59                                                                       .Where(msd => msd.EndDate.HasValue && msd.EndDate <= now && (msd.StartDate >= new DateTime(year.Value, 1, 1) && msd.StartDate < new DateTime(year.Value + 1, 1, 1)))
60                                                                       .OrderByDescending(msd => msd.StartDate)
61                                                                       .ToList();
62             return View(meetingSessions);
63         }
64
65         [HttpGet]
66         public ActionResult SessionDetails(int meetingSessionKey) {
67             Extensions.LogServiceCall("[IndexController][SessionDetails]", string.Format("Beginning: meetingSessionKey = {0}", meetingSessionKey));
68
69             var meetingSession = Database.MeetingSessions.Single(ms => ms.MeetingSessionKey == meetingSessionKey);
70             var result = new AdobeSessionViewModel {
71                 MeetingSession = meetingSession,
72                 ParticipantSessionsDataResult = Database.ParticipantSessionsData(meetingSessionKey)
73                                                         .ToList(),
74                 GetSessionReportResult = Database.GetSessionReport(meetingSessionKey)
75                                                  .ToList(),
76                 WebcastPurchaseDataResult = Database.WebcastPurchaseData(meetingSession.SCO_ID, meetingSessionKey)
77                                                     //.Where(w => w.Sco == meetingSession.SCO_ID && w.mDate.DayOfYear >= meetingSession.StartDate.DayOfYear)
78                                                     .ToList()
79             };
80             //if (result.ParticipantSessionsDataResult.Count == 0) {
81             adobe.GetAdobeTransactions(meetingSession, Database);
82             Database.SubmitChanges();
83
84             result = new AdobeSessionViewModel {
85                 MeetingSession = meetingSession,
86                 ParticipantSessionsDataResult = Database.ParticipantSessionsData(meetingSessionKey)
87                                                         .ToList(),
88                 GetSessionReportResult = Database.GetSessionReport(meetingSessionKey)
89                                                  .ToList(),
90                 WebcastPurchaseDataResult = Database.WebcastPurchaseData(meetingSession.SCO_ID, meetingSessionKey)
91                                                     .ToList()
92             };
93             //}
94             return View(result);
95         }
96
97         [HttpGet]
98         public ActionResult RetrieveSession(int meetingSessionKey) {
99             Extensions.LogServiceCall("[IndexController][RetrieveSession]", string.Format("Beginning: meetingSessionKey = {0}", meetingSessionKey));
100
101             var meetingSession = Database.MeetingSessions.Single(ms => ms.MeetingSessionKey == meetingSessionKey);
102             if(Database.ParticipantSessionsData(meetingSessionKey)
103                        .ToList()
104                        .Count == 0) {
105                 adobe.GetAdobeTransactions(meetingSession, Database);
106                 Database.SubmitChanges();
107             }
108
109             return RedirectToAction("SessionDetails", new {meetingSessionKey});
110         }
111
112
113         [HttpGet]
114         public ActionResult TestElucidat()
115         {
116             var baseUrl = "https://api-launchpad.elucidat.com/";
117             var urlFull = "health/ping";
118             Extensions.LogServiceCall("[IndexController][TestElucidat]", $"Beginning: {baseUrl}{urlFull}");
119
120             ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Ssl3;
121             ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Tls;
122             ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Tls11;
123             // Add TLS 1.2
124             ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;
125
126             var client = new WebClient { BaseAddress = baseUrl };
127             client.Headers.Clear();
128             client.Headers["Accept"] = "application/json";
129             var response = client.DownloadString(urlFull);
130             Extensions.LogServiceCall("[IndexController][TestElucidat]", $"Response: {response}");
131
132
133             return Content(response);
134         }
135
136         [HttpGet]
137         public ActionResult Login(string meetingUrl, string d = null, string c = null) {
138             meetingUrl = meetingUrl?.Trim();
139             d = d?.Trim();
140             c = c?.Trim();
141
142
143             Extensions.LogServiceCall("[IndexController][Login|Get]", string.Format("meetingUrl = {0} d (PurchaseDate) = {1} c (TicketFromUrl) = {2}", meetingUrl, d, c));
144
145             //Webcast and Rebroadcast access test course
146             if(meetingUrl.ToLower() == "test_room") {
147                 var baseUrl = ConfigurationManager.AppSettings["Connect.Url"];
148                 var testUrl = ConfigurationManager.AppSettings["Connect.AccessTestMeetingUrl"];
149                 var accessTestUrl = baseUrl + '/' + testUrl;
150                 return Redirect(accessTestUrl);
151             }
152             var meetingType = meetingUrl.Contains('-') ? MeetingType.Elucidat : MeetingType.Adobe;
153
154             if(meetingType == MeetingType.Elucidat) {
155                 var releaseCode = meetingUrl.Substring(meetingUrl.IndexOf('-') + 1);
156                 Extensions.LogServiceCall("[IndexController][Login|Get]", string.Format("meetingUrl = {0} releaseCode = {1}", meetingUrl, releaseCode));
157
158                 ReleaseModel release = ElucidatMeetingConnection.GetReleaseDetails(releaseCode);
159                 string projectName = null;
160                 if(release != null && release.Project != null) {
161                     projectName = release.Project.Name;
162                 }
163                 return View("elucidatlogin", new ElucidatCourseView {Name = projectName, Url = meetingUrl, PurchaseDate = d, TicketFromUrl = c, Message = null});
164             }
165             //if (ConfigurationManager.AppSettings["CPE.AdobeTicketingOn"].ToLower() == "true")
166             //{
167             //    //The flag is unnecessary now since we're keeping magic passcode access available. Non-ticketed link is now magicTicket 
168
169             // }
170
171             XmlDocument meeting = AdobeMeetingConnection.getAdobeMeeting(meetingUrl);
172             if(meeting != null) {
173                 if(meeting.SelectSingleNode("//sco")
174                           .Attributes["icon"].Value != "archive") {
175                     return View("login", new AdobeMeetingView {
176                         Name = meeting.SelectSingleNode("//sco/name")
177                                       .InnerText,
178                         HasPassCode = meeting.SelectSingleNode("//meeting-passcode") != null,
179                         PurchaseDate = d,
180                         TicketFromUrl = c
181                     });
182                 }
183             }
184             return null;
185         }
186
187         [HttpPost]
188         public ActionResult Login(string meetingUrl, string firstname, string lastname, string email, string passcode,
189                                   string courseName, string ticket = null, string ticketFromUrl = null, string purchaseDate = null,
190                                   string message = null) {
191             meetingUrl = meetingUrl?.Trim();
192             firstname = firstname?.Trim();
193             lastname = lastname?.Trim();
194             email = email?.Trim();
195             passcode = passcode?.Trim();
196             courseName = courseName?.Trim();
197             ticket = ticket?.Trim();
198             ticketFromUrl = ticketFromUrl?.Trim();
199             purchaseDate = purchaseDate?.Trim();
200             message = message?.Trim();
201
202             Extensions.LogServiceCall("[IndexController][Login|Post]", string.Format("email = {0} meetingUrl = {1} ticket = {2} ticketFromUrl = {3} purchaseDate = {4} firstname = {5} lastname = {6} passcode = {7} courseName = {8}", email, meetingUrl, ticket, ticketFromUrl, purchaseDate, firstname, lastname, passcode, courseName));
203
204             var magicTicketLogin = string.IsNullOrEmpty(ticketFromUrl);
205             var meetingType = meetingUrl.Contains('-') ? MeetingType.Elucidat : MeetingType.Adobe;
206
207             if(meetingType.Equals(MeetingType.Elucidat)) {
208                 var releaseCode = meetingUrl.Substring(meetingUrl.IndexOf('-') + 1);
209
210                 if(!ticket.Equals(ticketFromUrl) ||
211                    !VerifyAccess.VerifyTicket(ticket, meetingUrl, firstname, lastname, email, purchaseDate)) {
212                     return View("elucidatlogin", new ElucidatCourseView {
213                         Url = meetingUrl,
214                         Name = courseName,
215                         PurchaseDate = purchaseDate,
216                         TicketFromUrl = ticketFromUrl,
217                         Message =
218                             "Invalid Login. Please re-enter your information. This information MUST match the information in the email you received with your passcode. If you continue to have trouble, please contact Customer Service at 1-800-544-1114 or email us at sswebcast@cpeincmail.com"
219                     }
220                         );
221                 }
222
223                 PurchasedCourse course =
224                     Database.PurchasedCourses.SingleOrDefault(pc => pc.Ticket == ticket && pc.ContentUrl == meetingUrl);
225
226                 if(course == null) {
227                     //no purchase record yet, look for release details in database
228                     CourseDetail release = Database.CourseDetails.SingleOrDefault(r => r.ReleaseCode == releaseCode);
229                     if(release == null) {
230                         //course isn't in db yet, get details form api
231                         ReleaseModel releaseCourse = ElucidatMeetingConnection.GetReleaseDetails(releaseCode);
232                         var done = ReleaseHelper.GetReleaseDescriptionDetails(releaseCourse);
233                         if(done) {
234                             release = Database.CourseDetails.SingleOrDefault(cd => cd.ReleaseCode == releaseCode);
235                         }
236                     }
237                     string formattedPdate = purchaseDate.Substring(0, 4) + '-' + purchaseDate.Substring(4, 2) + '-' +
238                                             purchaseDate.Substring(6, 2);
239                     DateTime pDate = Convert.ToDateTime(formattedPdate);
240                     course = new PurchasedCourse {
241                         ContentUrl = meetingUrl,
242                         CourseName = release.Name,
243                         FirstName = firstname,
244                         LastName = lastname,
245                         Email = email,
246                         Ticket = ticket,
247                         PurchaseDate = pDate,
248                         Presenter = release.Presenter,
249                         Fos = release.Fos,
250                         Credits = release.Credits,
251                         CertificateDate = null,
252                         FailedAttempts = 0,
253                         isManualCertificate = false
254                     };
255                     Database.PurchasedCourses.InsertOnSubmit(course);
256                 }
257
258                 Database.SubmitChanges();
259
260                 //verify access (PurchaseDate<1yrold) and access not revoked
261                 if(!VerifyAccess.AccessBlocked(course) && VerifyAccess.IsValid(course)) {
262                     string courseUrl = ElucidatMeetingConnection.GetLaunchLink(releaseCode, firstname, lastname, email);
263
264                     Regex linkParser = new Regex(@"\b(?:https?://)\S+\b",
265                                                  RegexOptions.Compiled | RegexOptions.IgnoreCase);
266                     string rawString = courseUrl;
267                     string goodUrl = linkParser.Match(rawString)
268                                                .Value;
269
270                     return Redirect(goodUrl);
271                 }
272
273                 //Access is expired or Revoked
274                 return View("elucidatlogin", new ElucidatCourseView {
275                     Url = meetingUrl,
276                     Name = courseName,
277                     PurchaseDate = purchaseDate,
278                     TicketFromUrl = ticketFromUrl,
279                     Message =
280                         "Access to this course is no longer available. Please contact Customer Service at 1-800-544-1114 or email us at sswebcast@cpeincmail.com"
281                 }
282                     );
283             }
284             if((ConfigurationManager.AppSettings["CPE.AdobeTicketingOn"].ToLower() == "true") & !magicTicketLogin) {
285                 if(passcode == null) {
286                     passcode = (DateTime.UtcNow.ToString("MMM") + DateTime.UtcNow.Day.ToString("00")).ToLower();
287                 }
288                 if(!ticketFromUrl.Equals(ticket)) {
289                     return RedirectToAction("Login");
290                 }
291                 if(!VerifyAccess.VerifyTicket(ticket, meetingUrl, firstname, lastname, email, purchaseDate)) {
292                     return RedirectToAction("Login");
293                 }
294
295                 //if valid continue on to existing way of doing things
296             }
297
298             string connectUrl = ConfigurationManager.AppSettings["Connect.Url"];
299             int accountId = int.Parse(ConfigurationManager.AppSettings["Connect.AccountId"]);
300             string password = Guid.NewGuid()
301                                   .ToString()
302                                   .Replace("{", "")
303                                   .Replace("}", "")
304                                   .Substring(0, 8);
305             Session admin = AdobeMeetingConnection.GetAdobeAdminSession();
306             var request = new Request(admin, "principal-list");
307             request.Parameters.Add("filter-type", "guest");
308             request.Parameters.Add("filter-type", "user");
309             request.Parameters.Add("filter-login", email);
310             if(request.Execute() && request.Status == Status.OK) {
311                 Extensions.LogServiceCall("[IndexController][Login|Post]", string.Format("email = [{0}] request.XmlResults.InnerXml = {1}", email, request.XmlResults.InnerXml));
312
313                 int principalId;
314                 if(request.XmlResults.SelectSingleNode("//principal") == null) {
315                     principalId = Connect.Login.CreateGuest(admin, email, password, email, firstname, lastname);
316                 } else {
317                     principalId = int.Parse(request.XmlResults.SelectSingleNode("//principal")
318                                                    .Attributes["principal-id"].Value);
319                     email = request.XmlResults.SelectSingleNode("//principal/login")
320                                    .InnerText;
321                     if(request.XmlResults.SelectSingleNode("//principal")
322                               .Attributes["type"].Value == "user")
323                         return RedirectToAction("Login");
324                 }
325                 if(principalId < 1)
326                     return RedirectToAction("Login");
327
328
329                 Connect.Login.ResetPassword(admin, principalId, password);
330                 Session session = Connect.Login.UserLogin(email, password, connectUrl, accountId);
331
332                 var meetingView = new AdobeMeetingView {
333                     Name = AdobeMeetingConnection.getAdobeMeetingName(meetingUrl),
334                     PrincipalId = principalId,
335                     Url =
336                         string.Format("{0}/{1}?session={2}&launcher=false", connectUrl, meetingUrl,
337                                       session.SessionKey) + (passcode == null
338                                                                  ? ""
339                                                                  : "&meeting-passcode=" + passcode)
340                 };
341
342
343                 Participant participant = Database.Participants.SingleOrDefault(p => p.Principal_ID == principalId);
344                 if(participant == null) {
345                     participant = new Participant {
346                         Principal_ID = principalId,
347                         FirstName = firstname,
348                         LastName = lastname,
349                         Email = email
350                     };
351                     Database.Participants.InsertOnSubmit(participant);
352                 }
353
354                 Database.SubmitChanges();
355
356                 var certificateId = 0;
357                 int scoId = AdobeMeetingConnection.getAdobeMeetingSco(meetingUrl);
358
359                 if(!magicTicketLogin) {
360                     string formattedPdate = purchaseDate.Substring(0, 4) + '-' +
361                                             purchaseDate.Substring(4, 2) +
362                                             '-' + purchaseDate.Substring(6, 2);
363                     DateTime pDate = Convert.ToDateTime(formattedPdate);
364
365                     ParticipantPurchase purchase =
366                         Database.ParticipantPurchases.SingleOrDefault(
367                                                                       p =>
368                                                                       p.PrincipalID == principalId & p.Ticket == ticketFromUrl &
369                                                                       p.MeetingSco == scoId);
370                     if(purchase == null) {
371                         purchase = new ParticipantPurchase {
372                             FirstName = firstname,
373                             LastName = lastname,
374                             Email = email,
375                             PrincipalID = principalId,
376                             MeetingName = meetingView.Name,
377                             MeetingDate = DateTime.UtcNow,
378                             MeetingSco = scoId,
379                             Ticket = ticketFromUrl,
380                             PurchaseDate = pDate,
381                             EarnedCertificate = false,
382                             Credits = 0
383                         };
384                         Database.ParticipantPurchases.InsertOnSubmit(purchase);
385
386                         Extensions.LogServiceCall("[IndexController][Login|Post]", string.Format("email = {0} scoId = {1} principalId = {2} MeetingDate = {3}", email, scoId, principalId, purchase.MeetingDate));
387                     }
388
389                     Database.SubmitChanges();
390                     certificateId = purchase.Purchase_ID;
391                 }
392                 meetingView.CertificateId = certificateId;
393                 meetingView.ScoId = scoId;
394
395                 Extensions.LogServiceCall("[IndexController][Login|Post]", string.Format("email = {0} scoId = {1} certificateId = {2} principalId = {3}", email, scoId, certificateId, principalId));
396
397                 var idCookie = new HttpCookie("id") {
398                     Value = principalId.ToString(),
399                     Expires = DateTime.UtcNow.AddDays(1)
400                 };
401                 Response.Cookies.Add(idCookie);
402
403
404                 request = new Request(admin, "principal-update");
405                 request.Parameters.Add("first-name", firstname);
406                 request.Parameters.Add("last-name", lastname);
407                 request.Parameters.Add("principal-id", principalId.ToString());
408                 request.Execute();
409
410                 return View("meeting", meetingView);
411             }
412             return RedirectToAction("Login");
413         }
414
415         [HttpGet]
416         public ActionResult Admin() {
417             return View();
418         }
419
420         public ActionResult Email() {
421             var email = new MailMessage {
422                 To = {
423                     "sophia@sophicsystems.com"
424                 },
425                 Subject = "[CPE] Email Test",
426                 Body = "Email test has been received.",
427                 From = new MailAddress("support@intesolv.com")
428             };
429             var server = new SmtpClient("localhost");
430             server.Send(email);
431
432             return Redirect("/");
433         }
434         public ActionResult SendCerificateEmail(string email, string url, string key)
435         {
436             if (key != "q1w2e3") return Content("Bad key");
437             var course = Database.PurchasedCourses
438                 .Where(c => c.Email == email && c.ContentUrl == url)
439                 .OrderByDescending(c => c.CertificateDate).FirstOrDefault();
440
441             var done = SendEmailHelperWeb.SendCertificateEmail(course);
442
443             var s = url.Split('-');
444             var courseName = Database.CourseDetails
445                 .FirstOrDefault(c => c.ReleaseCode == s[1])?.Name;
446
447             Utilities.LogWrapper.Info("[TinCanHelper][HandleStatement] {0} cert sent email={1} courseName={2}", DateTime.UtcNow.ToString("yyyyMMdd_HHmmss"), email, courseName);
448
449             return Content("Certificate send successfully");
450         }
451
452         [HttpPost]
453         public ActionResult Admin(string login, string passcode) {
454             login = login?.Trim();
455             passcode = passcode?.Trim();
456
457            // string systemPassword = ConfigurationManager.AppSettings["password"];
458             if(IsAdmin(login, passcode)) {
459                 var reportingCookie = new HttpCookie("allowed") {
460                     Value = passcode,
461                     Expires = DateTime.UtcNow.AddDays(1)
462                 };
463                 Response.Cookies.Add(reportingCookie);
464             }
465             return Redirect("/");
466         }
467
468         [HttpGet]
469         public ActionResult CourseDetails(string releaseCode) {
470             releaseCode = releaseCode?.Trim();
471
472             var course = Database.CourseDetails.Single(cd => cd.ReleaseCode == releaseCode);
473             var result = new ElucidatCourseViewModel {
474                 CourseDetail = course,
475                 PurchasedCoursesDataResult = Database.PurchasedCoursesData(releaseCode)
476                                                      .OrderByDescending(pc => pc.PurchaseDate)
477                                                      .ToList()
478             };
479
480             return View(result);
481         }
482
483         [HttpGet]
484         public ActionResult Elucidat() {
485             if(Request.Cookies["allowed"] == null && !IsLocal())
486                 return Redirect("http://www.cpeonline.com/webcasts");
487 //            string systemPassword = ConfigurationManager.AppSettings["password"];
488             if(Request.Cookies["allowed"] != null && (!IsAdmin(Request.Cookies["allowed"].Value)))
489                 return Redirect("http://www.cpeonline.com/webcasts");
490             DateTime now = DateTime.UtcNow;
491
492             List<CourseListingsDataResult> courseListings = Database.CourseListingsData()
493                                                                     .Where(cl => cl.CreatedDate != null)
494                                                                     .OrderBy(cl => cl.Name)
495                                                                     .ToList();
496             return View(courseListings);
497         }
498
499         [HttpGet]
500         public ActionResult Wufoo(int id) {
501             //https://cpeonline.wufoo.com/forms/cpe-webcast-evaluation/def/Field1=Jason&Field2=Wigginton&Field3-1=7&Field3-2=2&Field3=2012&Field4=1234&Field5=J.%20McIntosh&Field6=ConnectPro&Field7=Test101&Field8=Test%20topic
502             ParticipantTracking pt = Database.ParticipantTrackings.OrderByDescending(p => p.StartDate)
503                                              .FirstOrDefault(p => p.Principal_ID == id);
504             string url = ConfigurationManager.AppSettings["Wufoo.Survey1.1"];
505             if(pt == null) {
506                 Extensions.LogServiceCall("[IndexController][Wufoo]", string.Format("id = {0} url = {1}", id, url));
507                 return Redirect(url);
508             }
509
510             MeetingDetail d = pt.MeetingParticipantSession.MeetingSession.Meeting.MeetingDetail;
511             DateTime date = Extensions.GetLocalDateTime(DateTime.UtcNow);
512             url += string.Format(ConfigurationManager.AppSettings["Wufoo.Survey1.2"], pt.Participant.FirstName, pt.Participant.LastName, date.Month.ToString("00"), date.Day.ToString("00"), date.Year, d.TopicID, d.TopicName, d.Instructor, d.Location, d.CourseCode);
513             Extensions.LogServiceCall("[IndexController][Wufoo]", string.Format("id = {0} url = {1}", id, url));
514             return Redirect(url);
515         }
516
517         public ActionResult Survey() {
518             int id = 0;
519             string url = ConfigurationManager.AppSettings["Wufoo.Survey1.1"];
520             string cookie = Request.Cookies["id"] == null
521                                 ? "0"
522                                 : Request.Cookies["id"].Value;
523             int.TryParse(cookie, out id);
524             if(id == 0) {
525                 return Redirect(url);
526             }
527             Extensions.LogServiceCall("[IndexController][Survey]", string.Format("id = {0}", id));
528             ParticipantTracking pt = Database.ParticipantTrackings.OrderByDescending(p => p.StartDate)
529                                              .FirstOrDefault(p => p.Principal_ID == id);
530             if(pt == null)
531                 return Redirect(url);
532
533             MeetingDetail d = pt.MeetingParticipantSession.MeetingSession.Meeting.MeetingDetail;
534             DateTime date = Extensions.GetLocalDateTime(DateTime.UtcNow);
535             url += string.Format(ConfigurationManager.AppSettings["Wufoo.Survey1.2"], pt.Participant.FirstName, pt.Participant.LastName, date.Month.ToString("00"), date.Day.ToString("00"), date.Year, d.TopicID, d.TopicName, d.Instructor, d.Location, d.CourseCode);
536             return Redirect(url);
537         }
538
539         [HttpGet]
540         public ActionResult AllowReporting(Guid? id) {
541             //if (id.HasValue && id == Guid.Parse("")) {
542             //    var reportingCookie = new HttpCookie("reporting") {Value = "1", Expires = DateTime.MaxValue};
543             //    Response.Cookies.Add(reportingCookie);
544             //    return Redirect("/");
545             //}
546             //return Redirect("http://www.cpeonline.com/webcasts");
547             return RedirectToAction("Admin");
548         }
549
550         [HttpGet]
551         public ActionResult GetTicket(string courseUrl) {
552             courseUrl = courseUrl?.Trim();
553
554             TicketModel ticketInfo = new TicketModel {
555                 CourseUrl = courseUrl
556             };
557             //return the view as a partial view that opens in a pretty jquery ui form (dialog) within the page, not a new page
558             return PartialView(ticketInfo);
559         }
560
561         [HttpPost]
562         public string GetTicket(string firstname, string lastname, string email, string contenturl) {
563             //NOT IMPLEMENTED. possible solution to "magic ticket" request for ondemand course, since a global entry would not make sense
564             //generate hashed ticket link for a specific user for an ondemand course. This will bypass cpe's commerce site and allow cpe customer service to generate an access link
565
566             firstname = firstname?.Trim();
567             lastname = lastname?.Trim();
568             email = email?.Trim();
569             contenturl = contenturl?.Trim();
570
571             string purchasedate = DateTime.Now.ToString("yyyyMMdd");
572             var ticket = VerifyAccess.generateTicket(contenturl, firstname, lastname, email, purchasedate);
573
574             var link = "http://cpeonlineselfstudywebcasts.com/" + contenturl + "?d=" + purchasedate + "&c=" + ticket;
575             return link;
576         }
577
578         // GET: CertificateReport
579         [HttpGet]
580         public ActionResult CertificateReport() {
581             List<CertficateDataResult> earnedCertificates = Database.CertficateData()
582                                                                     .OrderBy(ec => ec.Course)
583                                                                     .ToList();
584             return View(earnedCertificates);
585         }
586
587         public ActionResult WebcastCertificateReport() {
588             List<WebcastCertficateDataResult> earnedCertificates = Database.WebcastCertficateData()
589                                                                            .OrderBy(ec => ec.MeetingName)
590                                                                            .ToList();
591             return View(earnedCertificates);
592         }
593
594         //public string SendCert(int meeting_sco, int certificate_id, int principal_id)
595         //{
596         //    //TODO (webcast) make outcome dictionary to return pass, fail, ineligible, or wonky:contact cust serv
597         //    string _fail = "fail";
598         //    if (certificate_id > 0)
599         //    {
600         //        ParticipantPurchase purchase =
601         //            Database.ParticipantPurchases.FirstOrDefault(p => p.Purchase_ID == certificate_id && p.PrincipalID == principal_id);
602
603         //        if (purchase == null)
604         //        {
605         //            //if the certificate_id is >0 then purchase would only be null because of record being deleted while user was in the meeting, or the principalID got mis-matched
606         //            return _fail; // TODO probably return wonky, contact cust service message
607         //        }
608
609         //        if (!purchase.EarnedCertificate)
610         //        {
611         //            var meeting = Database.MeetingSessions.FirstOrDefault(
612         //                    m =>
613         //                        m.Recording == false && m.SCO_ID == meeting_sco &&
614         //                        m.StartDate.DayOfYear == DateTime.UtcNow.DayOfYear);
615         //            if (meeting == null)
616         //            {
617         //                return _fail;//TODO return wonky
618         //            }
619
620         //            int meetingSessionKey = meeting.MeetingSessionKey;
621
622         //            MeetingParticipantSession meetingParticipantSession =
623         //                Database.MeetingParticipantSessions.FirstOrDefault(
624         //                    m => m.MeetingSessionKey == meetingSessionKey && m.ParticipantKey == principal_id);
625         //            if (meetingParticipantSession == null)
626         //            {
627         //                return _fail;//TODO return wonky
628         //            }
629
630         //            List<ParticipantSessionsDataResult> participantSessionsDataResult =
631         //                Database.ParticipantSessionsData(meetingSessionKey)
632         //                    .ToList();
633
634         //            var participantSessionsData =
635         //                participantSessionsDataResult.OrderBy(p => p.MeetingParticipantSessionKey)
636         //                    .FirstOrDefault(
637         //                        p =>
638         //                            p.MeetingParticipantSessionKey ==
639         //                            meetingParticipantSession.MeetingParticipantSessionKey);
640
641         //            if (participantSessionsData == null)
642         //            {
643         //                return _fail;//TODO is this a return wonky? it means they weren't tracked
644         //            }
645
646         //            MeetingSessionsDataResult meetingSession = Database.MeetingSessionsData().FirstOrDefault(m => m.MeetingSessionKey == meetingSessionKey);
647         //            if (meetingSession == null)
648         //            {
649         //                return _fail;//TODO return wonky
650         //            }
651
652         //            var courseLength = meetingSession.ActualSessionTime.GetValueOrDefault(); //in minutes
653         //            double courseCredits = courseLength / 50.0; //1 credit per 50 minutes
654         //            List<double> maxCourseCredits = ConfigurationManager.AppSettings["MaxCourseCreditList"].Split(';').Select(s => double.Parse(s)).ToList(); //max credits cut list
655         //            int mx = maxCourseCredits.BinarySearch(courseCredits); //find appropriate max for this course
656         //            double maxCredits = maxCourseCredits[mx >= 0 ? mx : ~mx - 1];//...by rounding down
657         //            double realCredits = participantSessionsData.SessionCredit == null ? 0 : (double)participantSessionsData.SessionCredit.Value; //users credits per adobe
658         //            purchase.Credits = Math.Min(maxCredits, realCredits); //user awarded no more than max possible credits for the course
659
660         //            MeetingDetail meetingDetail =
661         //                Database.MeetingDetails.FirstOrDefault(m => m.MeetingKey == purchase.MeetingSco);
662
663         //            purchase.Presenter = meetingDetail == null ? "" : meetingDetail.Instructor;
664
665         //            double percentComplete = (participantSessionsData.SessionEngagementCount.GetValueOrDefault() == 0 ? 
666         //                    1 : (participantSessionsData.SessionHeartbeatCount.GetValueOrDefault() / participantSessionsData.SessionEngagementCount.Value));
667
668         //            if (percentComplete >= .75) //threshold for earning a certificate is 75% response rate
669         //            {
670         //                purchase.EarnedCertificate = true;
671         //            }
672
673         //            Database.SubmitChanges();
674
675         //            if (purchase.EarnedCertificate)
676         //            {
677         //                //TODO with return Pass dictionary value as string.format with replace of certUrl
678         //                //string certUrl = AdobeCertificateHelper.SendWebcastCert(purchase);
679         //                //format the outcome.pass.value message with certUrl replace
680         //                //return outcome.pass with its value
681         //                return AdobeCertificateHelper.SendWebcastCert(purchase);
682         //            }
683         //            //TODO return outcome.fail
684         //            return AdobeCertificateHelper.SendFailNotice(purchase);
685         //        }
686         //    }
687         //    return _fail;// TODO return ineligible.need to make AdobeCertificateHelper.SendIneligibleNotice(principalId)
688         //}
689
690         //public participantResult ProcessParticipantResult(participantResult result, ParticipantPurchase purchase)
691         //{
692         //    if (purchase == null)
693         //    {
694         //        result = participantResult.Ineligible;
695         //    }
696         //    switch (result)
697         //    {
698         //        case participantResult.Ineligible:
699         //            //Ineligible for auto-cert; not sending notice.  
700         //            break;
701         //        case participantResult.Fail:
702         //            AdobeCertificateHelper.SendFailNotice(purchase);
703         //            break;
704         //        case participantResult.Pass:
705         //            AdobeCertificateHelper.SendWebcastCert(purchase);
706         //            //Send Cert email;
707         //            break;
708         //        case participantResult.Wonky:
709         //            //something went wrong: send email to contact cust service? send email to cpe? do nothing? 
710         //            break;
711         //    }
712         //    return result;
713         //}
714
715         //public ActionResult BatchProcessParticipantResults(int msk)
716         //{
717         //    List<ParticipantSessionsDataResult> psdr = BaseController.Database.ParticipantSessionsData(msk).ToList();
718         //    var meeting = BaseController.Database.MeetingSessions.FirstOrDefault(m => m.MeetingSessionKey == msk);
719         //    if (meeting == null)
720         //    {
721         //        return Content("Error retrieving meeting session details.");
722         //    }
723         //    var scoId = meeting.SCO_ID;
724
725         //    foreach (var p in psdr)
726         //    {
727         //        ParticipantPurchase purchase = null;
728         //        participantResult result = participantResult.Wonky;
729         //        var mpsk = p.MeetingParticipantSessionKey;
730         //        var meetingParticipantSession =
731         //            BaseController.Database.MeetingParticipantSessions.FirstOrDefault(
732         //                mps => mps.MeetingParticipantSessionKey == mpsk && mps.MeetingSessionKey == msk);
733
734         //        if (meetingParticipantSession != null)
735         //        {
736         //            var principalId = meetingParticipantSession.ParticipantKey;
737
738         //            purchase = BaseController.Database.ParticipantPurchases.FirstOrDefault(pp => pp.PrincipalID == principalId && pp.MeetingSco == scoId);
739         //            if (purchase == null)
740         //            {
741         //                result = participantResult.Ineligible;
742         //            }
743         //            else
744         //            {
745         //                MeetingSessionsDataResult meetingSession = Database.MeetingSessionsData().FirstOrDefault(m => m.MeetingSessionKey == msk);
746         //                if (meetingSession != null)
747         //                {
748         //                    var courseLength = meetingSession.ActualSessionTime.GetValueOrDefault(); //in minutes
749         //                    double courseCredits = courseLength/50.0; //1 credit per 50 minutes
750         //                    List<double> maxCourseCredits =
751         //                        ConfigurationManager.AppSettings["MaxCourseCreditList"].Split(';')
752         //                            .Select(s => double.Parse(s))
753         //                            .ToList(); //max credits cut list
754         //                    int mx = maxCourseCredits.BinarySearch(courseCredits);
755         //                        //find appropriate max for this course
756         //                    double maxCredits = maxCourseCredits[mx >= 0 ? mx : ~mx - 1]; //...by rounding down
757         //                    double realCredits = p.SessionCredit == null
758         //                        ? 0
759         //                        : (double) p.SessionCredit.Value; //users credits
760         //                    purchase.Credits = Math.Min(maxCredits, realCredits);
761         //                        //user awarded no more than max possible credits for the course
762
763         //                    MeetingDetail meetingDetail =
764         //                        Database.MeetingDetails.FirstOrDefault(m => m.MeetingKey == purchase.MeetingSco);
765
766         //                    purchase.Presenter = meetingDetail == null ? "" : meetingDetail.Instructor;
767
768         //                    double percentComplete =
769         //                        (p.SessionEngagementCount.GetValueOrDefault() == 0
770         //                            ? 1
771         //                            : (p.SessionHeartbeatCount.GetValueOrDefault()/
772         //                               p.SessionEngagementCount.Value));
773
774         //                    if (percentComplete >= .75) //threshold for earning a certificate is 75% response rate
775         //                    {
776         //                        purchase.EarnedCertificate = true;
777         //                        result = participantResult.Pass;
778         //                    }
779         //                    else
780         //                    {
781         //                        result = participantResult.Fail;
782         //                    }
783
784         //                    Database.SubmitChanges();
785         //                }
786         //            }
787         //        }
788         //        ProcessParticipantResult(result, purchase);
789         //    }
790         //    return Content("done");
791         //}
792
793         public ActionResult Result(int principalid, int scoid) {
794             var resultView = new SessionResultViewModel();
795             participantResult result = participantResult.Wonky;
796
797             Extensions.LogServiceCall("[IndexController][Result]", string.Format("Beginning: principalid = {0} scoid = {1}", principalid, scoid));
798
799             Extensions.LogServiceCall("[IndexController][Result]", string.Format(
800                                                                                  "principalid = {0} scoid = {1} DateTime.UtcNow.DayOfYear = {2} DateTime.Now.DayOfYear = {3}",
801                                                                                  principalid, scoid, DateTime.UtcNow.DayOfYear, DateTime.Now.DayOfYear));
802
803             var meeting =
804                 Database.MeetingSessions.FirstOrDefault(
805                                                         m => m.SCO_ID == scoid && m.StartDate.DayOfYear == DateTime.UtcNow.DayOfYear);
806             if(meeting != null) {
807                 int msk = meeting.MeetingSessionKey;
808                 MeetingParticipantSession meetingParticipantSession =
809                     Database.MeetingParticipantSessions.FirstOrDefault(
810                                                                        m => m.MeetingSessionKey == msk && m.ParticipantKey == principalid);
811                 if(meetingParticipantSession != null) {
812                     adobe.GetAdobeTransactions(meetingParticipantSession.MeetingSession, Database);
813                     Database.SubmitChanges();
814
815                     result = SessionEnd.ProcessEndOfMeetingSessionHeartbeatResultsForParticipant(Database, meetingParticipantSession);
816                     switch (result) {
817                         case participantResult.Ineligible:
818                             resultView.Message = Utilities.Result.RenderIneligibleResult(principalid);
819                             break;
820                         case participantResult.Fail:
821                             resultView.Message = Utilities.Result.RenderFailResult(principalid);
822                             break;
823                         case participantResult.Pass:
824                             resultView.Message = Utilities.Result.RenderPassResult(principalid);
825                             break;
826                         case participantResult.Wonky:
827                             resultView.Message = Utilities.Result.RenderWonkyResult();
828                             break;
829                     }
830                 } else {
831                     Extensions.LogServiceCall("[IndexController][Result]", string.Format(
832                                                                                          "meetingParticipantSession is null: principalid = {0} scoid= {1} msk = {2}",
833                                                                                          principalid, scoid, msk));
834                 }
835             } else {
836                 Extensions.LogServiceCall("[IndexController][Result]", string.Format(
837                                                                                      "meeting is null: principalid = {0} scoid= {1} DateTime.UtcNow.DayOfYear = {2} DateTime.Now.DayOfYear = {3}",
838                                                                                      principalid, scoid, DateTime.UtcNow.DayOfYear, DateTime.Now.DayOfYear));
839             }
840             resultView.Result = (int) result;
841             return View("result", resultView);
842         }
843     }
844 }