コード例 #1
0
        /// <summary>
        /// Call for page with associated FirmaPage
        /// </summary>
        protected FirmaViewData(Person currentPerson, Models.FirmaPage firmaPage)
        {
            FirmaPage = firmaPage;

            CurrentPerson = currentPerson;
            FirmaHomeUrl  = SitkaRoute <HomeController> .BuildUrlFromExpression(c => c.Index());

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

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

            MakeFirmaMenu(currentPerson);

            FullProjectListUrl = SitkaRoute <ProjectController> .BuildUrlFromExpression(c => c.Index());

            ProjectSearchUrl = SitkaRoute <ProjectController> .BuildUrlFromExpression(c => c.Search(UrlTemplate.Parameter1String));

            ProjectFindUrl = SitkaRoute <ProjectController> .BuildUrlFromExpression(c => c.Find(string.Empty));

            var currentPersonCanManage = new FirmaPageManageFeature().HasPermission(currentPerson, firmaPage).HasPermission;

            ViewPageContentViewData = firmaPage != null ? new ViewPageContentViewData(firmaPage, currentPersonCanManage) : null;
            CustomFooterViewData    =
                new ViewPageContentViewData(Models.FirmaPage.GetFirmaPageByPageType(FirmaPageType.CustomFooter),
                                            currentPersonCanManage);
            TenantName          = MultiTenantHelpers.GetTenantName();
            TenantDisplayName   = MultiTenantHelpers.GetTenantDisplayName();
            TenantBannerLogoUrl = MultiTenantHelpers.GetTenantBannerLogoUrl();
        }
コード例 #2
0
        public static List <string> ValidateImpl(string explanation, List <int> expectedYears,
                                                 List <IFundingSourceExpenditure> projectFundingSourceExpenditures)
        {
            var errors = new List <string>();
            // Need to get FundingSources by IDs because we may have unsaved projectFundingSourceExpenditures that won't have a reference to the entity
            var fundingSourcesIDs = projectFundingSourceExpenditures.Select(x => x.FundingSourceID).Distinct().ToList();
            var fundingSources    =
                HttpRequestStorage.DatabaseEntities.FundingSources.Where(x => fundingSourcesIDs.Contains(x.FundingSourceID));

            var missingFundingSourceYears = new Dictionary <ProjectFirmaModels.Models.FundingSource, IEnumerable <int> >();

            foreach (var fundingSource in fundingSources)
            {
                var currentFundingSource = fundingSource;
                var missingYears         =
                    expectedYears
                    .GetMissingYears(projectFundingSourceExpenditures
                                     .Where(x => x.FundingSourceID == currentFundingSource.FundingSourceID)
                                     .Select(x => x.CalendarYear)).ToList();

                if (missingYears.Any())
                {
                    missingFundingSourceYears.Add(currentFundingSource, missingYears);
                }
            }

            foreach (var fundingSource in missingFundingSourceYears)
            {
                var yearsForErrorDisplay = string.Join(", ", FirmaHelpers.CalculateYearRanges(fundingSource.Value));
                errors.Add($"Missing Expenditures for {FieldDefinitionEnum.FundingSource.ToType().GetFieldDefinitionLabel()} '{fundingSource.Key.GetDisplayName()}' for the following years: {string.Join(", ", yearsForErrorDisplay)}. If there are no expenditures to report, save the form with zeros.");
            }

            return(errors);
        }
コード例 #3
0
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            var redirectToLogin = new RedirectResult(FirmaHelpers.GenerateLogInUrlWithReturnUrl());

            if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
            {
                filterContext.Result = redirectToLogin;
                return;
            }
            throw new SitkaRecordNotAuthorizedException($"You are not authorized for feature \"{FeatureName}\". Log out and log in as a different user or request additional permissions.");
        }
コード例 #4
0
        /// <summary>
        /// Call for page with associated FirmaPage
        /// </summary>
        protected FirmaViewData(FirmaSession currentFirmaSession, ProjectFirmaModels.Models.FirmaPage firmaPage)
        {
            FirmaPage = firmaPage;

            //CurrentPerson = currentPerson;
            CurrentFirmaSession = currentFirmaSession;
            FirmaHomeUrl        = SitkaRoute <HomeController> .BuildUrlFromExpression(c => c.Index());

            LogInUrl  = FirmaHelpers.GenerateLogInUrl();
            LogOutUrl = FirmaHelpers.GenerateLogOutUrlWithReturnUrl();

            CurrentUrl         = HttpContext.Current.Request.Url;
            ForgotPasswordUrl  = FirmaHelpers.GenerateForgotPasswordUrlWithReturnUrl(CurrentUrl.AbsoluteUri);
            RegisterAccountUrl = FirmaHelpers.GenerateCreateAccountWithReturnUrl(CurrentUrl.AbsoluteUri);

            QaUrl    = MultiTenantHelpers.GetRelativeUrlForEnvironment(CurrentUrl, FirmaEnvironmentType.Qa);
            LocalUrl = MultiTenantHelpers.GetRelativeUrlForEnvironment(CurrentUrl, FirmaEnvironmentType.Local);
            ProdUrl  = MultiTenantHelpers.GetRelativeUrlForEnvironment(CurrentUrl, FirmaEnvironmentType.Prod);

            TenantSimples = MultiTenantHelpers.GetAllTenantSimples().Where(ts => ts.ShowTenantInSwitcherDropdown).ToList();

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

            MakeFirmaMenu(currentFirmaSession);

            FullProjectListUrl = SitkaRoute <ProjectController> .BuildUrlFromExpression(c => c.Index());

            ProjectSearchUrl = SitkaRoute <ProjectController> .BuildUrlFromExpression(c => c.Search(UrlTemplate.Parameter1String));

            ProjectFindUrl = SitkaRoute <ProjectController> .BuildUrlFromExpression(c => c.Find(string.Empty));

            var currentPersonCanManage = new FirmaPageManageFeature().HasPermission(currentFirmaSession, firmaPage).HasPermission;

            ViewPageContentViewData = firmaPage != null ? new ViewPageContentViewData(firmaPage, currentPersonCanManage) : null;
            CustomFooterViewData    = new CustomFooterViewData(FirmaPageTypeEnum.CustomFooter.GetFirmaPage(), currentPersonCanManage, this.CurrentFirmaSession);
            TenantName             = MultiTenantHelpers.GetTenantName();
            TenantShortDisplayName = MultiTenantHelpers.GetTenantShortDisplayName();
            TenantBannerLogoUrl    = MultiTenantHelpers.GetTenantBannerLogoUrl();
            TenantToolDisplayName  = MultiTenantHelpers.GetToolDisplayName();
            ShowTenantDropdown     =
                // Tenant dropdown can be globally disabled if necessary. (Reclamation needs this, and so might other hard-ish forks.)
                FirmaWebConfiguration.TenantDropdownEnabled &&
                (FirmaWebConfiguration.FirmaEnvironment.FirmaEnvironmentType == FirmaEnvironmentType.Local ||
                 CurrentFirmaSession.IsSitkaAdministrator());
            ShowEnvironmentLabel    = FirmaWebConfiguration.FirmaEnvironment.FirmaEnvironmentType != FirmaEnvironmentType.Prod;
            ShowEnvironmentDropdown =
                FirmaWebConfiguration.FirmaEnvironment.FirmaEnvironmentType == FirmaEnvironmentType.Local ||
                CurrentFirmaSession.IsSitkaAdministrator();
            FirmaIncludesViewData = new FirmaIncludesViewData();
        }
コード例 #5
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);
        }
コード例 #6
0
        public IEnumerable <ValidationResult> Validate(ValidationContext validationContext)
        {
            var editContactViewModel = (EditContactViewModel)validationContext.ObjectInstance;
            var thePersonBeingEdited = HttpRequestStorage.DatabaseEntities.People.SingleOrDefault(p => p.PersonID == editContactViewModel.PersonID);

            if (Phone != null)
            {
                Regex strip             = new Regex(@"[()\-\s]"); // don't worry about whitespace characters or "phone-number" characters
                var   phoneNumberToTest = strip.Replace(Phone, "");
                if (phoneNumberToTest.Length != 10 ||             //number of digits in an american phone number
                    !phoneNumberToTest.All(char.IsDigit))         // phone numbers must be digits
                {
                    yield return(new SitkaValidationResult <EditContactViewModel, string>("Phone Number was invalid.", m => m.Phone));
                }
            }

            bool emailProvided = Email != null;

            if (emailProvided && !FirmaHelpers.IsValidEmail(Email))
            {
                yield return(new SitkaValidationResult <EditContactViewModel, string>("Email Address was invalid.", m => m.Email));
            }

            // If Person record is being created, or email is being changed, make sure someone does not already have the given email address
            bool existingUserHasGivenEmailAddressAlready = HttpRequestStorage.DatabaseEntities.People.Any(p => p.Email == Email);
            bool personIsBeingCreated = thePersonBeingEdited == null;

            // Create case
            if (emailProvided && personIsBeingCreated && existingUserHasGivenEmailAddressAlready)
            {
                yield return(new SitkaValidationResult <EditContactViewModel, string>($"Email Address \"{Email}\" already in use.", m => m.Email));
            }

            // Edit case
            if (!personIsBeingCreated)
            {
                bool personsEmailIsChanging = thePersonBeingEdited.Email != Email;
                if (emailProvided && personsEmailIsChanging && existingUserHasGivenEmailAddressAlready)
                {
                    yield return(new SitkaValidationResult <EditContactViewModel, string>($"Email Address \"{Email}\" already in use.", m => m.Email));
                }
            }
        }
コード例 #7
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);
        }
コード例 #8
0
        public static List <string> ValidateImpl(List <ProjectExemptReportingYearSimple> projectExemptReportingYearSimples,
                                                 string explanation,
                                                 List <int> expectedYears,
                                                 List <IGrantAllocationExpenditure> projectGrantAllocationExpenditures)
        {
            var errors = new List <string>();

            var grantAllocationsIDs = projectGrantAllocationExpenditures.Select(x => x.GrantAllocationID).Distinct().ToList();
            var grantAllocations    = HttpRequestStorage.DatabaseEntities.GrantAllocations.Where(x => grantAllocationsIDs.Contains(x.GrantAllocationID));

            // validation 1: ensure that we have expenditure values from ProjectUpdate start year to min(endyear, currentyear)
            if (projectExemptReportingYearSimples.Any(x => x.IsExempt) && string.IsNullOrWhiteSpace(explanation))
            {
                errors.Add(FirmaValidationMessages.ExplanationNecessaryForProjectExemptYears);
            }

            if (!projectExemptReportingYearSimples.Any(x => x.IsExempt) && !string.IsNullOrWhiteSpace(explanation))
            {
                errors.Add(FirmaValidationMessages.ExplanationNotNecessaryForProjectExemptYears);
            }

            var exemptReportingYears = projectExemptReportingYearSimples.Where(y => y.IsExempt).Select(y => y.CalendarYear).ToList();

            var everyYearIsExempt = exemptReportingYears.Count == expectedYears.Count;

            if (!everyYearIsExempt)
            {
                if (grantAllocations.Any())
                {
                    var missingGrantAllocationYears = new Dictionary <Models.GrantAllocation, IEnumerable <int> >();
                    foreach (var currentGrantAllocation in grantAllocations)
                    {
                        //Added check for 0 to prevent a user from submitting a 0 value with no comment
                        var yearsWithValues = projectGrantAllocationExpenditures
                                              .Where(x => x.GrantAllocationID == currentGrantAllocation.GrantAllocationID &&
                                                     x.ExpenditureAmount > 0)
                                              .Select(x => x.CalendarYear);
                        var missingYears =
                            expectedYears
                            .GetMissingYears(yearsWithValues).ToList()
                            .Where(year =>
                                   !exemptReportingYears.Contains(year)).ToList();

                        if (missingYears.Any())
                        {
                            missingGrantAllocationYears.Add(currentGrantAllocation, missingYears);
                        }
                    }

                    foreach (var grantAllocation in missingGrantAllocationYears)
                    {
                        var yearsForErrorDisplay = string.Join(", ", FirmaHelpers.CalculateYearRanges(grantAllocation.Value));
                        errors.Add($"Missing Expenditures for {Models.FieldDefinition.GrantAllocation.GetFieldDefinitionLabel()} '{grantAllocation.Key.DisplayName}' for the following years: {string.Join(", ", yearsForErrorDisplay)}");
                    }
                }
            }


            // reported expenditures in exempt years - Added check for 0 to prevent a user from submitting a 0 value with no comment
            var yearsWithExpenditures = projectGrantAllocationExpenditures.Where(x => x.ExpenditureAmount > 0).GroupBy(x => x.GrantAllocationID);

            foreach (var grantAllocation in yearsWithExpenditures)
            {
                var exemptYearsWithReportedValues = grantAllocation
                                                    .Where(x => exemptReportingYears.Contains(x.CalendarYear)).Select(x => x.CalendarYear)
                                                    .ToList();
                if (exemptYearsWithReportedValues.Any())
                {
                    var grantAllocationName  = grantAllocations.SingleOrDefault(x => x.GrantAllocationID == grantAllocation.Key)?.GrantAllocationName;
                    var yearsForErrorDisplay = string.Join(", ", FirmaHelpers.CalculateYearRanges(exemptYearsWithReportedValues));
                    errors.Add($"Grant Allocation {grantAllocationName} has reported values for the exempt years: {yearsForErrorDisplay}");
                }
            }

            return(errors);
        }
コード例 #9
0
        public static List <string> ValidateExpendituresByCostType(this ProjectUpdateBatch projectUpdateBatch)
        {
            if (!projectUpdateBatch.AreProjectBasicsValid())
            {
                return(new List <string> {
                    FirmaValidationMessages.UpdateSectionIsDependentUponBasicsSection
                });
            }

            if (projectUpdateBatch.ProjectUpdate.ProjectStage.RequiresReportedExpenditures() || projectUpdateBatch.ProjectUpdate.ProjectStage == ProjectStage.Completed)
            {
                // validation 1: ensure that we have expenditure values from ProjectUpdate start year to min(endyear, currentyear)
                var yearsExpected = projectUpdateBatch.ProjectUpdate.GetProjectUpdatePlanningDesignStartToCompletionYearRange();
                List <IFundingSourceExpenditure> projectFundingSourceExpenditures = new List <IFundingSourceExpenditure>(projectUpdateBatch.ProjectFundingSourceExpenditureUpdates);
                var errors = new List <string>();
                // Need to get FundingSources by IDs because we may have unsaved projectFundingSourceExpenditures that won't have a reference to the entity
                var fundingSourcesIDs = projectFundingSourceExpenditures.Select(x => x.FundingSourceID).Distinct().ToList();
                var fundingSources    =
                    HttpRequestStorage.DatabaseEntities.FundingSources.Where(x => fundingSourcesIDs.Contains(x.FundingSourceID));

                if (!projectFundingSourceExpenditures.Any())
                {
                    if (string.IsNullOrWhiteSpace(projectUpdateBatch.ExpendituresNote))
                    {
                        errors.Add(FirmaValidationMessages.ExplanationNecessaryForProjectExemptYears);
                    }
                }
                else
                {
                    if (!fundingSources.Any())
                    {
                        var yearsForErrorDisplay = string.Join(", ", FirmaHelpers.CalculateYearRanges(yearsExpected));
                        errors.Add($"Missing Expenditures for {string.Join(", ", yearsForErrorDisplay)}");
                    }
                    else
                    {
                        var missingFundingSourceYears =
                            new Dictionary <ProjectFirmaModels.Models.FundingSource, IEnumerable <int> >();
                        foreach (var fundingSource in fundingSources)
                        {
                            var currentFundingSource = fundingSource;
                            var missingYears         =
                                yearsExpected
                                .GetMissingYears(projectFundingSourceExpenditures
                                                 .Where(x => x.FundingSourceID == currentFundingSource.FundingSourceID)
                                                 .Select(x => x.CalendarYear)).ToList();

                            if (missingYears.Any())
                            {
                                missingFundingSourceYears.Add(currentFundingSource, missingYears);
                            }
                        }

                        foreach (var fundingSource in missingFundingSourceYears)
                        {
                            var yearsForErrorDisplay =
                                string.Join(", ", FirmaHelpers.CalculateYearRanges(fundingSource.Value));
                            errors.Add(
                                $"Missing Expenditures for {FieldDefinitionEnum.FundingSource.ToType().GetFieldDefinitionLabel()} '{fundingSource.Key.GetDisplayName()}' for the following years: {string.Join(", ", yearsForErrorDisplay)}");
                        }
                    }
                }

                return(errors);
            }
            return(new List <string>());
        }