public virtual async Task SavePresumedScopeAsync(ScopingViewModel model, int snapshotYear) { if (string.IsNullOrWhiteSpace(model.EnterCodes.EmployerReference)) { throw new ArgumentNullException(nameof(model.EnterCodes.EmployerReference)); } if (model.IsSecurityCodeExpired) { throw new ArgumentOutOfRangeException(nameof(model.IsSecurityCodeExpired)); } // get the organisation by EmployerReference var org = await GetOrgByEmployerReferenceAsync(model.EnterCodes.EmployerReference); if (org == null) { throw new ArgumentOutOfRangeException( nameof(model.EnterCodes.EmployerReference), $"Cannot find organisation with EmployerReference: {model.EnterCodes.EmployerReference} in the database"); } // can only save a presumed scope in the prev or current snapshot year var currentSnapshotDate = _sharedBusinessLogic.GetAccountingStartDate(org.SectorType); if (snapshotYear > currentSnapshotDate.Year || snapshotYear < currentSnapshotDate.Year - 1) { throw new ArgumentOutOfRangeException(nameof(snapshotYear)); } // skip saving a presumed scope when an active scope already exists for the snapshot year if (await ScopeBusinessLogic.GetLatestScopeBySnapshotYearAsync(org.OrganisationId, snapshotYear) != null) { return; } // create the new OrganisationScope var newScope = new OrganisationScope { OrganisationId = org.OrganisationId, ContactEmailAddress = model.EnterAnswers.EmailAddress, ContactFirstname = model.EnterAnswers.FirstName, ContactLastname = model.EnterAnswers.LastName, ReadGuidance = model.EnterAnswers.HasReadGuidance(), Reason = "", ScopeStatus = model.IsOutOfScopeJourney ? ScopeStatuses.PresumedOutOfScope : ScopeStatuses.PresumedInScope, CampaignId = model.CampaignId, // set the snapshot date according to sector SnapshotDate = _sharedBusinessLogic.GetAccountingStartDate(org.SectorType, snapshotYear), StatusDetails = "Generated by the system" }; // save the presumed scope await ScopeBusinessLogic.SaveScopeAsync(org, true, newScope); }
public static IScopeBusinessLogic CreateFakeScopeBusinessLogic() { var fakeSharedBusinessLogic = CreateFakeSharedBusinessLogic(); var fakeSearchBusinessLogic = CreateFakeSearchBusinessLogic(); var fakeScopeBusinessLogic = new ScopeBusinessLogic(fakeSharedBusinessLogic, fakeSharedBusinessLogic.DataRepository, fakeSearchBusinessLogic, null); return(fakeScopeBusinessLogic); }
public virtual async Task SaveScopesAsync(ScopingViewModel model, IEnumerable <int> snapshotYears) { if (string.IsNullOrWhiteSpace(model.EnterCodes.EmployerReference)) { throw new ArgumentNullException(nameof(model.EnterCodes.EmployerReference)); } if (model.IsSecurityCodeExpired) { throw new ArgumentOutOfRangeException(nameof(model.IsSecurityCodeExpired)); } if (!snapshotYears.Any()) { throw new ArgumentNullException(nameof(snapshotYears)); } //Get the organisation with this employer reference var org = model.OrganisationId == 0 ? null : await _sharedBusinessLogic.DataRepository.FirstOrDefaultAsync <Organisation>(o => o.OrganisationId == model.OrganisationId); if (org == null) { throw new ArgumentOutOfRangeException( nameof(model.OrganisationId), $"Cannot find organisation with Id: {model.OrganisationId} in the database"); } var newScopes = new List <OrganisationScope>(); foreach (var snapshotYear in snapshotYears.OrderByDescending(y => y)) { var scope = new OrganisationScope { OrganisationId = org.OrganisationId, ContactEmailAddress = model.EnterAnswers.EmailAddress, ContactFirstname = model.EnterAnswers.FirstName, ContactLastname = model.EnterAnswers.LastName, ReadGuidance = model.EnterAnswers.HasReadGuidance(), Reason = model.EnterAnswers.Reason != "Other" ? model.EnterAnswers.Reason : model.EnterAnswers.OtherReason, ScopeStatus = model.IsOutOfScopeJourney ? ScopeStatuses.OutOfScope : ScopeStatuses.InScope, CampaignId = model.CampaignId, // set the snapshot date according to sector SnapshotDate = _sharedBusinessLogic.GetAccountingStartDate(org.SectorType, snapshotYear) }; newScopes.Add(scope); } await ScopeBusinessLogic.SaveScopesAsync(org, newScopes); await _searchBusinessLogic.UpdateSearchIndexAsync(org); }
public virtual ScopingViewModel CreateScopingViewModel(Organisation org, User currentUser) { if (org == null) { throw new ArgumentNullException(nameof(org)); } var model = new ScopingViewModel { OrganisationId = org.OrganisationId, DUNSNumber = org.DUNSNumber, OrganisationName = org.OrganisationName, OrganisationAddress = org.LatestAddress?.GetAddressString(), AccountingDate = _sharedBusinessLogic.GetAccountingStartDate(org.SectorType) }; model.EnterCodes.EmployerReference = org.EmployerReference; // get the scope info for this year var scope = ScopeBusinessLogic.GetLatestScopeBySnapshotYear(org, model.AccountingDate.Year); if (scope != null) { model.ThisScope = new ScopeViewModel { OrganisationScopeId = scope.OrganisationScopeId, ScopeStatus = scope.ScopeStatus, StatusDate = scope.ScopeStatusDate, RegisterStatus = scope.RegisterStatus, SnapshotDate = scope.SnapshotDate } } ; // get the scope info for last year scope = ScopeBusinessLogic.GetLatestScopeBySnapshotYear(org, model.AccountingDate.Year - 1); if (scope != null) { model.LastScope = new ScopeViewModel { OrganisationScopeId = scope.OrganisationScopeId, ScopeStatus = scope.ScopeStatus, StatusDate = scope.ScopeStatusDate, RegisterStatus = scope.RegisterStatus, SnapshotDate = scope.SnapshotDate } } ; //Check if the user is registered for this organisation model.UserIsRegistered = currentUser != null && org.UserOrganisations.Any(uo => uo.UserId == currentUser.UserId); return(model); }
public IActionResult DeclareScope(string id) { //Ensure user has completed the registration process IActionResult checkResult = CheckUserRegisteredOk(out User currentUser); if (checkResult != null) { return(checkResult); } // Decrypt org id if (!id.DecryptToId(out long organisationId)) { return(new HttpBadRequestResult($"Cannot decrypt employer id {id}")); } // Check the user has permission for this organisation UserOrganisation userOrg = currentUser.UserOrganisations.FirstOrDefault(uo => uo.OrganisationId == organisationId); if (userOrg == null) { return(new HttpForbiddenResult($"User {currentUser?.EmailAddress} is not registered for employer id {organisationId}")); } // Ensure this user is registered fully for this organisation if (userOrg.PINConfirmedDate == null) { return(new HttpForbiddenResult( $"User {currentUser?.EmailAddress} has not completed registration for employer {userOrg.Organisation.EmployerReference}")); } //Get the current snapshot date DateTime snapshotDate = userOrg.Organisation.SectorType.GetAccountingStartDate().AddYears(-1); if (snapshotDate.Year < Global.FirstReportingYear) { return(new HttpBadRequestResult($"Snapshot year {snapshotDate.Year} is invalid")); } ScopeStatuses scopeStatus = ScopeBusinessLogic.GetLatestScopeStatusForSnapshotYear(organisationId, snapshotDate.Year); if (scopeStatus.IsAny(ScopeStatuses.InScope, ScopeStatuses.OutOfScope)) { return(new HttpBadRequestResult("Explicit scope is already set")); } // build the view model var model = new DeclareScopeModel { OrganisationId = userOrg.OrganisationId, OrganisationName = userOrg.Organisation.OrganisationName, SnapshotDate = snapshotDate }; return(View(model)); }
public IActionResult ManageOrganisation(string id) { // Check for feature flag and redirect if enabled if (FeatureFlagHelper.IsFeatureEnabled(FeatureFlag.NewManageOrganisationsJourney)) { return(RedirectToAction("ManageOrganisationGet", "ManageOrganisations", new { encryptedOrganisationId = id })); } //Ensure user has completed the registration process IActionResult checkResult = CheckUserRegisteredOk(out User currentUser); if (checkResult != null) { return(checkResult); } // Decrypt org id if (!id.DecryptToId(out long organisationId)) { return(new HttpBadRequestResult($"Cannot decrypt organisation id {id}")); } // Check the user has permission for this organisation UserOrganisation userOrg = currentUser.UserOrganisations.FirstOrDefault(uo => uo.OrganisationId == organisationId); if (userOrg == null || userOrg.PINConfirmedDate == null) { return(new HttpForbiddenResult($"User {currentUser?.EmailAddress} is not registered for organisation id {organisationId}")); } // clear the stash this.ClearStash(); //Get the current snapshot date DateTime currentSnapshotDate = userOrg.Organisation.SectorType.GetAccountingStartDate(); //Make sure we have an explicit scope for last and year for organisations new to this year if (userOrg.HasBeenActivated() && userOrg.Organisation.Created >= currentSnapshotDate) { ScopeStatuses scopeStatus = ScopeBusinessLogic.GetLatestScopeStatusForSnapshotYear(organisationId, currentSnapshotDate.Year - 1); if (!scopeStatus.IsAny(ScopeStatuses.InScope, ScopeStatuses.OutOfScope)) { return(RedirectToAction(nameof(DeclareScope), "Organisation", new { id })); } } // get any associated users for the current org List <UserOrganisation> associatedUserOrgs = userOrg.GetAssociatedUsers().ToList(); // build the view model List <int> yearsWithDraftReturns = DataRepository.GetAll <DraftReturn>() .Where(d => d.OrganisationId == organisationId) .Select(d => d.SnapshotYear) .ToList(); var model = new ManageOrganisationModel { CurrentUserOrg = userOrg, AssociatedUserOrgs = associatedUserOrgs, EncCurrentOrgId = Encryption.EncryptQuerystring(organisationId.ToString()), ReportingYearsWithDraftReturns = yearsWithDraftReturns }; return(View(model)); }
public IActionResult DeclareScope(DeclareScopeModel model, string id) { // Ensure user has completed the registration process IActionResult checkResult = CheckUserRegisteredOk(out User currentUser); if (checkResult != null) { return(checkResult); } // Decrypt org id if (!id.DecryptToId(out long organisationId)) { return(new HttpBadRequestResult($"Cannot decrypt employer id {id}")); } // Check the user has permission for this organisation UserOrganisation userOrg = currentUser.UserOrganisations.FirstOrDefault(uo => uo.OrganisationId == organisationId); if (userOrg == null) { return(new HttpForbiddenResult($"User {currentUser?.EmailAddress} is not registered for employer id {organisationId}")); } // Ensure this user is registered fully for this organisation if (userOrg.PINConfirmedDate == null) { return(new HttpForbiddenResult( $"User {currentUser?.EmailAddress} has not completed registration for employer {userOrg.Organisation.EmployerReference}")); } //Check the year parameters if (model.SnapshotDate.Year < Global.FirstReportingYear || model.SnapshotDate.Year > VirtualDateTime.Now.Year) { return(new HttpBadRequestResult($"Snapshot year {model.SnapshotDate.Year} is invalid")); } //Check if we need the current years scope ScopeStatuses scopeStatus = ScopeBusinessLogic.GetLatestScopeStatusForSnapshotYear(organisationId, model.SnapshotDate.Year); if (scopeStatus.IsAny(ScopeStatuses.InScope, ScopeStatuses.OutOfScope)) { return(new HttpBadRequestResult("Explicit scope is already set")); } //Validate the submitted fields ModelState.Clear(); if (model.ScopeStatus == null || model.ScopeStatus == ScopeStatuses.Unknown) { AddModelError(3032, "ScopeStatus"); } if (!ModelState.IsValid) { this.CleanModelErrors <DeclareScopeModel>(); return(View("DeclareScope", model)); } //Create last years declared scope var newScope = new OrganisationScope { OrganisationId = userOrg.OrganisationId, Organisation = userOrg.Organisation, ContactEmailAddress = currentUser.EmailAddress, ContactFirstname = currentUser.Firstname, ContactLastname = currentUser.Lastname, ScopeStatus = model.ScopeStatus.Value, Status = ScopeRowStatuses.Active, ScopeStatusDate = VirtualDateTime.Now, SnapshotDate = model.SnapshotDate }; //Save the new declared scopes ScopeBusinessLogic.SaveScope(userOrg.Organisation, true, newScope); return(View("ScopeDeclared", model)); }
public IActionResult ReportForOrganisation(string request) { //Ensure user has completed the registration process IActionResult checkResult = CheckUserRegisteredOk(out User currentUser); if (checkResult != null) { return(checkResult); } // Decrypt request if (!request.DecryptToParams(out List <string> requestParams)) { return(new HttpBadRequestResult($"Cannot decrypt parameters '{request}'")); } // Extract the request vars long organisationId = requestParams[0].ToInt64(); int reportingStartYear = requestParams[1].ToInt32(); bool change = requestParams[2].ToBoolean(); // Ensure we can report for the year requested if (!SubmissionService.IsValidSnapshotYear(reportingStartYear)) { return(new HttpBadRequestResult($"Invalid snapshot year {reportingStartYear}")); } // Check the user has permission for this organisation UserOrganisation userOrg = currentUser.UserOrganisations.FirstOrDefault(uo => uo.OrganisationId == organisationId); if (userOrg == null) { return(new HttpForbiddenResult($"User {currentUser?.EmailAddress} is not registered for organisation id {organisationId}")); } // get the sector SectorTypes sectorType = userOrg.Organisation.SectorType; // Determine if this is for the previous reporting year bool isPrevReportingYear = SubmissionService.IsCurrentSnapshotYear(sectorType, reportingStartYear) == false; // Set the reporting session globals ReportingOrganisationId = organisationId; ReportingOrganisationStartYear = reportingStartYear; // Clear the SubmitController stash this.ClearAllStashes(); var reportingRequirement = ScopeBusinessLogic.GetLatestScopeStatusForSnapshotYear(organisationId, reportingStartYear); bool requiredToReport = reportingRequirement == ScopeStatuses.InScope || reportingRequirement == ScopeStatuses.PresumedInScope; // When previous reporting year then do late submission flow // unless the reporting year has been excluded from late flag enforcement (eg. 2019/20 due to COVID-19) var yearsToExclude = Global.ReportingStartYearsToExcludeFromLateFlagEnforcement; var reportingYearShouldBeExcluded = yearsToExclude.Contains(reportingStartYear); if (isPrevReportingYear && requiredToReport && !reportingYearShouldBeExcluded) { // Change an existing late submission if (change) { return(RedirectToAction("LateWarning", "Submit", new { request, returnUrl = "CheckData" })); } // Create new a late submission return(RedirectToAction("LateWarning", "Submit", new { request })); } /* * Under normal circumstances, we might want to stash the model at this point, just before the redirection, however, we are NOT going to for two reasons: * (1) The information currently on the model includes ONLY the bare minimum to know if there is a draft or not, it doesn't for example, include anything to do with the permissions to access, who is locked it, lastWrittenTimestamp... This behaviour is by design: the draft file is locked on access, and that will happen once the user arrives to 'check data' or 'enter calculations', if we were to stash the model now, the stashed info won't contain all relevant draft information. * (2) Currently stash/unstash only works with the name of the controller, so it really doesn't matter what we stash here, the 'check data' and 'enter calculations' page belong to a different controller, so the stashed info will never be read by them anyway. */ // Change an existing submission if (change) { return(RedirectToAction("CheckData", "Submit")); } // Create new a submission return(RedirectToAction("EnterCalculations", "Submit")); }