Example #1
0
        public IActionResult UpdateCaseStatus([FromBody] UpdateCaseStatusRequest request)
        {
            var validator         = new UpdateCaseStatusValidator();
            var validationResults = validator.Validate(request);

            if (!validationResults.IsValid)
            {
                return(BadRequest(validationResults.ToString()));
            }

            try
            {
                var caseStatus = _caseStatusesUseCase.ExecuteUpdate(request);
                return(Ok(caseStatus));
            }
            catch (Exception e) when(
                e is PersonNotFoundException ||
                e is WorkerNotFoundException ||
                e is CaseStatusDoesNotMatchPersonException ||
                e is InvalidCaseStatusUpdateRequestException
                )
            {
                return(BadRequest(e.Message));
            }
            catch (CaseStatusDoesNotExistException e)
            {
                return(NotFound(e.Message));
            }
        }
Example #2
0
        private void ReplaceCurrentActiveAnswers(UpdateCaseStatusRequest request, Infrastructure.CaseStatus caseStatus, List <CaseStatusAnswer> caseStatusAnswers)
        {
            Guid     identifier           = Guid.NewGuid();
            DateTime?currentStatusEndDate = null;

            foreach (var a in caseStatusAnswers)
            {
                a.DiscardedAt    = _systemTime.Now;
                a.LastModifiedBy = request.EditedBy;
                var currentEndDate = a.EndDate;
                if (currentEndDate.HasValue)
                {
                    currentStatusEndDate = currentEndDate;
                }
            }

            foreach (var ra in request.Answers)
            {
                caseStatus.Answers.Add(new CaseStatusAnswer()
                {
                    CaseStatusId = caseStatus.Id,
                    CreatedBy    = request.EditedBy,
                    StartDate    = (DateTime)request.StartDate,
                    Option       = ra.Option,
                    Value        = ra.Value,
                    GroupId      = identifier.ToString(),
                    CreatedAt    = _systemTime.Now,
                    EndDate      = currentStatusEndDate
                });
            }
        }
Example #3
0
        public CaseStatusResponse ExecuteUpdate(UpdateCaseStatusRequest request)
        {
            var caseStatus = _caseStatusGateway.GetCasesStatusByCaseStatusId(request.CaseStatusId);

            ExecuteUpdateValidation(request, caseStatus);

            var updatedCaseStatus = _caseStatusGateway.UpdateCaseStatus(request);

            return(updatedCaseStatus.ToResponse());
        }
Example #4
0
        private static void ValidateUpdate(UpdateCaseStatusRequest request, Infrastructure.CaseStatus caseStatus)
        {
            if (caseStatus == null)
            {
                throw new CaseStatusDoesNotExistException($"Case status with {request.CaseStatusId} not found");
            }

            if (caseStatus.EndDate != null && request.EndDate < DateTime.Today)
            {
                throw new InvalidEndDateException($"Invalid end date.");
            }
        }
        public void TestWhenResidentAgeContextIsNotChildrensInvalidAgeContextExceptionThrown()
        {
            _updateCaseStatusRequest      = TestHelpers.CreateUpdateCaseStatusRequest();
            _caseStatus.Person.AgeContext = "A";

            _mockCaseStatusGateway.Setup(x => x.GetCasesStatusByCaseStatusId(It.IsAny <long>())).Returns(_caseStatus.ToDomain);

            Action act = () => _caseStatusesUseCase.ExecuteUpdate(_updateCaseStatusRequest);

            act.Should().Throw <InvalidAgeContextException>()
            .WithMessage($"Person with the id {_resident.Id} belongs to the wrong AgeContext for this operation");
        }
        public void WhenTypeIsLACAndRequestedEndDateIsOnActiveCaseStatusAnswerStartDateItCallsTheGateway()
        {
            _caseStatus = TestHelpers.CreateCaseStatus(resident: _resident, startDate: new DateTime(2021, 11, 3), type: "LAC");
            _updateCaseStatusRequest = TestHelpers.CreateUpdateCaseStatusRequest(caseStatusId: _caseStatus.Id, email: _worker.Email, endDate: new DateTime(2021, 11, 3), min: 1, max: 1);

            _mockCaseStatusGateway
            .Setup(x => x.GetCasesStatusByCaseStatusId(_caseStatus.Id))
            .Returns(_caseStatus.ToDomain());
            _mockCaseStatusGateway.Setup(x => x.UpdateCaseStatus(_updateCaseStatusRequest)).Returns(new DomainCaseStatus());

            _caseStatusesUseCase.ExecuteUpdate(_updateCaseStatusRequest);

            _mockCaseStatusGateway.Verify(x => x.UpdateCaseStatus(_updateCaseStatusRequest));
        }
Example #7
0
        public void WhenTypeIsCINAndRequestedEndDateIsBeforeCaseStatusStartDateInvalidEndDateExceptionThrown()
        {
            _caseStatus = TestHelpers.CreateCaseStatus(resident: _resident, startDate: new DateTime(2021, 11, 3), type: "CIN");
            _updateCaseStatusRequest = TestHelpers.CreateUpdateCaseStatusRequest(caseStatusId: _caseStatus.Id, email: _worker.Email, endDate: new DateTime(2021, 11, 1));

            _mockCaseStatusGateway
            .Setup(x => x.GetCasesStatusByCaseStatusId(_caseStatus.Id))
            .Returns(_caseStatus.ToDomain());

            Action act = () => _caseStatusesUseCase.ExecuteUpdate(_updateCaseStatusRequest);

            act.Should().Throw <InvalidEndDateException>()
            .WithMessage($"requested end date of {_updateCaseStatusRequest.EndDate?.ToString("O")} " +
                         $"is before the start date of {_caseStatus.StartDate:O}");
        }
        public void UpdateCaseStatusRequestValidation(UpdateCaseStatusRequest request, bool validRequest, string?errorMessage)
        {
            var validator          = new UpdateCaseStatusValidator();
            var validationResponse = validator.Validate(request);

            if (validRequest)
            {
                validationResponse.IsValid.Should().BeTrue();
            }
            else
            {
                validationResponse.IsValid.Should().BeFalse();
                validationResponse.ToString().Should().Be(errorMessage);
            }
        }
Example #9
0
        private void AddNewAnswers(UpdateCaseStatusRequest request, Infrastructure.CaseStatus caseStatus, DateTime?startDate = null, DateTime?endDate = null, string?groupId = null)
        {
            Guid identifier = Guid.NewGuid();

            foreach (var a in request?.Answers)
            {
                caseStatus.Answers.Add(new Infrastructure.CaseStatusAnswer()
                {
                    CaseStatusId = caseStatus.Id,
                    CreatedBy    = request.EditedBy,
                    StartDate    = startDate ?? (DateTime)request.StartDate,
                    EndDate      = endDate ?? null,
                    Option       = a.Option,
                    Value        = a.Value,
                    GroupId      = groupId ?? identifier.ToString(),
                    CreatedAt    = _systemTime.Now
                });
            }
        }
        public void WhenTypeIsLACandTheProvidedEndDateIsValidAndThereAreScheduledAnswersItCallsTheGateway()
        {
            var activeAnswers    = TestHelpers.CreateCaseStatusAnswers(min: 2, max: 2, startDate: new DateTime(2000, 01, 11), endDate: new DateTime(2040, 02, 01));
            var scheduledAnswers = TestHelpers.CreateCaseStatusAnswers(min: 2, max: 2, startDate: new DateTime(2040, 02, 01));

            _caseStatus         = TestHelpers.CreateCaseStatus(resident: _resident, startDate: new DateTime(2000, 01, 11), type: "LAC");
            _caseStatus.Answers = new List <CaseStatusAnswer>();
            _caseStatus.Answers.AddRange(activeAnswers);
            _caseStatus.Answers.AddRange(scheduledAnswers);

            _updateCaseStatusRequest = TestHelpers.CreateUpdateCaseStatusRequest(caseStatusId: _caseStatus.Id, email: _worker.Email, endDate: new DateTime(2000, 01, 11), min: 1, max: 1);

            _mockCaseStatusGateway.Setup(x => x.GetCasesStatusByCaseStatusId(_caseStatus.Id)).Returns(_caseStatus.ToDomain());
            _mockCaseStatusGateway.Setup(x => x.UpdateCaseStatus(It.IsAny <UpdateCaseStatusRequest>())).Returns(new DomainCaseStatus());

            _caseStatusesUseCase.ExecuteUpdate(_updateCaseStatusRequest);

            _mockCaseStatusGateway.Verify(x => x.UpdateCaseStatus(_updateCaseStatusRequest));
        }
        public void WhenTypeIsLACAndProvidedEndIsBeforeTheCurrentlyActiveAnswersStartDateItThrowsInvalidEndDateException()
        {
            _caseStatus         = TestHelpers.CreateCaseStatus(resident: _resident, startDate: DateTime.Now.AddDays(1), type: "LAC");
            _caseStatus.Answers = new List <CaseStatusAnswer>();
            _caseStatus.Answers.AddRange(TestHelpers.CreateCaseStatusAnswers(min: 2, max: 2, startDate: new DateTime(2021, 11, 3)));

            _updateCaseStatusRequest = TestHelpers.CreateUpdateCaseStatusRequest(caseStatusId: _caseStatus.Id, email: _worker.Email, endDate: new DateTime(2021, 11, 1), min: 1, max: 1);

            _mockCaseStatusGateway
            .Setup(x => x.GetCasesStatusByCaseStatusId(_caseStatus.Id))
            .Returns(_caseStatus.ToDomain());

            _mockCaseStatusGateway.Setup(x => x.UpdateCaseStatus(It.IsAny <UpdateCaseStatusRequest>())).Returns(new DomainCaseStatus());

            Action act = () => _caseStatusesUseCase.ExecuteUpdate(_updateCaseStatusRequest);

            act.Should().Throw <InvalidEndDateException>()
            .WithMessage("requested end date is before the start date of the currently active answer");
        }
Example #12
0
        private void CopyAndDiscardPreviousAnswers(UpdateCaseStatusRequest request, Infrastructure.CaseStatus caseStatus, List <CaseStatusAnswer> previousCaseStatusAnswers)
        {
            Guid identifier = Guid.NewGuid();

            foreach (var a in previousCaseStatusAnswers)
            {
                a.DiscardedAt    = _systemTime.Now;
                a.LastModifiedBy = request.EditedBy;

                caseStatus.Answers.Add(new CaseStatusAnswer()
                {
                    CaseStatusId = caseStatus.Id,
                    CreatedBy    = request.EditedBy,
                    StartDate    = a.StartDate,
                    EndDate      = request.StartDate,
                    Option       = a.Option,
                    Value        = a.Value,
                    GroupId      = identifier.ToString(),
                    CreatedAt    = _systemTime.Now
                });
            }
        }
        public void SetUp()
        {
            _mockCaseStatusGateway = new Mock <ICaseStatusGateway>();
            _mockDatabaseGateway   = new Mock <IDatabaseGateway>();
            _caseStatusesUseCase   = new CaseStatusesUseCase(_mockCaseStatusGateway.Object, _mockDatabaseGateway.Object);

            _resident   = TestHelpers.CreatePerson(ageContext: "C");
            _worker     = TestHelpers.CreateWorker();
            _caseStatus = TestHelpers.CreateCaseStatus(resident: _resident);
            _updateCaseStatusRequest = TestHelpers.CreateUpdateCaseStatusRequest(caseStatusId: _caseStatus.Id, email: _worker.Email);
            _updatedCaseStatus       = TestHelpers.CreateCaseStatus(_resident.Id, _caseStatus.Notes,
                                                                    _caseStatus.StartDate, _updateCaseStatusRequest.EndDate, resident: _resident);

            _mockCaseStatusGateway
            .Setup(x => x.GetCasesStatusByCaseStatusId(_caseStatus.Id))
            .Returns(_caseStatus.ToDomain());

            _mockCaseStatusGateway
            .Setup(x => x.UpdateCaseStatus(_updateCaseStatusRequest))
            .Returns(_updatedCaseStatus.ToDomain());

            _mockDatabaseGateway.Setup(x => x.GetPersonByMosaicId(_resident.Id)).Returns(_resident);
            _mockDatabaseGateway.Setup(x => x.GetWorkerByEmail(_worker.Email)).Returns(_worker);
        }
Example #14
0
        public CaseStatus UpdateCaseStatus(UpdateCaseStatusRequest request)
        {
            var caseStatus = _databaseContext.CaseStatuses.Include(cs => cs.Answers).FirstOrDefault(x => x.Id == request.CaseStatusId);

            ValidateUpdate(request, caseStatus);
            var caseStatusType = caseStatus.Type.ToLower();

            //end date provided
            if (request.EndDate != null)
            {
                caseStatus.EndDate = request.EndDate;

                switch (caseStatusType)
                {
                case "cp":
                case "lac":
                    var activeStatusAnswers = caseStatus
                                              .Answers
                                              .Where(x => x.DiscardedAt == null && (x.EndDate == null || x.EndDate > DateTime.Today));

                    //discard future ones
                    foreach (var a in activeStatusAnswers.Where(x => x.StartDate > DateTime.Today))
                    {
                        a.DiscardedAt    = _systemTime.Now;
                        a.LastModifiedBy = request.EditedBy;
                    }

                    //save start date and group id from the current answer and use them in the end reason
                    var activeAnswer = activeStatusAnswers.Where(x => x.StartDate <= DateTime.Today).First();

                    //end current ones
                    foreach (var a in activeStatusAnswers.Where(x => x.StartDate <= DateTime.Today))
                    {
                        a.EndDate        = request.EndDate;
                        a.LastModifiedBy = request.EditedBy;
                    }

                    AddNewAnswers(request, caseStatus, startDate: activeAnswer.StartDate, endDate: request.EndDate, groupId: activeAnswer.GroupId);
                    break;
                }
            }
            //end date not provided
            else
            {
                switch (caseStatusType)
                {
                case "cin":
                    caseStatus.Notes = request.Notes;
                    if (request.StartDate != null)
                    {
                        caseStatus.StartDate = (DateTime)request.StartDate;
                    }
                    break;

                case "cp":
                case "lac":
                    var previousAnswersToCopyAndDiscardCount = caseStatusType == "cp" ? 1 : 2;

                    var existingAnswerGroups = caseStatus
                                               .Answers
                                               .Where(x => x.DiscardedAt == null)
                                               .OrderBy(x => x.StartDate)
                                               .GroupBy(x => x.GroupId);

                    //multiple answer groups, check for overlapping dates
                    if (existingAnswerGroups?.Count() > 1)
                    {
                        foreach (var g in existingAnswerGroups)
                        {
                            foreach (var a in g)
                            {
                                if (request.StartDate <= a.StartDate && a.EndDate != null && a.EndDate < DateTime.Today)
                                {
                                    throw new InvalidStartDateException("Start date overlaps with previous status start date.");
                                }
                            }
                        }
                    }

                    if (existingAnswerGroups?.Count() == 1 || (existingAnswerGroups?.Count() == 2 && caseStatus.Answers.Any(x => x.StartDate > DateTime.Today && x.EndDate == null)))
                    {
                        caseStatus.StartDate = (DateTime)request.StartDate;
                    }

                    var currentActiveAnswers = caseStatus.Answers
                                               .Where(x => x.DiscardedAt == null && (x.EndDate == null || x.EndDate > DateTime.Today) && x.StartDate <= DateTime.Today)
                                               .OrderBy(x => x.StartDate).ToList();

                    ReplaceCurrentActiveAnswers(request, caseStatus, currentActiveAnswers);

                    var previousCaseStatusAnswers = caseStatus.Answers
                                                    .Where(x => x.DiscardedAt == null && x.EndDate != null && x.EndDate <= DateTime.Today)
                                                    .OrderByDescending(x => x.StartDate).Take(previousAnswersToCopyAndDiscardCount).ToList();

                    CopyAndDiscardPreviousAnswers(request, caseStatus, previousCaseStatusAnswers);

                    break;
                }
            }

            caseStatus.LastModifiedBy = request.EditedBy;
            _databaseContext.SaveChanges();

            return(caseStatus.ToDomain());
        }
Example #15
0
        private void ExecuteUpdateValidation(UpdateCaseStatusRequest request, CaseStatus?caseStatus)
        {
            if (caseStatus == null)
            {
                throw new CaseStatusDoesNotExistException($"Case status with {request.CaseStatusId} not found");
            }

            if (caseStatus.Person.AgeContext.ToLower() != "c")
            {
                throw new InvalidAgeContextException($"Person with the id {caseStatus.Person.Id} belongs to the wrong AgeContext for this operation");
            }

            var worker = _databaseGateway.GetWorkerByEmail(request.EditedBy);

            if (worker == null)
            {
                throw new WorkerNotFoundException($"Worker with email `{request.EditedBy}` was not found");
            }
            var caseStatusType = caseStatus.Type.ToLower();

            //end date validation
            if (request.EndDate != null)
            {
                switch (caseStatusType)
                {
                case "cp":
                case "lac":
                    var activeAnswerCountToMatch = caseStatusType == "cp" ? 1 : 2;

                    var activeAnswers = caseStatus.Answers.Where(x => x.DiscardedAt == null && (x.EndDate == null || x.EndDate > DateTime.Today));

                    if (activeAnswers.Count() == activeAnswerCountToMatch && activeAnswers.FirstOrDefault().StartDate > request.EndDate)
                    {
                        throw new InvalidEndDateException("requested end date is before the start date of the currently active answer");
                    }
                    if (request?.Answers?.Count != 1 ||
                        request.Answers.Any(x => string.IsNullOrWhiteSpace(x.Option)) ||
                        request.Answers.Any(x => string.IsNullOrWhiteSpace(x.Value)))
                    {
                        throw new InvalidCaseStatusUpdateRequestException($"Invalid {caseStatus.Type.ToUpper()} episode ending answer");
                    }
                    break;

                case "cin":
                    if (request.EndDate < caseStatus.StartDate)
                    {
                        throw new InvalidEndDateException($"requested end date of {request.EndDate?.ToString("O")} " + $"is before the start date of {caseStatus.StartDate:O}");
                    }
                    break;
                }
            }

            //when end date is not provided
            if (request.EndDate == null)
            {
                if (request.StartDate > DateTime.Today)
                {
                    throw new InvalidStartDateException("Invalid start date. It cannot be in the future.");
                }

                switch (caseStatusType)
                {
                case "cp":
                    if (request?.Answers?.Count != 1 ||
                        request.Answers.Any(x => string.IsNullOrWhiteSpace(x.Option)) ||
                        request.Answers.Any(x => string.IsNullOrWhiteSpace(x.Value)))
                    {
                        throw new InvalidCaseStatusUpdateRequestException("Invalid CP answer");
                    }
                    break;

                case "lac":
                    if (request?.Answers?.Count != 2 ||
                        request.Answers.Any(x => string.IsNullOrWhiteSpace(x.Option)) ||
                        request.Answers.Any(x => string.IsNullOrWhiteSpace(x.Value)))
                    {
                        throw new InvalidCaseStatusUpdateRequestException("Invalid LAC answers");
                    }
                    break;
                }
            }
        }