using CPE.App.Api.Models; using CPE.App.Web.Code; using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace CPE.App.Api.Helpers { public class TinCanHelper { public static bool HandleStatement(TinCanStatementModel statement) { // statement.Verb.Id=http://adlnet.gov/expapi/verbs/answered // statement.Verb.Id=http://adlnet.gov/expapi/verbs/experienced if (statement.Verb.Id.IndexOf("passed")>-1) { Utilities.LogWrapper.Info("[TinCanHelper][HandleStatement] {0} statement.Verb.Id={1}", DateTime.UtcNow.ToString("yyyyMMdd_HHmmss"), statement.Verb.Id); //parse statement to db variables var email = statement.Actor.Mbox.Substring(7); var fname = statement.Actor.Name.Substring(0, statement.Actor.Name.IndexOf(" ") + 1); var lname = statement.Actor.Name.Substring(statement.Actor.Name.LastIndexOf(" ") + 1); var courseUrl = statement.Object.Id.Substring(statement.Object.Id.LastIndexOf("/") + 1); var courseName = statement.Object.Definition.Name.EnUs; //cpe has test data with multiple, currently valid purchases of the same course for one user, which causes problems but is not a real-world problem. //elucidat tracks all users globally by email address so a tincan statement won't identify a specific purchase here //unless we create unique email addy (e.g. email+ticket@mail.com) when originally logging them in to content var course = BaseController.Database.PurchasedCourses.FirstOrDefault(c => c.Email == email && c.ContentUrl == courseUrl && c.CertificateDate == null); if (course == null) { Utilities.LogWrapper.Info("[TinCanHelper][HandleStatement] {0} no action, cert already earned email={1} courseName={2}", DateTime.UtcNow.ToString("yyyyMMdd_HHmmss"), email, courseName); //no action, cert already earned return true; } course.CertificateDate = Convert.ToDateTime(statement.Timestamp); try { BaseController.Database.SubmitChanges(); } catch (Exception exception) { Utilities.LogWrapper.Error("[TinCanHelper][HandleStatement] {0} email={1} courseName={2} exception={3}", DateTime.UtcNow.ToString("yyyyMMdd_HHmmss"), email, courseName, exception.ToString()); } var done = SendEmailHelper.SendCertificateEmail(course); Utilities.LogWrapper.Info("[TinCanHelper][HandleStatement] {0} cert sent email={1} courseName={2}", DateTime.UtcNow.ToString("yyyyMMdd_HHmmss"), email, courseName); //umm why am i not returning done here? return true; } if (statement.Verb.Id.IndexOf("failed") > -1) { Utilities.LogWrapper.Info("[TinCanHelper][HandleStatement] {0} statement.Verb.Id={1}", DateTime.UtcNow.ToString("yyyyMMdd_HHmmss"), statement.Verb.Id); //parse statement to db variables var email = statement.Actor.Mbox.Substring(7); var fname = statement.Actor.Name.Substring(0, statement.Actor.Name.IndexOf(" ") + 1); var lname = statement.Actor.Name.Substring(statement.Actor.Name.LastIndexOf(" ") + 1); var courseUrl = statement.Object.Id.Substring(statement.Object.Id.LastIndexOf("/") + 1); var courseName = statement.Object.Definition.Name.EnUs; //only logging failed attempts prior to earning a cert //selecting first record for a user for a course that is not expired. To allow for if a user fails to earn a cert within a year and re-purchases course var course = BaseController.Database.PurchasedCourses.FirstOrDefault(c => c.Email == email && c.ContentUrl == courseUrl && c.CertificateDate == null && ((c.PurchaseDate).AddYears(1)) > DateTime.UtcNow); if (course == null) { //no action, cert already earned return true; } Utilities.LogWrapper.Info("[TinCanHelper][HandleStatement] {0} course.Ticket={1}", DateTime.UtcNow.ToString("yyyyMMdd_HHmmss"), course.Ticket); if (!course.FailedAttempts.HasValue) { course.FailedAttempts = 0; } course.FailedAttempts++; try { BaseController.Database.SubmitChanges(); } catch (Exception exception) { Utilities.LogWrapper.Error("[TinCanHelper][HandleStatement] {0} email={1} courseName={2} exception={3}", DateTime.UtcNow.ToString("yyyyMMdd_HHmmss"), email, courseName, exception.ToString()); } Utilities.LogWrapper.Info("[TinCanHelper][HandleStatement] {0} failure recorded email={1} courseName={2}", DateTime.UtcNow.ToString("yyyyMMdd_HHmmss"), email, courseName); return true; } return true; } } }