private MailMessage GenerateReminderForPerson(Person person, List <Project> projects)
        {
            var projectListAsHtmlStrings =
                GenerateProjectListAsHtmlStrings(
                    projects);
            var projectsRequiringAnUpdateUrl =
                SitkaRoute <ProjectUpdateController> .BuildAbsoluteUrlHttpsFromExpression(x =>
                                                                                          x.MyProjectsRequiringAnUpdate());

            var emailContent = GetEmailContentWithGeneratedSignature(projectsRequiringAnUpdateUrl,
                                                                     person.FullNameFirstLast, String.Join("<br/>", projectListAsHtmlStrings));

            var htmlView = AlternateView.CreateAlternateViewFromString(emailContent, null, "text/html");

            htmlView.LinkedResources.Add(
                new LinkedResource(new MemoryStream(ToolLogo.FileResourceData), "img/jpeg")
            {
                ContentId = "tool-logo"
            });
            var mailMessage = new MailMessage {
                Subject = ReminderEmailSubject, IsBodyHtml = true
            };

            mailMessage.AlternateViews.Add(htmlView);

            return(mailMessage);
        }
예제 #2
0
        public static void SendApprovalMessage(List <Person> peopleToCc, ProjectUpdateBatch projectUpdateBatch)
        {
            Check.Require(projectUpdateBatch.ProjectUpdateState == ProjectUpdateState.Approved, "Need to be in Approved state to send the Approved email!");
            var latestProjectUpdateHistorySubmitted = projectUpdateBatch.LatestProjectUpdateHistorySubmitted;
            var submitterPerson = latestProjectUpdateHistorySubmitted.UpdatePerson;
            var emailsToSendTo  = new List <string> {
                submitterPerson.Email
            };

            var personNames          = submitterPerson.FullNameFirstLast;
            var primaryContactPerson = projectUpdateBatch.Project.GetPrimaryContact();

            if (primaryContactPerson != null &&
                !String.Equals(primaryContactPerson.Email, submitterPerson.Email, StringComparison.InvariantCultureIgnoreCase))
            {
                if (string.IsNullOrEmpty(primaryContactPerson.Email))
                {
                    Logger.Warn($"Primary Contact is missing email address and will not get an Approval Message. Primary Contact ID:{primaryContactPerson.PersonID} Primary Contact Name:{primaryContactPerson.FullNameFirstLast} Project Update Batch ID:{projectUpdateBatch.ProjectUpdateBatchID} ");
                }
                else
                {
                    emailsToSendTo.Add(primaryContactPerson.Email);
                    personNames += $" and {primaryContactPerson.FullNameFirstLast}";
                }
            }

            var approverPerson = projectUpdateBatch.LastUpdatePerson;
            var detailUrl      = SitkaRoute <ProjectController> .BuildAbsoluteUrlHttpsFromExpression(x => x.Detail(projectUpdateBatch.Project));

            var message = $@"
Dear {personNames},
<p>
    The update submitted for {FieldDefinition.Project.GetFieldDefinitionLabel()} {projectUpdateBatch.Project.DisplayName} on {
                    latestProjectUpdateHistorySubmitted.TransitionDate.ToStringDate()
                } was approved by {approverPerson.FullNameFirstLastAndOrg}.
</p>
<p>
    There is no action for you to take - this is simply a notification email. The updates for this {FieldDefinition.Project.GetFieldDefinitionLabel()} are now visible to the general public on this {FieldDefinition.Project.GetFieldDefinitionLabel()}'s detail page:
</p>
<p>
    <a href=""{detailUrl}"">View this {FieldDefinition.Project.GetFieldDefinitionLabel()}</a>
</p>
Thank you for keeping your {FieldDefinition.Project.GetFieldDefinitionLabel()} information and accomplishments up to date!<br />
{$"- {MultiTenantHelpers.GetToolDisplayName()} team"}
";

            var subject     = $"The update for {FieldDefinition.Project.GetFieldDefinitionLabel()} {projectUpdateBatch.Project.DisplayName} was approved";
            var mailMessage = new MailMessage {
                Subject = subject, Body = message, IsBodyHtml = true
            };

            SendMessageAndLogNotificationForProjectUpdateTransition(projectUpdateBatch,
                                                                    mailMessage,
                                                                    emailsToSendTo,
                                                                    new List <string> {
                approverPerson.Email
            },
                                                                    peopleToCc.Select(x => x.Email).ToList(),
                                                                    NotificationType.ProjectUpdateApproved);
        }
 public WebServiceProjectKeyPhoto(Project project)
 {
     ProjectID   = project.ProjectID;
     ProjectName = project.ProjectName;
     KeyPhotoUrl = project.KeyPhoto != null
         ? SitkaRoute <FileResourceController> .BuildAbsoluteUrlHttpsFromExpression(x => x.DisplayResource(project.KeyPhoto.FileResource.FileResourceGUIDAsString))
         : ViewUtilities.NoneString;
 }
        public static void SendReturnedMessage(Project project)
        {
            var submitterPerson             = project.ProposingPerson;
            var fieldDefinitionLabelProject = FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel();
            var subject   = $@"Your {fieldDefinitionLabelProject} ""{project.GetDisplayName().ToEllipsifiedString(80)}"" was not approved";
            var basicsUrl = SitkaRoute <ProjectCreateController> .BuildAbsoluteUrlHttpsFromExpression(x => x.EditBasics(project.ProjectID));

            var message = $@"
<p>Dear {submitterPerson.GetFullNameFirstLast()},</p>
<p>The {MultiTenantHelpers.GetToolDisplayName()} {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} submitted on {project.SubmissionDate.ToStringDate()} has been returned for further review.</p>
<p>The {fieldDefinitionLabelProject} was returned by {project.ReviewedByPerson.GetFullNameFirstLastAndOrg()}. Please review this {fieldDefinitionLabelProject} and address the comments that {project.ReviewedByPerson.FirstName} left for you. If you have questions please email: {project.ReviewedByPerson.Email}.</p>
<a href=""{basicsUrl}"">View this {fieldDefinitionLabelProject}</a></p>
<p>Thank you for using the {MultiTenantHelpers.GetToolDisplayName()}</p>
<p>{$"- {MultiTenantHelpers.GetToolDisplayName()} team"}<br/><br/><img src=""cid:tool-logo"" width=""160"" /></p>
";

            var mailMessage = new MailMessage {
                Subject = subject, Body = message, IsBodyHtml = true
            };

            var tenantAttribute = MultiTenantHelpers.GetTenantAttributeFromCache();
            var toolLogo        = tenantAttribute.TenantSquareLogoFileResourceInfo ??
                                  tenantAttribute.TenantBannerLogoFileResourceInfo;
            var htmlView = AlternateView.CreateAlternateViewFromString(message, null, "text/html");

            htmlView.LinkedResources.Add(
                new LinkedResource(new MemoryStream(toolLogo.FileResourceData.Data), "img/jpeg")
            {
                ContentId = "tool-logo"
            });
            mailMessage.AlternateViews.Add(htmlView);

            var emailsToSendTo = new List <string> {
                submitterPerson.Email
            };
            var primaryContactPerson = project.PrimaryContactPerson;

            if (primaryContactPerson != null && !String.Equals(primaryContactPerson.Email, submitterPerson.Email, StringComparison.InvariantCultureIgnoreCase))
            {
                emailsToSendTo.Add(primaryContactPerson.Email);
            }
            var contactsWhoCanManageProject = project.GetContactsWhoCanManageProject();

            foreach (var contact in contactsWhoCanManageProject)
            {
                if (!string.Equals(contact.Email, submitterPerson.Email, StringComparison.InvariantCultureIgnoreCase) && (primaryContactPerson == null || !string.Equals(contact.Email, primaryContactPerson.Email, StringComparison.InvariantCultureIgnoreCase)))
                {
                    emailsToSendTo.Add(contact.Email);
                }
            }
            var emailsToReplyTo = new List <string> {
                project.ReviewedByPerson.Email
            };
            var emailsToCc = project.GetProjectStewardPeople().Select(x => x.Email).ToList();

            SendMessageAndLogNotification(project, mailMessage, emailsToSendTo, emailsToReplyTo, emailsToCc, NotificationType.ProjectReturned);
        }
        public static void SendSubmittedMessage(List <Person> peopleToNotify, ProjectUpdateBatch projectUpdateBatch)
        {
            Check.Require(projectUpdateBatch.ProjectUpdateState == ProjectUpdateState.Submitted, "Need to be in Submitted state to send the Submitted email!");
            var latestProjectUpdateHistorySubmitted = projectUpdateBatch.GetLatestProjectUpdateHistorySubmitted();
            var submitterPerson = latestProjectUpdateHistorySubmitted.UpdatePerson;
            var submitterEmails = new List <string> {
                submitterPerson.Email
            };
            var primaryContactPerson = projectUpdateBatch.Project.GetPrimaryContact();

            if (primaryContactPerson != null && !string.Equals(primaryContactPerson.Email, submitterPerson.Email, StringComparison.InvariantCultureIgnoreCase))
            {
                submitterEmails.Add(primaryContactPerson.Email);
            }
            var contactsWhoCanManageProject = projectUpdateBatch.Project.GetContactsWhoCanManageProject();

            foreach (var contact in contactsWhoCanManageProject)
            {
                if (!string.Equals(contact.Email, submitterPerson.Email, StringComparison.InvariantCultureIgnoreCase) && (primaryContactPerson == null || !string.Equals(contact.Email, primaryContactPerson.Email, StringComparison.InvariantCultureIgnoreCase)))
                {
                    submitterEmails.Add(contact.Email);
                }
            }

            var emailsToSendTo  = peopleToNotify.Select(x => x.Email).ToList();
            var subject         = $"The update for {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} {projectUpdateBatch.Project.GetDisplayName()} was submitted";
            var instructionsUrl = SitkaRoute <ProjectUpdateController> .BuildAbsoluteUrlHttpsFromExpression(x => x.Instructions(projectUpdateBatch.Project));

            var message = $@"
<p>The update for {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} {projectUpdateBatch.Project.GetDisplayName()} on {
                    latestProjectUpdateHistorySubmitted.TransitionDate.ToStringDate()
                } was just submitted by {submitterPerson.GetFullNameFirstLastAndOrg()}.</p>
<p>Please review and Approve or Return it at your earliest convenience.<br />
<a href=""{instructionsUrl}"">View this {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} update</a></p>
{$"- {MultiTenantHelpers.GetToolDisplayName()} team"}<br/><br/><img src=""cid:tool-logo"" width=""160"" />
<p>You received this email because you are assigned to receive support notifications within the ProjectFirma tool.</p>
";

            var mailMessage = new MailMessage {
                Subject = subject, Body = message, IsBodyHtml = true
            };

            var tenantAttribute = MultiTenantHelpers.GetTenantAttributeFromCache();
            var toolLogo        = tenantAttribute.TenantSquareLogoFileResourceInfo ??
                                  tenantAttribute.TenantBannerLogoFileResourceInfo;
            var htmlView = AlternateView.CreateAlternateViewFromString(message, null, "text/html");

            htmlView.LinkedResources.Add(
                new LinkedResource(new MemoryStream(toolLogo.FileResourceData.Data), "img/jpeg")
            {
                ContentId = "tool-logo"
            });
            mailMessage.AlternateViews.Add(htmlView);

            SendMessageAndLogNotificationForProjectUpdateTransition(projectUpdateBatch, mailMessage, emailsToSendTo, submitterEmails, new List <string>(), NotificationType.ProjectUpdateSubmitted);
        }
        public static void SendSubmittedMessage(Project project)
        {
            var submitterPerson = project.ProposingPerson;
            var subject         = $"A {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} was submitted by {submitterPerson.GetFullNameFirstLastAndOrg()}";
            var basicsUrl       = SitkaRoute <ProjectCreateController> .BuildAbsoluteUrlHttpsFromExpression(x => x.EditBasics(project.ProjectID));

            var message     = $@"
<p>A new {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()}, “{project.GetDisplayName()}”, was submitted.</p>
<p>The {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} was submitted on {project.ProposingDate.ToStringDate()} by {
                    submitterPerson.GetFullNameFirstLastAndOrg()
                }.<br />
<p>Please review and Approve or Return it at your earliest convenience.</p>
<a href=""{basicsUrl}"">View this {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()}</a></p>
{$"- {MultiTenantHelpers.GetToolDisplayName()} team"}<br/><br/><img src=""cid:tool-logo"" width=""160"" />
<p>You received this email because you are assigned to receive support notifications within the ProjectFirma tool.</p>
";
            var mailMessage = new MailMessage {
                Subject = subject, Body = message, IsBodyHtml = true
            };

            var tenantAttribute = MultiTenantHelpers.GetTenantAttributeFromCache();
            var toolLogo        = tenantAttribute.TenantSquareLogoFileResourceInfo ??
                                  tenantAttribute.TenantBannerLogoFileResourceInfo;
            var htmlView = AlternateView.CreateAlternateViewFromString(message, null, "text/html");

            htmlView.LinkedResources.Add(
                new LinkedResource(new MemoryStream(toolLogo.FileResourceData.Data), "img/jpeg")
            {
                ContentId = "tool-logo"
            });
            mailMessage.AlternateViews.Add(htmlView);

            var emailsToSendTo  = project.GetProjectStewardPeople().Select(x => x.Email).Distinct().ToList();
            var emailsToReplyTo = new List <string> {
                submitterPerson.Email
            };
            var primaryContactPerson = project.PrimaryContactPerson;

            if (primaryContactPerson != null && !String.Equals(primaryContactPerson.Email, submitterPerson.Email, StringComparison.InvariantCultureIgnoreCase))
            {
                emailsToReplyTo.Add(primaryContactPerson.Email);
            }
            var contactsWhoCanManageProject = project.GetContactsWhoCanManageProject();

            foreach (var contact in contactsWhoCanManageProject)
            {
                if (!string.Equals(contact.Email, submitterPerson.Email, StringComparison.InvariantCultureIgnoreCase) && (primaryContactPerson == null || !string.Equals(contact.Email, primaryContactPerson.Email, StringComparison.InvariantCultureIgnoreCase)))
                {
                    emailsToReplyTo.Add(contact.Email);
                }
            }
            var emailsToCc = new List <string>();

            SendMessageAndLogNotification(project, mailMessage, emailsToSendTo, emailsToReplyTo, emailsToCc, NotificationType.ProjectSubmitted);
        }
 public ProjectMapViewData(Person currentPerson, Models.FirmaPage firmaPage, ProjectLocationsMapInitJson projectLocationsMapInitJson, ProjectLocationsMapViewData projectLocationsMapViewData, Dictionary <ProjectLocationFilterTypeSimple, IEnumerable <SelectListItem> > projectLocationFilterTypesAndValues, string projectLocationsUrl, string filteredProjectsWithLocationAreasUrl, List <ProjectMapLocationJson> projectMapLocationJsons) : base(currentPerson, firmaPage)
 {
     PageTitle = $"{Models.FieldDefinition.Project.GetFieldDefinitionLabel()} Map";
     ProjectLocationsMapInitJson         = projectLocationsMapInitJson;
     ProjectLocationFilterTypesAndValues = projectLocationFilterTypesAndValues;
     ProjectLocationsMapViewData         = projectLocationsMapViewData;
     ProjectLocationsUrl = projectLocationsUrl;
     FilteredProjectsWithLocationAreasUrl = filteredProjectsWithLocationAreasUrl;
     ProjectMapViewDataForAngular         = new ProjectMapViewDataForAngular(projectLocationsMapInitJson, projectLocationsMapInitJson.ProjectLocationsLayerGeoJson, projectMapLocationJsons);
     GeocodeAddressUrl = SitkaRoute <ResultsController> .BuildAbsoluteUrlHttpsFromExpression(x => x.GeocodeAddress(null, null));;
 }
예제 #8
0
        public IndexViewData(Person currentPerson, NeptunePage neptunePage, MapInitJson ovtaBasedMapInitJson,
                             MapInitJson areaBasedMapInitJson, MapInitJson loadBasedMapInitJson,
                             IEnumerable <Models.TreatmentBMP> treatmentBMPs, List <TrashCaptureStatusType> trashCaptureStatusTypes,
                             List <Models.Parcel> parcels, List <StormwaterJurisdiction> stormwaterJurisdictions,
                             FeatureCollection geoJsonForJurisdictions) : base(currentPerson, neptunePage)
        {
            OVTABasedMapInitJson = ovtaBasedMapInitJson;
            AreaBasedMapInitJson = areaBasedMapInitJson;
            LoadBasedMapInitJson = loadBasedMapInitJson;

            var stormwaterJurisdictionIDs = stormwaterJurisdictions.Select(x => x.StormwaterJurisdictionID).ToList();

            StormwaterJurisdictionCQLFilter =
                currentPerson.GetStormwaterJurisdictionCqlFilter(stormwaterJurisdictionIDs);
            NegativeStormwaterJurisdictionCQLFilter =
                currentPerson.GetNegativeStormwaterJurisdictionCqlFilter(stormwaterJurisdictionIDs);
            JurisdictionSelectList = stormwaterJurisdictions.OrderBy(x => x.GetOrganizationDisplayName())
                                     .ToSelectList(x => x.StormwaterJurisdictionID.ToString(CultureInfo.InvariantCulture),
                                                   x => x.GetOrganizationDisplayName());
            var showDropdown = stormwaterJurisdictions.Count > 1;
            var currentUserIsAnonymousOrUnassigned = CurrentPerson.IsAnonymousOrUnassigned();

            ViewDataForAngular = new ViewDataForAngularClass(ovtaBasedMapInitJson, areaBasedMapInitJson,
                                                             loadBasedMapInitJson,
                                                             treatmentBMPs, trashCaptureStatusTypes, parcels, StormwaterJurisdictionCQLFilter, showDropdown,
                                                             NegativeStormwaterJurisdictionCQLFilter, geoJsonForJurisdictions, currentUserIsAnonymousOrUnassigned);
            EntityName  = "Trash Module";
            PageTitle   = "Welcome";
            AllOVTAsUrl =
                SitkaRoute <OnlandVisualTrashAssessmentController> .BuildAbsoluteUrlHttpsFromExpression(x => x.Index(),
                                                                                                        NeptuneWebConfiguration.CanonicalHostName);

            FindBMPUrl = SitkaRoute <TreatmentBMPController> .BuildAbsoluteUrlHttpsFromExpression(x => x.FindABMP(),
                                                                                                  NeptuneWebConfiguration.CanonicalHostName);

            BeginOVTAUrl =
                SitkaRoute <OnlandVisualTrashAssessmentController> .BuildAbsoluteUrlHttpsFromExpression(x =>
                                                                                                        x.Instructions(null),
                                                                                                        NeptuneWebConfiguration.CanonicalHostName);

            AddBMPUrl = SitkaRoute <TreatmentBMPController> .BuildAbsoluteUrlHttpsFromExpression(x => x.New(),
                                                                                                 NeptuneWebConfiguration.CanonicalHostName);

            RefreshTguUrl = SitkaRoute <HomeController> .BuildUrlFromExpression(x => x.RefreshTrashGeneratingUnits());

            ScoreDescriptionsUrl =
                SitkaRoute <OnlandVisualTrashAssessmentController> .BuildUrlFromExpression(x => x.ScoreDescriptions());

            ProgramOverviewPageContentViewData = new ViewPageContentViewData(
                NeptunePage.GetNeptunePageByPageType(NeptunePageType.TrashModuleProgramOverview), currentPerson);
        }
        private static IEnumerable <string> GenerateProjectListAsHtmlStrings(
            IReadOnlyCollection <Project> projects)
        {
            var projectsRemaining        = projects;
            var projectListAsHtmlStrings = projectsRemaining.OrderBy(project => project.DisplayName).Select(project =>
            {
                var projectUrl =
                    SitkaRoute <ProjectController> .BuildAbsoluteUrlHttpsFromExpression(controller =>
                                                                                        controller.Detail(project));
                return($@"<div style=""font-size:smaller""><a href=""{projectUrl}"">{project.ProjectName}</a></div>");
            }).ToList();

            return(projectListAsHtmlStrings);
        }
        public static void SendApprovalMessage(Project project)
        {
            Check.Require(project.ProjectApprovalStatus == ProjectApprovalStatus.Approved, "Need to be in Approved state to send the Approved email!");
            var submitterPerson             = project.ProposingPerson;
            var fieldDefinitionLabelProject = FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel();
            var subject   = $"Your {fieldDefinitionLabelProject} \"{project.GetDisplayName().ToEllipsifiedString(80)}\" was approved!";
            var detailUrl = SitkaRoute <ProjectController> .BuildAbsoluteUrlHttpsFromExpression(x => x.Detail(project.ProjectID));

            var projectListUrl = SitkaRoute <ProjectController> .BuildAbsoluteUrlHttpsFromExpression(x => x.Index());

            var message     = $@"
<p>Dear {submitterPerson.GetFullNameFirstLast()},</p>
<p>The {MultiTenantHelpers.GetToolDisplayName()} {fieldDefinitionLabelProject} submitted on {project.SubmissionDate.ToStringDate()} was approved by {project.ReviewedByPerson.GetFullNameFirstLastAndOrg()}.</p>
<p>This {fieldDefinitionLabelProject} is now on the <a href=""{projectListUrl}"">{MultiTenantHelpers.GetToolDisplayName()} {fieldDefinitionLabelProject} List</a> and is visible to the public via the {fieldDefinitionLabelProject} detail page.</p>
<p><a href=""{detailUrl}"">View this {fieldDefinitionLabelProject}</a></p>
<p>Thank you for using the {MultiTenantHelpers.GetToolDisplayName()}!</p>
<p>{$"- {MultiTenantHelpers.GetToolDisplayName()} team"}</p>
";
            var mailMessage = new MailMessage {
                Subject = subject, Body = message, IsBodyHtml = true
            };
            var emailsToSendTo = new List <string> {
                submitterPerson.Email
            };
            var emailsToReplyTo = new List <string> {
                project.ReviewedByPerson.Email
            };
            var primaryContactPerson = project.GetPrimaryContact();

            if (primaryContactPerson != null && !String.Equals(primaryContactPerson.Email, submitterPerson.Email, StringComparison.InvariantCultureIgnoreCase))
            {
                emailsToSendTo.Add(primaryContactPerson.Email);
            }
            var contactsWhoCanManageProject = project.GetContactsWhoCanManageProject();

            foreach (var contact in contactsWhoCanManageProject)
            {
                if (!string.Equals(contact.Email, submitterPerson.Email, StringComparison.InvariantCultureIgnoreCase) && (primaryContactPerson == null || !string.Equals(contact.Email, primaryContactPerson.Email, StringComparison.InvariantCultureIgnoreCase)))
                {
                    emailsToSendTo.Add(contact.Email);
                }
            }

            SendMessageAndLogNotification(project,
                                          mailMessage,
                                          emailsToSendTo,
                                          emailsToReplyTo, project.GetProjectStewardPeople().Select(x => x.Email).ToList(),
                                          NotificationType.ProjectUpdateApproved);
        }
예제 #11
0
        private IEnumerable <string> GenerateProjectListAsHtmlStrings(
            IReadOnlyCollection <Project> projects)
        {
            var projectsRemaining        = projects;
            var tenantCanonicalHostName  = FirmaWebConfiguration.GetCanonicalHostForBackgroundJob(TenantID);
            var projectListAsHtmlStrings = projectsRemaining.OrderBy(project => project.GetDisplayName()).Select(project =>
            {
                var projectUrl =
                    SitkaRoute <ProjectController> .BuildAbsoluteUrlHttpsFromExpression(controller =>
                                                                                        controller.Detail(project));
                projectUrl = SitkaRoute <ProjectController> .ReplaceHostNameForBackgroundJob(projectUrl, tenantCanonicalHostName);
                return($@"<div style=""font-size:smaller""><a href=""{projectUrl}"">{project.ProjectName}</a></div>");
            }).ToList();

            return(projectListAsHtmlStrings);
        }
예제 #12
0
        public static void SendApprovalMessage(Project project)
        {
            Check.Require(project.ProjectApprovalStatus == ProjectApprovalStatus.Approved, "Need to be in Approved state to send the Approved email!");
            var submitterPerson = project.ProposingPerson;
            var subject         = $"Your {Models.FieldDefinition.Project.GetFieldDefinitionLabel()} \"{project.DisplayName.ToEllipsifiedString(80)}\" was approved!";
            var detailUrl       = SitkaRoute <ProjectController> .BuildAbsoluteUrlHttpsFromExpression(x => x.Detail(project.ProjectID));

            var projectListUrl = SitkaRoute <ProjectController> .BuildAbsoluteUrlHttpsFromExpression(x => x.Index());

            var message     = $@"
<p>Dear {submitterPerson.FullNameFirstLastAndOrg},</p>
<p>The {MultiTenantHelpers.GetToolDisplayName()} {Models.FieldDefinition.Project.GetFieldDefinitionLabel()} submitted on {project.SubmissionDate.ToStringDate()} was approved by {project.ReviewedByPerson.FullNameFirstLastAndOrg}.</p>
<p>This {Models.FieldDefinition.Project.GetFieldDefinitionLabel()} is now on the <a href=""{projectListUrl}"">{MultiTenantHelpers.GetToolDisplayName()} {Models.FieldDefinition.Project.GetFieldDefinitionLabel()} List</a> and is visible to the public via the {Models.FieldDefinition.Project.GetFieldDefinitionLabel()} detail page.</p>
<p><a href=""{detailUrl}"">View this {Models.FieldDefinition.Project.GetFieldDefinitionLabel()}</a></p>
<p>Thank you for using the {MultiTenantHelpers.GetToolDisplayName()}!</p>
<p>{$"- {MultiTenantHelpers.GetToolDisplayName()} team"}</p>
";
            var mailMessage = new MailMessage {
                Subject = subject, Body = message, IsBodyHtml = true
            };
            var emailsToSendTo = new List <string> {
                submitterPerson.Email
            };
            var emailsToReplyTo = new List <string> {
                project.ReviewedByPerson.Email
            };
            var primaryContactPerson = project.GetPrimaryContact();

            if (primaryContactPerson != null && !String.Equals(primaryContactPerson.Email, submitterPerson.Email, StringComparison.InvariantCultureIgnoreCase))
            {
                if (string.IsNullOrEmpty(primaryContactPerson.Email))
                {
                    Logger.Warn($"Primary Contact is missing email address and will not get an Approval Message. Primary Contact ID:{primaryContactPerson.PersonID} Primary Contact Name:{primaryContactPerson.FullNameFirstLast} Project ID:{project.ProjectID} ");
                }
                else
                {
                    emailsToSendTo.Add(primaryContactPerson.Email);
                }
            }

            SendMessageAndLogNotification(project,
                                          mailMessage,
                                          emailsToSendTo,
                                          emailsToReplyTo,
                                          GetProjectStewardPeople(project).Select(x => x.Email).ToList(),
                                          NotificationType.ProjectUpdateApproved);
        }
예제 #13
0
        public ActionResult EditBasics(AgreementPrimaryKey agreementPrimaryKey, AgreementEditViewModel viewModel)
        {
            var agreement = agreementPrimaryKey.EntityObject;

            if (!ModelState.IsValid)
            {
                return(AgreementViewEdit(viewModel, CurrentFirmaSession, agreement));
            }

            viewModel.UpdateModelAndSaveChanges(agreement, CurrentFirmaSession, HttpRequestStorage.DatabaseEntities);

            SetMessageForDisplay($"Agreement {agreement.GetDetailLinkUsingAgreementNumber()} saved.");

            // They may have edited the Agreement Number, so we need to redirect in case this has happened.
            string redirectUrl = SitkaRoute <AgreementController> .BuildAbsoluteUrlHttpsFromExpression(x => x.AgreementDetail(viewModel.AgreementNumber));

            return(new ModalDialogFormJsonResult(redirectUrl));
        }
        public static void SendSubmittedMessage(List <Person> peopleToNotify, ProjectUpdateBatch projectUpdateBatch)
        {
            Check.Require(projectUpdateBatch.ProjectUpdateState == ProjectUpdateState.Submitted, "Need to be in Submitted state to send the Submitted email!");
            var latestProjectUpdateHistorySubmitted = projectUpdateBatch.GetLatestProjectUpdateHistorySubmitted();
            var submitterPerson = latestProjectUpdateHistorySubmitted.UpdatePerson;
            var submitterEmails = new List <string> {
                submitterPerson.Email
            };
            var primaryContactPerson = projectUpdateBatch.Project.GetPrimaryContact();

            if (primaryContactPerson != null && !string.Equals(primaryContactPerson.Email, submitterPerson.Email, StringComparison.InvariantCultureIgnoreCase))
            {
                submitterEmails.Add(primaryContactPerson.Email);
            }
            var contactsWhoCanManageProject = projectUpdateBatch.Project.GetContactsWhoCanManageProject();

            foreach (var contact in contactsWhoCanManageProject)
            {
                if (!string.Equals(contact.Email, submitterPerson.Email, StringComparison.InvariantCultureIgnoreCase) && (primaryContactPerson == null || !string.Equals(contact.Email, primaryContactPerson.Email, StringComparison.InvariantCultureIgnoreCase)))
                {
                    submitterEmails.Add(contact.Email);
                }
            }

            var emailsToSendTo  = peopleToNotify.Select(x => x.Email).ToList();
            var subject         = $"The update for {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} {projectUpdateBatch.Project.GetDisplayName()} was submitted";
            var instructionsUrl = SitkaRoute <ProjectUpdateController> .BuildAbsoluteUrlHttpsFromExpression(x => x.Instructions(projectUpdateBatch.Project));

            var message = $@"
<p>The update for {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} {projectUpdateBatch.Project.GetDisplayName()} on {
                    latestProjectUpdateHistorySubmitted.TransitionDate.ToStringDate()
                } was just submitted by {submitterPerson.GetFullNameFirstLastAndOrg()}.</p>
<p>Please review and Approve or Return it at your earliest convenience.<br />
<a href=""{instructionsUrl}"">View this {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} update</a></p>
<p>You received this email because you are assigned to receive support notifications within the ProjectFirma tool.</p>
";

            var mailMessage = new MailMessage {
                Subject = subject, Body = message, IsBodyHtml = true
            };

            SendMessageAndLogNotificationForProjectUpdateTransition(projectUpdateBatch, mailMessage, emailsToSendTo, submitterEmails, new List <string>(), NotificationType.ProjectUpdateSubmitted);
        }
예제 #15
0
        /// <summary>
        /// Call for page with associated NeptunePage
        /// </summary>
        protected NeptuneViewData(Person currentPerson, Models.NeptunePage neptunePage, bool isHomePage,
                                  NeptuneArea neptuneArea)
        {
            NeptunePage = neptunePage;

            CurrentPerson  = currentPerson;
            NeptuneHomeUrl = SitkaRoute <HomeController> .BuildAbsoluteUrlHttpsFromExpression(c => c.Index(), NeptuneWebConfiguration.CanonicalHostNameRoot);

            LogInUrl  = NeptuneHelpers.GenerateLogInUrlWithReturnUrl();
            LogOutUrl = NeptuneHelpers.GenerateLogOutUrlWithReturnUrl();

            RequestSupportUrl = SitkaRoute <HelpController> .BuildUrlFromExpression(c => c.Support());

            LegalUrl = SitkaRoute <HomeController> .BuildUrlFromExpression(c => c.Legal());

            MakeNeptuneMenu(currentPerson);
            NeptuneNavBarViewData = new NeptuneNavBarViewData(currentPerson, LogInUrl, LogOutUrl, RequestSupportUrl, neptuneArea, isHomePage);

            ViewPageContentViewData = neptunePage != null ? new ViewPageContentViewData(neptunePage, currentPerson) : null;
        }
예제 #16
0
        public static void SendReturnedMessage(Project project)
        {
            var submitterPerson = project.ProposingPerson;
            var subject         = $@"Your {Models.FieldDefinition.Project.GetFieldDefinitionLabel()} ""{project.DisplayName.ToEllipsifiedString(80)}"" was not approved";
            var basicsUrl       = SitkaRoute <ProjectCreateController> .BuildAbsoluteUrlHttpsFromExpression(x => x.EditBasics(project.ProjectID));

            var message = $@"
<p>Dear {submitterPerson.FullNameFirstLast},</p>
<p>The {MultiTenantHelpers.GetToolDisplayName()} {Models.FieldDefinition.Project.GetFieldDefinitionLabel()} submitted on {project.SubmissionDate.ToStringDate()} has been returned for further review.</p>
<p>The {Models.FieldDefinition.Project.GetFieldDefinitionLabel()} was returned by {project.ReviewedByPerson.FullNameFirstLastAndOrg}. {project.ReviewedByPerson.FirstName} will contact you for additional information before this {Models.FieldDefinition.Project.GetFieldDefinitionLabel()} can move forward.</p>
<a href=""{basicsUrl}"">View this {Models.FieldDefinition.Project.GetFieldDefinitionLabel()}</a></p>
<p>Thank you for using the {MultiTenantHelpers.GetToolDisplayName()}</p>
<p>{$"- {MultiTenantHelpers.GetToolDisplayName()} team"}</p>
";

            var mailMessage = new MailMessage {
                Subject = subject, Body = message, IsBodyHtml = true
            };
            var emailsToSendTo = new List <string> {
                submitterPerson.Email
            };
            var primaryContactPerson = project.GetPrimaryContact();

            if (primaryContactPerson != null && !String.Equals(primaryContactPerson.Email, submitterPerson.Email, StringComparison.InvariantCultureIgnoreCase))
            {
                if (string.IsNullOrEmpty(primaryContactPerson.Email))
                {
                    Logger.Warn($"Primary Contact is missing email address and will not get a Returned Message. Primary Contact ID:{primaryContactPerson.PersonID} Primary Contact Name:{primaryContactPerson.FullNameFirstLast} Project ID:{project.ProjectID} ");
                }
                else
                {
                    emailsToSendTo.Add(primaryContactPerson.Email);
                }
            }
            var emailsToReplyTo = new List <string> {
                project.ReviewedByPerson.Email
            };
            var emailsToCc = GetProjectStewardPeople(project).Select(x => x.Email).ToList();

            SendMessageAndLogNotification(project, mailMessage, emailsToSendTo, emailsToReplyTo, emailsToCc, NotificationType.ProjectReturned);
        }
        public static void SendSubmittedMessage(Project project)
        {
            var submitterPerson = project.ProposingPerson;
            var subject         = $"A {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} was submitted by {submitterPerson.GetFullNameFirstLastAndOrg()}";
            var basicsUrl       = SitkaRoute <ProjectCreateController> .BuildAbsoluteUrlHttpsFromExpression(x => x.EditBasics(project.ProjectID));

            var message     = $@"
<p>A new {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()}, “{project.GetDisplayName()}”, was submitted.</p>
<p>The {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} was submitted on {project.ProposingDate.ToStringDate()} by {
                    submitterPerson.GetFullNameFirstLastAndOrg()
                }.<br />
<p>Please review and Approve or Return it at your earliest convenience.</p>
<a href=""{basicsUrl}"">View this {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()}</a></p>
<p>You received this email because you are assigned to receive support notifications within the ProjectFirma tool.</p>
";
            var mailMessage = new MailMessage {
                Subject = subject, Body = message, IsBodyHtml = true
            };
            var emailsToSendTo  = project.GetProjectStewardPeople().Select(x => x.Email).Distinct().ToList();
            var emailsToReplyTo = new List <string> {
                submitterPerson.Email
            };
            var primaryContactPerson = project.PrimaryContactPerson;

            if (primaryContactPerson != null && !String.Equals(primaryContactPerson.Email, submitterPerson.Email, StringComparison.InvariantCultureIgnoreCase))
            {
                emailsToReplyTo.Add(primaryContactPerson.Email);
            }
            var contactsWhoCanManageProject = project.GetContactsWhoCanManageProject();

            foreach (var contact in contactsWhoCanManageProject)
            {
                if (!string.Equals(contact.Email, submitterPerson.Email, StringComparison.InvariantCultureIgnoreCase) && (primaryContactPerson == null || !string.Equals(contact.Email, primaryContactPerson.Email, StringComparison.InvariantCultureIgnoreCase)))
                {
                    emailsToReplyTo.Add(contact.Email);
                }
            }
            var emailsToCc = new List <string>();

            SendMessageAndLogNotification(project, mailMessage, emailsToSendTo, emailsToReplyTo, emailsToCc, NotificationType.ProjectSubmitted);
        }
예제 #18
0
        public static void SendSubmittedMessage(Project project)
        {
            var submitterPerson = project.ProposingPerson;
            var subject         = $"A {Models.FieldDefinition.Project.GetFieldDefinitionLabel()} was submitted by {submitterPerson.FullNameFirstLastAndOrg}";
            var basicsUrl       = SitkaRoute <ProjectCreateController> .BuildAbsoluteUrlHttpsFromExpression(x => x.EditBasics(project.ProjectID));

            var message     = $@"
<p>A new {Models.FieldDefinition.Project.GetFieldDefinitionLabel()}, “{project.DisplayName}”, was submitted.</p>
<p>The {Models.FieldDefinition.Project.GetFieldDefinitionLabel()} was submitted on {project.ProposingDate.ToStringDate()} by {
                    submitterPerson.FullNameFirstLastAndOrg
                }.<br />
<p>Please review and Approve or Return it at your earliest convenience.</p>
<a href=""{basicsUrl}"">View this {Models.FieldDefinition.Project.GetFieldDefinitionLabel()}</a></p>
<p>You received this email because you are assigned to receive support notifications within the ProjectFirma tool.</p>
";
            var mailMessage = new MailMessage {
                Subject = subject, Body = message, IsBodyHtml = true
            };
            var emailsToSendTo  = GetProjectStewardPeople(project).Select(x => x.Email).Distinct().ToList();
            var emailsToReplyTo = new List <string> {
                submitterPerson.Email
            };
            var primaryContactPerson = project.GetPrimaryContact();

            if (primaryContactPerson != null && !string.Equals(primaryContactPerson.Email, submitterPerson.Email, StringComparison.InvariantCultureIgnoreCase))
            {
                if (string.IsNullOrEmpty(primaryContactPerson.Email))
                {
                    Logger.Warn($"Primary Contact is missing email address and will not get a Submitted Message. Primary Contact ID:{primaryContactPerson.PersonID} Primary Contact Name:{primaryContactPerson.FullNameFirstLast} Project ID:{project.ProjectID} ");
                }
                else
                {
                    emailsToReplyTo.Add(primaryContactPerson.Email);
                }
            }
            var emailsToCc = new List <string>();

            SendMessageAndLogNotification(project, mailMessage, emailsToSendTo, emailsToReplyTo, emailsToCc, NotificationType.ProjectSubmitted);
        }
예제 #19
0
        /// <summary>
        /// Function required by <see cref="OwinStartupAttribute"/>
        /// </summary>
        public void Configuration(IAppBuilder app)
        {
            SitkaHttpApplication.Logger.Info("Owin Startup");

            JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = "Cookies",
                CookieDomain       = CookieDomain,
                CookieManager      = new Microsoft.Owin.Host.SystemWeb.SystemWebChunkingCookieManager(),
                CookieName         = $"{NeptuneWebConfiguration.KeystoneOpenIDClientId}_{NeptuneWebConfiguration.NeptuneEnvironment.NeptuneEnvironmentType}"
            });

            //Needed (at least in development) to allow Neptune to talk to upgraded keystone
            ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;

            //Most of the new openID for mvc pieces came from here https://www.scottbrady91.com/ASPNET/Refreshing-your-Legacy-ASPNET-IdentityServer-Client-Applications
            app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
            {
                ClientId              = NeptuneWebConfiguration.KeystoneOpenIDClientId,
                Authority             = NeptuneWebConfiguration.KeystoneOpenIDUrl,
                RedirectUri           = SitkaRoute <AccountController> .BuildAbsoluteUrlHttpsFromExpression(c => c.LogOn(), NeptuneWebConfiguration.CanonicalHostNameRoot), // this has to match the keystone client redirect uri
                PostLogoutRedirectUri = $"https://{NeptuneWebConfiguration.CanonicalHostNameRoot}/",                                                                        // OpenID is super picky about this; url must match what Keystone has EXACTLY (Trailing slash and all)
                ResponseType          = "code",
                Scope                      = "openid profile offline_access keystone",
                UseTokenLifetime           = false,
                SignInAsAuthenticationType = "Cookies",
                //ClientSecret = NeptuneWebConfiguration.KeystoneOpenIDClientSecret,
                CallbackPath = new PathString("/Account/LogOn"),

                RequireHttpsMetadata = false,
                RedeemCode           = true,
                SaveTokens           = true,
                ResponseMode         = "query",

                Notifications = new OpenIdConnectAuthenticationNotifications
                {
                    AuthenticationFailed = (context) =>
                    {
                        if ((context.Exception.Message.StartsWith("OICE_20004") || context.Exception.Message.Contains("IDX10311")))
                        {
                            context.SkipToNextMiddleware();
                            return(Task.FromResult(0));
                        }

                        return(Task.FromResult(0));
                    },
                    SecurityTokenValidated = n =>
                    {
                        var claimsIdentity = n.AuthenticationTicket.Identity;
                        claimsIdentity.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken));

                        if (n.ProtocolMessage.Code != null)
                        {
                            claimsIdentity.AddClaim(new Claim("code", n.ProtocolMessage.Code));
                        }

                        if (n.ProtocolMessage.AccessToken != null)
                        {
                            claimsIdentity.AddClaim(new Claim("access_token", n.ProtocolMessage.AccessToken));
                        }

                        //map name claim to default name type
                        claimsIdentity.AddClaim(new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", claimsIdentity.FindFirst(KeystoneOpenIDClaimTypes.Name).Value.ToString()));

                        if (claimsIdentity.IsAuthenticated) // we have a token and we can determine the person.
                        {
                            KeystoneOpenIDUtilities.OpenIDClaimHandler(SyncLocalAccountStore, claimsIdentity);
                        }

                        return(Task.FromResult(0));
                    },
                    RedirectToIdentityProvider = n =>
                    {
                        if (n.ProtocolMessage.RequestType == Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectRequestType.Authentication)
                        {
                            // generate code verifier and code challenge
                            var codeVerifier = CryptoRandom.CreateUniqueId(32);

                            string codeChallenge;
                            using (var sha256 = SHA256.Create())
                            {
                                var challengeBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(codeVerifier));
                                codeChallenge      = Base64Url.Encode(challengeBytes);
                            }

                            // set code_challenge parameter on authorization request
                            n.ProtocolMessage.SetParameter("code_challenge", codeChallenge);
                            n.ProtocolMessage.SetParameter("code_challenge_method", "S256");

                            // remember code verifier in cookie (adapted from OWIN nonce cookie)
                            // see: https://github.com/scottbrady91/Blog-Example-Classes/blob/master/AspNetFrameworkPkce/ScottBrady91.BlogExampleCode.AspNetPkce/Startup.cs#L85
                            RememberCodeVerifier(n, codeVerifier);
                        }

                        //https://identityserver.github.io/Documentation/docsv2/overview/mvcGettingStarted.html#adding-logout
                        if (n.ProtocolMessage.RequestType == Microsoft.IdentityModel.Protocols.OpenIdConnect
                            .OpenIdConnectRequestType.Logout)
                        {
                            var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token");

                            if (idTokenHint != null)
                            {
                                n.ProtocolMessage.IdTokenHint = idTokenHint.Value;
                            }
                        }

                        return(Task.CompletedTask);
                    },
                    AuthorizationCodeReceived = n =>
                    {
                        // get code verifier from cookie
                        // see: https://github.com/scottbrady91/Blog-Example-Classes/blob/master/AspNetFrameworkPkce/ScottBrady91.BlogExampleCode.AspNetPkce/Startup.cs#L102
                        var codeVerifier = RetrieveCodeVerifier(n);

                        // attach code_verifier on token request
                        n.TokenEndpointRequest.SetParameter("code_verifier", codeVerifier);

                        return(Task.CompletedTask);
                    }
                }
            });

            ScheduledBackgroundJobBootstrapper.ConfigureHangfireAndScheduledBackgroundJobs(app);
        }
        public static void SendReturnedMessage(List <Person> peopleToCc, ProjectUpdateBatch projectUpdateBatch)
        {
            Check.Require(projectUpdateBatch.ProjectUpdateState == ProjectUpdateState.Returned, "Need to be in Returned state to send the Returned email!");
            var latestProjectUpdateHistorySubmitted = projectUpdateBatch.GetLatestProjectUpdateHistorySubmitted();
            var submitterPerson = latestProjectUpdateHistorySubmitted.UpdatePerson;
            var emailsToSendTo  = new List <string> {
                submitterPerson.Email
            };

            var personNames          = submitterPerson.GetFullNameFirstLast();
            var primaryContactPerson = projectUpdateBatch.Project.GetPrimaryContact();

            if (primaryContactPerson != null && !String.Equals(primaryContactPerson.Email, submitterPerson.Email, StringComparison.InvariantCultureIgnoreCase))
            {
                emailsToSendTo.Add(primaryContactPerson.Email);
                personNames += $" and {primaryContactPerson.GetFullNameFirstLast()}";
            }
            var contactsWhoCanManageProject = projectUpdateBatch.Project.GetContactsWhoCanManageProject();

            foreach (var contact in contactsWhoCanManageProject)
            {
                if (!string.Equals(contact.Email, submitterPerson.Email, StringComparison.InvariantCultureIgnoreCase) && (primaryContactPerson == null || !string.Equals(contact.Email, primaryContactPerson.Email, StringComparison.InvariantCultureIgnoreCase)))
                {
                    emailsToSendTo.Add(contact.Email);
                    personNames += $" and {contact.GetFullNameFirstLast()}";
                }
            }

            var returnerPerson  = projectUpdateBatch.GetLatestProjectUpdateHistoryReturned().UpdatePerson;
            var instructionsUrl = SitkaRoute <ProjectUpdateController> .BuildAbsoluteUrlHttpsFromExpression(x => x.Instructions(projectUpdateBatch.Project));

            var message = $@"
Dear {personNames},
<p>
    The update submitted for {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} {
                    projectUpdateBatch.Project.GetDisplayName()
                } on {latestProjectUpdateHistorySubmitted.TransitionDate.ToStringDate()} has been returned by {
                    returnerPerson.GetFullNameFirstLastAndOrg()
                }.
</p>
<p>
    <a href=""{instructionsUrl}"">View this {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} update</a>
</p>
<p>
    Please review this update and address the comments that {
                    returnerPerson.FirstName
                } left for you. If you have questions, please email: {returnerPerson.Email}
</p>
Thank you,<br />
{$"- {MultiTenantHelpers.GetToolDisplayName()} team"}
";

            var subject =
                $"The update for {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} {projectUpdateBatch.Project.GetDisplayName()} has been returned - please review and re-submit";
            var mailMessage = new MailMessage {
                Subject = subject, Body = message, IsBodyHtml = true
            };

            SendMessageAndLogNotificationForProjectUpdateTransition(projectUpdateBatch,
                                                                    mailMessage,
                                                                    emailsToSendTo,
                                                                    new List <string> {
                returnerPerson.Email
            },
                                                                    peopleToCc.Select(x => x.Email).ToList(),
                                                                    NotificationType.ProjectUpdateReturned);
        }
예제 #21
0
        public ViewResult ProjectMap()
        {
            List <int> filterValues;
            ProjectLocationFilterType projectLocationFilterType;
            ProjectColorByType        colorByValue;

            var currentPersonCanViewProposals = CurrentFirmaSession.CanViewProposals();

            if (!String.IsNullOrEmpty(Request.QueryString[ProjectMapCustomization.FilterByQueryStringParameter]))
            {
                projectLocationFilterType = ProjectLocationFilterType.ToType(Request
                                                                             .QueryString[ProjectMapCustomization.FilterByQueryStringParameter]
                                                                             .ParseAsEnum <ProjectLocationFilterTypeEnum>());
            }
            else
            {
                projectLocationFilterType = ProjectMapCustomization.DefaultLocationFilterType;
            }

            if (!String.IsNullOrEmpty(Request.QueryString[ProjectMapCustomization.FilterValuesQueryStringParameter]))
            {
                var filterValuesAsString = Request.QueryString[ProjectMapCustomization.FilterValuesQueryStringParameter]
                                           .Split(',');
                filterValues = filterValuesAsString.Select(Int32.Parse).ToList();
            }
            else
            {
                filterValues = GetDefaultFilterValuesForFilterType(projectLocationFilterType.ToEnum, currentPersonCanViewProposals);
            }

            if (!String.IsNullOrEmpty(Request.QueryString[ProjectMapCustomization.ColorByQueryStringParameter]))
            {
                colorByValue = ProjectColorByType.ToType(Request
                                                         .QueryString[ProjectMapCustomization.ColorByQueryStringParameter]
                                                         .ParseAsEnum <ProjectColorByTypeEnum>());
            }
            else
            {
                colorByValue = ProjectMapCustomization.DefaultColorByType;
            }

            var firmaPage = FirmaPageTypeEnum.ProjectMap.GetFirmaPage();

            var projectsToShow = ProjectMapCustomization.ProjectsForMap(currentPersonCanViewProposals, CurrentFirmaSession);

            var initialCustomization =
                new ProjectMapCustomization(projectLocationFilterType, filterValues, colorByValue);
            var projectLocationsLayerGeoJson =
                new LayerGeoJson($"{FieldDefinitionEnum.ProjectLocation.ToType().GetFieldDefinitionLabel()}",
                                 projectsToShow.MappedPointsToGeoJsonFeatureCollection(false, true, true), "red", 1,
                                 LayerInitialVisibility.LayerInitialVisibilityEnum.Show);
            var projectLocationsMapInitJson = new ProjectLocationsMapInitJson(projectLocationsLayerGeoJson,
                                                                              initialCustomization, "ProjectLocationsMap", true);

            // Add Organization Type boundaries according to configuration
            projectLocationsMapInitJson.Layers.AddRange(HttpRequestStorage.DatabaseEntities.Organizations.GetConfiguredBoundaryLayersGeoJson());

            var projectLocationsMapViewData = new ProjectLocationsMapViewData(projectLocationsMapInitJson.MapDivID, null, MultiTenantHelpers.GetTopLevelTaxonomyTiers(), currentPersonCanViewProposals, true);


            var projectLocationFilterTypesAndValues = CreateProjectLocationFilterTypesAndValuesDictionary(currentPersonCanViewProposals);
            var projectLocationsUrl = SitkaRoute <ResultsController> .BuildAbsoluteUrlHttpsFromExpression(x => x.ProjectMap());

            var filteredProjectsWithLocationAreasUrl =
                SitkaRoute <ResultsController> .BuildUrlFromExpression(x => x.FilteredProjectsWithLocationAreas(null));

            var projectColorByTypes = new List <ProjectColorByType> {
                ProjectColorByType.ProjectStage
            };

            if (MultiTenantHelpers.IsTaxonomyLevelTrunk())
            {
                projectColorByTypes.Add(ProjectColorByType.TaxonomyTrunk);
            }
            else if (MultiTenantHelpers.IsTaxonomyLevelBranch())
            {
                projectColorByTypes.Add(ProjectColorByType.TaxonomyBranch);
            }
            var viewData = new ProjectMapViewData(CurrentFirmaSession,
                                                  firmaPage,
                                                  projectLocationsMapInitJson,
                                                  projectLocationsMapViewData,
                                                  projectLocationFilterTypesAndValues,
                                                  projectLocationsUrl, filteredProjectsWithLocationAreasUrl, projectColorByTypes, ProjectColorByType.ProjectStage.GetDisplayNameFieldDefinition());

            return(RazorView <ProjectMap, ProjectMapViewData>(viewData));
        }
예제 #22
0
        public ViewResult ProjectMap()
        {
            List <int> filterValues;
            ProjectLocationFilterType projectLocationFilterType;
            ProjectColorByType        colorByValue;

            var currentPersonCanViewProposals = CurrentPerson.CanViewProposals;

            if (!String.IsNullOrEmpty(Request.QueryString[ProjectMapCustomization.FilterByQueryStringParameter]))
            {
                projectLocationFilterType = ProjectLocationFilterType.ToType(Request
                                                                             .QueryString[ProjectMapCustomization.FilterByQueryStringParameter]
                                                                             .ParseAsEnum <ProjectLocationFilterTypeEnum>());
            }
            else
            {
                projectLocationFilterType = ProjectMapCustomization.DefaultLocationFilterType;
            }

            if (!String.IsNullOrEmpty(Request.QueryString[ProjectMapCustomization.FilterValuesQueryStringParameter]))
            {
                var filterValuesAsString = Request.QueryString[ProjectMapCustomization.FilterValuesQueryStringParameter]
                                           .Split(',');
                filterValues = filterValuesAsString.Select(Int32.Parse).ToList();
            }
            else
            {
                filterValues = ProjectMapCustomization.GetDefaultLocationFilterValues(currentPersonCanViewProposals);
            }

            if (!String.IsNullOrEmpty(Request.QueryString[ProjectMapCustomization.ColorByQueryStringParameter]))
            {
                colorByValue = ProjectColorByType.ToType(Request
                                                         .QueryString[ProjectMapCustomization.ColorByQueryStringParameter]
                                                         .ParseAsEnum <ProjectColorByTypeEnum>());
            }
            else
            {
                colorByValue = ProjectMapCustomization.DefaultColorByType;
            }

            var firmaPage = FirmaPage.GetFirmaPageByPageType(FirmaPageType.ProjectMap);

            var projectsToShow = ProjectMapCustomization.ProjectsForMap(CurrentPerson);

            var initialCustomization =
                new ProjectMapCustomization(projectLocationFilterType, filterValues, colorByValue);
            var projectLocationsLayerGeoJson =
                new LayerGeoJson($"{FieldDefinition.ProjectLocation.GetFieldDefinitionLabel()}",
                                 Project.MappedPointsToGeoJsonFeatureCollection(projectsToShow, true, true), "red", 1,
                                 LayerInitialVisibility.Show);
            var projectLocationsMapInitJson = new ProjectLocationsMapInitJson(projectLocationsLayerGeoJson, initialCustomization, "ProjectLocationsMap");

            projectLocationsMapInitJson.Layers.AddRange(HttpRequestStorage.DatabaseEntities.Organizations.GetBoundaryLayerGeoJson());

            var interactionEventLayer = HttpRequestStorage.DatabaseEntities.InteractionEvents.GetInteractionEventsLayerGeoJson();

            projectLocationsMapInitJson.Layers.Add(interactionEventLayer);
            projectLocationsMapInitJson.Layers.Add(MapInitJson.GetWashingtonCountyLayer());
            projectLocationsMapInitJson.Layers.Add(MapInitJson.GetWashingtonLegislativeDistrictLayer());


            var projectLocationsMapViewData = new ProjectLocationsMapViewData(projectLocationsMapInitJson.MapDivID,
                                                                              colorByValue.DisplayName,
                                                                              MultiTenantHelpers.GetTopLevelTaxonomyTiers(),
                                                                              currentPersonCanViewProposals);


            var projectLocationFilterTypesAndValues = CreateProjectLocationFilterTypesAndValuesDictionary(currentPersonCanViewProposals);
            var projectLocationsUrl = SitkaRoute <ResultsController> .BuildAbsoluteUrlHttpsFromExpression(x => x.ProjectMap());

            var filteredProjectsWithLocationAreasUrl =
                SitkaRoute <ResultsController> .BuildUrlFromExpression(x => x.FilteredProjectsWithLocationAreas(null));

            var projectMapLocationJsons = new List <ProjectMapLocationJson>();
            var filteredProjectList     = projectsToShow.Where(x1 => x1.HasProjectLocationPoint).Where(x => x.ProjectStage.ShouldShowOnMap()).ToList();

            projectMapLocationJsons = filteredProjectList.ToList().Select(p => new ProjectMapLocationJson(p)).ToList();

            var viewData = new ProjectMapViewData(CurrentPerson,
                                                  firmaPage,
                                                  projectLocationsMapInitJson,
                                                  projectLocationsMapViewData,
                                                  projectLocationFilterTypesAndValues,
                                                  projectLocationsUrl,
                                                  filteredProjectsWithLocationAreasUrl,
                                                  projectMapLocationJsons);

            return(RazorView <ProjectMap, ProjectMapViewData>(viewData));
        }
예제 #23
0
        private static void SendExistingKeystoneUserCreatedMessage(Person person, Person currentPerson)
        {
            var toolDisplayName = MultiTenantHelpers.GetToolDisplayName();
            var subject         = $"Invitation to {toolDisplayName}";
            var message         = $@"
<div style='font-size: 12px; font-family: Arial'>
    Welcome {person.FirstName},
    <p>
    You have been invited by a colleague, {currentPerson.GetFullNameFirstLast()}, to check out <a href=""{SitkaRoute<HomeController>.BuildAbsoluteUrlHttpsFromExpression(x => x.Index())}\"">{toolDisplayName}</a>.
</p>
    <p>
    Because you have logged into other systems that use the same log in service (Keystone) that {toolDisplayName} uses, you already have an account, but it needs to be activated for {toolDisplayName}.
    </p>
    <p>
    When you have a moment, please activate your account by logging in:
    </p>
    <strong>Log in here:</strong>  <a href=""{FirmaHelpers.GenerateAbsoluteLogInUrl()}"">{toolDisplayName}</a><br />
    <strong>Your user name is:</strong> {person.LoginName}<br />
    <p>
    If you don't remember your password, you will be able to reset it from the link above.
    </p>
    <p>
    Sincerely,<br />
    The {toolDisplayName} team<br/><br/><img src=""cid:tool-logo"" width=""160"" />
    </p>";
            var mailMessage     = new MailMessage
            {
                From       = new MailAddress(FirmaWebConfiguration.DoNotReplyEmail),
                Subject    = subject,
                Body       = message,
                IsBodyHtml = true
            };

            var tenantAttribute = MultiTenantHelpers.GetTenantAttributeFromCache();
            var toolLogo        = tenantAttribute.TenantSquareLogoFileResourceInfo ??
                                  tenantAttribute.TenantBannerLogoFileResourceInfo;
            var htmlView = AlternateView.CreateAlternateViewFromString(message, null, "text/html");

            htmlView.LinkedResources.Add(
                new LinkedResource(new MemoryStream(toolLogo.FileResourceData.Data), "img/jpeg")
            {
                ContentId = "tool-logo"
            });
            mailMessage.AlternateViews.Add(htmlView);

            mailMessage.ReplyToList.Add(currentPerson.Email);
            mailMessage.To.Add(person.Email);
            SitkaSmtpClient.Send(mailMessage);
        }
        public static void SendApprovalMessage(List <Person> peopleToCc, ProjectUpdateBatch projectUpdateBatch)
        {
            Check.Require(projectUpdateBatch.ProjectUpdateState == ProjectUpdateState.Approved, "Need to be in Approved state to send the Approved email!");
            var latestProjectUpdateHistorySubmitted = projectUpdateBatch.GetLatestProjectUpdateHistorySubmitted();
            var submitterPerson = latestProjectUpdateHistorySubmitted.UpdatePerson;
            var emailsToSendTo  = new List <string> {
                submitterPerson.Email
            };

            var personNames          = submitterPerson.GetFullNameFirstLast();
            var primaryContactPerson = projectUpdateBatch.Project.GetPrimaryContact();

            if (primaryContactPerson != null && !String.Equals(primaryContactPerson.Email, submitterPerson.Email, StringComparison.InvariantCultureIgnoreCase))
            {
                emailsToSendTo.Add(primaryContactPerson.Email);
                personNames += $" and {primaryContactPerson.GetFullNameFirstLast()}";
            }
            var contactsWhoCanManageProject = projectUpdateBatch.Project.GetContactsWhoCanManageProject();

            foreach (var contact in contactsWhoCanManageProject)
            {
                if (!string.Equals(contact.Email, submitterPerson.Email, StringComparison.InvariantCultureIgnoreCase) && (primaryContactPerson == null || !string.Equals(contact.Email, primaryContactPerson.Email, StringComparison.InvariantCultureIgnoreCase)))
                {
                    emailsToSendTo.Add(contact.Email);
                    personNames += $" and {contact.GetFullNameFirstLast()}";
                }
            }

            var approverPerson = projectUpdateBatch.LastUpdatePerson;
            var detailUrl      = SitkaRoute <ProjectController> .BuildAbsoluteUrlHttpsFromExpression(x => x.Detail(projectUpdateBatch.Project));

            var message = $@"
Dear {personNames},
<p>
    The update submitted for {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} {projectUpdateBatch.Project.GetDisplayName()} on {
                    latestProjectUpdateHistorySubmitted.TransitionDate.ToStringDate()
                } was approved by {approverPerson.GetFullNameFirstLastAndOrg()}.
</p>
<p>
    There is no action for you to take - this is simply a notification email. The updates for this {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} are now visible to the general public on this {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()}'s detail page:
</p>
<p>
    <a href=""{detailUrl}"">View this {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()}</a>
</p>
Thank you for keeping your {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} information and accomplishments up to date!<br />
{$"- {MultiTenantHelpers.GetToolDisplayName()} team"}<br/><br/><img src=""cid:tool-logo"" width=""160"" />
";

            var subject     = $"The update for {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} {projectUpdateBatch.Project.GetDisplayName()} was approved";
            var mailMessage = new MailMessage {
                Subject = subject, Body = message, IsBodyHtml = true
            };

            var tenantAttribute = MultiTenantHelpers.GetTenantAttributeFromCache();
            var toolLogo        = tenantAttribute.TenantSquareLogoFileResourceInfo ??
                                  tenantAttribute.TenantBannerLogoFileResourceInfo;
            var htmlView = AlternateView.CreateAlternateViewFromString(message, null, "text/html");

            htmlView.LinkedResources.Add(
                new LinkedResource(new MemoryStream(toolLogo.FileResourceData.Data), "img/jpeg")
            {
                ContentId = "tool-logo"
            });
            mailMessage.AlternateViews.Add(htmlView);

            SendMessageAndLogNotificationForProjectUpdateTransition(projectUpdateBatch,
                                                                    mailMessage,
                                                                    emailsToSendTo,
                                                                    new List <string> {
                approverPerson.Email
            },
                                                                    peopleToCc.Select(x => x.Email).ToList(),
                                                                    NotificationType.ProjectUpdateApproved);
        }
예제 #25
0
        private static void SendExistingKeystoneUserCreatedMessage(Person person, Person currentPerson)
        {
            var toolDisplayName = MultiTenantHelpers.GetToolDisplayName();
            var subject         = $"Invitation to {toolDisplayName}";
            var message         = $@"
<div style='font-size: 12px; font-family: Arial'>
    Welcome {person.FirstName},
    <p>
    You have been invited by a colleague, {currentPerson.GetFullNameFirstLast()}, to check out <a href=""{SitkaRoute<HomeController>.BuildAbsoluteUrlHttpsFromExpression(x => x.Index())}\"">{toolDisplayName}</a>.
</p>
    <p>
    Because you have logged into other systems that use the same log in service (Keystone) that {toolDisplayName} uses, you already have an account, but it needs to be activated for {toolDisplayName}.
    </p>
    <p>
    When you have a moment, please activate your account by logging in:
    </p>
    <strong>Log in here:</strong>  <a href=""{FirmaHelpers.GenerateAbsoluteLogInUrl()}"">{toolDisplayName}</a><br />
    <strong>Your user name is:</strong> {person.LoginName}<br />
    <p>
    If you don't remember your password, you will be able to reset it from the link above.
    </p>
    <p>
    Sincerely,<br />
    The {toolDisplayName} team
    </p>";
            var mailMessage     = new MailMessage
            {
                From       = new MailAddress(FirmaWebConfiguration.DoNotReplyEmail),
                Subject    = subject,
                Body       = message,
                IsBodyHtml = true
            };

            mailMessage.ReplyToList.Add(currentPerson.Email);
            mailMessage.To.Add(person.Email);
            SitkaSmtpClient.Send(mailMessage);
        }
        public void SendMessage(string ipAddress, string userAgent, string currentUrl, SupportRequestType supportRequestType, Project project)
        {
            var subject           = $"Support Request for Project Firma - {DateTime.Now.ToStringDateTime()}";
            var projectSummaryUrl = project == null
                ? string.Empty
                : $"<strong>{FieldDefinition.Project.GetFieldDefinitionLabel()}:</strong> <a href=\"{SitkaRoute<ProjectController>.BuildAbsoluteUrlHttpsFromExpression(x => x.Detail(project))}\">{project.DisplayName}</a><br />";
            var message = string.Format(@"
<div style='font-size: 12px; font-family: Arial'>
    <strong>{0}</strong><br />
    <br />
    <strong>From:</strong> {1} - {2}<br />
    <strong>Email:</strong> {3}<br />
    <strong>Phone:</strong> {4}<br />
    {5}
    <br />
    <strong>Subject:</strong> {6}<br />
    <br />
    <strong>Description:</strong><br />
    {7}
    <br />
    <br />
    <br />
    <div style='font-size: 10px; color: gray'>
    OTHER DETAILS:<br />
    LOGIN: {8}<br />
    IP ADDRESS: {9}<br />
    USERAGENT: {10}<br />
    URL FROM: {11}<br />
    <br />
    </div>
    <div>You received this email because you are set up as a point of contact for support - if that's not correct, let us know: {12}</div>.
</div>
", subject, RequestPersonName, RequestPersonOrganization ?? "(not provided)", RequestPersonEmail, RequestPersonPhone ?? "(not provided)", projectSummaryUrl,
                                        supportRequestType.SupportRequestTypeDisplayName,
                                        RequestDescription.HtmlEncodeWithBreaks(),
                                        RequestPerson != null ? $"{RequestPerson.FullNameFirstLast} (UserID {RequestPerson.PersonID})" : "(anonymous user)",
                                        ipAddress,
                                        userAgent,
                                        currentUrl,
                                        Common.FirmaWebConfiguration.SitkaSupportEmail);
            // Create Notification
            var mailMessage = new MailMessage {
                From = new MailAddress(Common.FirmaWebConfiguration.DoNotReplyEmail), Subject = subject, Body = message, IsBodyHtml = true
            };

            // Reply-To Header
            mailMessage.ReplyToList.Add(RequestPersonEmail);

            // TO field
            SupportRequestType.SetEmailRecipientsOfSupportRequest(mailMessage);

            SitkaSmtpClient.Send(mailMessage);
        }
예제 #27
0
        public ActionResult Invite(InviteViewModel viewModel)
        {
            var toolDisplayName = MultiTenantHelpers.GetToolDisplayName();
            var homeUrl         = SitkaRoute <HomeController> .BuildAbsoluteUrlHttpsFromExpression(x => x.Index());

            var supportUrl = SitkaRoute <HelpController> .BuildAbsoluteUrlHttpsFromExpression(x => x.RequestSupport());

            var tenantAttribute        = MultiTenantHelpers.GetTenantAttributeFromCache();
            var primaryContactFullName = tenantAttribute.PrimaryContactPerson
                                         .GetFullNameFirstLast();
            var primaryContactOrganizationName = tenantAttribute.PrimaryContactPerson
                                                 .Organization.OrganizationName;
            var primaryContactEmail = tenantAttribute.PrimaryContactPerson.Email;

            KeystoneService.KeystoneApiResponse <KeystoneService.KeystoneNewUserModel> keystoneNewUserResponse = null;

            var theSelectedOrganization = HttpRequestStorage.DatabaseEntities.Organizations.GetOrganization(viewModel.OrganizationID);

            Check.EnsureNotNull(theSelectedOrganization);
            bool organizationSelectedIsNotUnknownOrg = !theSelectedOrganization.IsUnknown();

            if (organizationSelectedIsNotUnknownOrg && theSelectedOrganization.KeystoneOrganizationGuid == null)
            {
                // If we pick an Org, it must already be in Keystone, and so the local dbo.Organization must have a valid OrganizationGuid
                ModelState.AddModelError("OrganizationID", $"Organization is not in Keystone");
            }
            else
            {
                var inviteModel = new KeystoneService.KeystoneInviteModel
                {
                    FirstName   = viewModel.FirstName,
                    LastName    = viewModel.LastName,
                    Email       = viewModel.Email,
                    SiteName    = toolDisplayName,
                    Subject     = $"Invitation to {toolDisplayName}",
                    WelcomeText =
                        $"You have been invited by {CurrentPerson.GetFullNameFirstLast()} at {CurrentPerson.Organization.OrganizationName} ({CurrentPerson.Email}), to create an account in <a href=\"{homeUrl}\">{toolDisplayName}</a>.",
                    RedirectURL      = homeUrl,
                    SupportBlock     = $"If you have any questions, please visit our <a href=\"{supportUrl}\">support page</a> or contact {primaryContactFullName} at {primaryContactOrganizationName} ({primaryContactEmail})",
                    OrganizationGuid = theSelectedOrganization.KeystoneOrganizationGuid,
                    SignatureBlock   = $"The {toolDisplayName} team"
                };

                var keystoneService = new KeystoneService(HttpRequestStorage.GetHttpContextUserThroughOwin());
                keystoneNewUserResponse = keystoneService.Invite(inviteModel);
                if (keystoneNewUserResponse.StatusCode != HttpStatusCode.OK || keystoneNewUserResponse.Error != null)
                {
                    ModelState.AddModelError("Email", $"There was a problem inviting the user to Keystone: {keystoneNewUserResponse.Error.Message}.");
                    if (keystoneNewUserResponse.Error.ModelState != null)
                    {
                        foreach (var modelStateKey in keystoneNewUserResponse.Error.ModelState.Keys)
                        {
                            foreach (var err in keystoneNewUserResponse.Error.ModelState[modelStateKey])
                            {
                                ModelState.AddModelError(modelStateKey, err);
                            }
                        }
                    }
                }
                else
                {
                    // Sanity check - did we get back the same Organization GUID we asked for?
                    // (The GUID could also be null here, for the unknown org, but in that case we'll also get back null so this check is still valid.)
                    var keystoneUserTmp = keystoneNewUserResponse.Payload.Claims;
                    if (keystoneUserTmp.OrganizationGuid != inviteModel.OrganizationGuid)
                    {
                        string errorMessage = $"There was a problem with the Keystone Organization GUID Invited:{inviteModel.OrganizationGuid} Received back: {keystoneUserTmp.OrganizationGuid}. Please contact Sitka for assistance.";
                        _logger.Error(errorMessage);
                        ModelState.AddModelError("OrganizationID", errorMessage);
                    }
                }
            }

            if (!ModelState.IsValid)
            {
                return(ViewInvite(viewModel));
            }

            var keystoneUser = keystoneNewUserResponse.Payload.Claims;
            var existingUser = HttpRequestStorage.DatabaseEntities.People.GetPersonByPersonGuid(keystoneUser.UserGuid);

            if (existingUser != null)
            {
                SetMessageForDisplay($"{existingUser.GetFullNameFirstLastAndOrgAsUrl(CurrentFirmaSession)} already has an account.</a>.");
                return(RedirectToAction(new SitkaRoute <UserController>(x => x.Detail(existingUser))));
            }

            var newUser = CreateNewFirmaPerson(keystoneUser, keystoneUser.OrganizationGuid);

            HttpRequestStorage.DatabaseEntities.SaveChanges();

            newUser.RoleID = Role.Normal.RoleID;

            HttpRequestStorage.DatabaseEntities.SaveChanges();

            if (!viewModel.DoNotSendInviteEmailIfExisting && !keystoneNewUserResponse.Payload.Created)
            {
                SendExistingKeystoneUserCreatedMessage(newUser, CurrentPerson);
            }

            SetMessageForDisplay(
                $"{newUser.GetFullNameFirstLastAndOrgAsUrl(CurrentFirmaSession)} successfully added. You may want to assign them a role</a>.");
            return(RedirectToAction(new SitkaRoute <UserController>(x => x.Detail(newUser))));
        }
예제 #28
0
        public ActionResult Invite(InviteViewModel viewModel)
        {
            var toolDisplayName = "Orange County Stormwater Tools";
            var homeUrl         = SitkaRoute <HomeController> .BuildAbsoluteUrlHttpsFromExpression(x => x.Index(), NeptuneWebConfiguration.CanonicalHostNameRoot);

            var loginUrl =
                SitkaRoute <AccountController> .BuildAbsoluteUrlHttpsFromExpression(x => x.LogOn(),
                                                                                    NeptuneWebConfiguration.CanonicalHostName);

            var supportUrl = SitkaRoute <HelpController> .BuildAbsoluteUrlHttpsFromExpression(x => x.Support(), NeptuneWebConfiguration.CanonicalHostNameRoot);

            var inviteModel = new KeystoneService.KeystoneInviteModel
            {
                FirstName        = viewModel.FirstName,
                LastName         = viewModel.LastName,
                Email            = viewModel.Email,
                SiteName         = toolDisplayName,
                Subject          = $"Invitation to the {toolDisplayName}",
                WelcomeText      = $"You have been invited by a colleague to create an account in the <a href=\"{homeUrl}\">{toolDisplayName}</a>. The {toolDisplayName} application is a collaborative effort of Orange County Public Works, MS4 Permittees, and other organizations.",
                RedirectURL      = loginUrl,
                SupportBlock     = $"If you have any questions, please visit our <a href=\"{supportUrl}\">support page</a>",
                OrganizationGuid = viewModel.OrganizationGuid,
                SignatureBlock   = $"The {toolDisplayName} team"
            };

            var keystoneService = new KeystoneService(HttpRequestStorage.GetHttpContextUserThroughOwin());
            var response        = keystoneService.Invite(inviteModel);

            if (response.StatusCode != HttpStatusCode.OK || response.Error != null)
            {
                ModelState.AddModelError("Email", $"There was a problem inviting the user to Keystone: {response.Error.Message}.");
                if (response.Error.ModelState != null)
                {
                    foreach (var modelStateKey in response.Error.ModelState.Keys)
                    {
                        foreach (var err in response.Error.ModelState[modelStateKey])
                        {
                            ModelState.AddModelError(modelStateKey, err);
                        }
                    }
                }
            }

            if (!ModelState.IsValid)
            {
                return(ViewInvite(viewModel));
            }

            var keystoneUser = response.Payload.Claims;
            var existingUser = HttpRequestStorage.DatabaseEntities.People.GetPersonByPersonGuid(keystoneUser.UserGuid);

            if (existingUser != null)
            {
                SetMessageForDisplay($"{existingUser.GetFullNameFirstLastAndOrgAsUrl()} already has an account.</a>.");
                return(RedirectToAction(new SitkaRoute <UserController>(x => x.Detail(existingUser))));
            }

            var setJurisdictions = !CurrentPerson.IsAdministrator();
            var newUser          = CreateNewFirmaPerson(keystoneUser, keystoneUser.OrganizationGuid);

            HttpRequestStorage.DatabaseEntities.SaveChanges();

            if (setJurisdictions)
            {
                foreach (var stormwaterJurisdictionPerson in CurrentPerson.StormwaterJurisdictionPeople)
                {
                    newUser.StormwaterJurisdictionPeople.Add(new StormwaterJurisdictionPerson(stormwaterJurisdictionPerson.StormwaterJurisdictionID, newUser.PersonID));
                }
            }

            newUser.RoleID = Role.JurisdictionEditor.RoleID;

            HttpRequestStorage.DatabaseEntities.SaveChanges();

            SetMessageForDisplay(
                $"{newUser.GetFullNameFirstLastAndOrgAsUrl()} successfully added. You may want to assign them a role</a>.");
            return(RedirectToAction(new SitkaRoute <UserController>(x => x.Detail(newUser))));
        }