Exemplo n.º 1
0
        private static void ValidateReclaim(CarePackageReclaimCreationDomain requestedReclaim, CarePackage package)
        {
            var coreCost = package.Details
                           .FirstOrDefault(d => d.Type is PackageDetailType.CoreCost)
                           .EnsureExists($"Core cost for package {package.Id} not found", HttpStatusCode.InternalServerError);

            if (package.Status.In(PackageStatus.Cancelled, PackageStatus.Ended))
            {
                throw new ApiException($"Can not create FNC reclaim for care package status {package.Status.GetDisplayName()}", HttpStatusCode.BadRequest);
            }

            if (package.PackageType != PackageType.NursingCare)
            {
                throw new ApiException($"FNC only allowed for nursing care package. Package {package.Id} is invalid", HttpStatusCode.BadRequest);
            }

            if (package.Reclaims.Any(r => r.Type is ReclaimType.Fnc))
            {
                throw new ApiException($"FNC already added to package {package.Id}", HttpStatusCode.Conflict);
            }

            if (!requestedReclaim.StartDate.IsInRange(coreCost.StartDate, coreCost.EndDate ?? DateTimeOffset.UtcNow.AddYears(10)))
            {
                throw new ApiException($"FNC start date must be equal or greater than {coreCost.StartDate}", HttpStatusCode.UnprocessableEntity);
            }

            if (requestedReclaim.EndDate != null)
            {
                var fncEndDate = (DateTimeOffset)requestedReclaim.EndDate;
                if (coreCost.EndDate != null && !fncEndDate.IsInRange(coreCost.StartDate, (DateTimeOffset)coreCost.EndDate))
                {
                    throw new ApiException($"FNC end date is invalid. Must be in the range {coreCost.StartDate} - {coreCost.EndDate}", HttpStatusCode.UnprocessableEntity);
                }
            }
        }
Exemplo n.º 2
0
        private static CarePackageReclaim CreateReclaimEntity(CarePackageReclaimCreationDomain requestedReclaim, ReclaimSubType subType)
        {
            var fncPayment = requestedReclaim.ToEntity();

            fncPayment.Type       = ReclaimType.Fnc;
            fncPayment.SubType    = subType;
            fncPayment.Status     = ReclaimStatus.Active;
            fncPayment.Subjective = fncPayment.SubType == ReclaimSubType.FncPayment ? SubjectiveConstants.FncPaymentSubjectiveCode : SubjectiveConstants.FncReclaimSubjectiveCode;

            return(fncPayment);
        }
        private static void ValidateProvisionalCareChargeAsync(CarePackageReclaimCreationDomain reclaimCreationDomain, CarePackage carePackage, CarePackageDetail coreCostDetail)
        {
            var validReclaimStatuses = new[] { ReclaimStatus.Active, ReclaimStatus.Pending, ReclaimStatus.Ended };

            if (reclaimCreationDomain.SubType != ReclaimSubType.CareChargeProvisional)
            {
                throw new ApiException($"Cannot create {reclaimCreationDomain.SubType.GetDisplayName()}. Manage other care charges types in the Care Charges menu",
                                       HttpStatusCode.BadRequest);
            }

            if (carePackage.Reclaims.Any(cc => cc.Type == ReclaimType.CareCharge && cc.SubType == ReclaimSubType.CareChargeProvisional && cc.Status.In(validReclaimStatuses)))
            {
                throw new ApiException($"Provisional Care charge assessment for this package already done",
                                       HttpStatusCode.BadRequest);
            }

            if (carePackage.Reclaims.Any(cc => cc.Type == ReclaimType.CareCharge && cc.SubType != ReclaimSubType.CareChargeProvisional))
            {
                throw new ApiException($"Care charge assessment for this package already done. Manage care charges for this package in the Care Charges menu",
                                       HttpStatusCode.BadRequest);
            }

            // Start date of provisional CC cannot be before package start date
            if (!reclaimCreationDomain.StartDate.IsInRange(coreCostDetail.StartDate, coreCostDetail.EndDate ?? DateTimeOffset.UtcNow.AddYears(10)))
            {
                throw new ApiException($"{ReclaimSubType.CareChargeProvisional.GetDisplayName()} start date must be equal or greater than {coreCostDetail.StartDate.Date}", HttpStatusCode.UnprocessableEntity);
            }

            // End date of provisional CC cannot be before package end date
            if (reclaimCreationDomain.EndDate != null)
            {
                var provisionalCareChargeEndDate = (DateTimeOffset)reclaimCreationDomain.EndDate;
                if (coreCostDetail.EndDate != null && !provisionalCareChargeEndDate.IsInRange(coreCostDetail.StartDate, (DateTimeOffset)coreCostDetail.EndDate))
                {
                    throw new ApiException(
                              $"{reclaimCreationDomain.SubType} end date is invalid. Must be in the range {coreCostDetail.StartDate} - {coreCostDetail.EndDate}", HttpStatusCode.UnprocessableEntity);
                }
            }

            // If provisional cc is set to be ongoing, force end date to be the end date of the package
            if (coreCostDetail.EndDate != null && reclaimCreationDomain.EndDate == null)
            {
                reclaimCreationDomain.EndDate = coreCostDetail.EndDate;
            }
        }
        public async Task <CarePackageReclaimResponse> CreateProvisionalCareCharge(CarePackageReclaimCreationDomain reclaimCreationDomain, ReclaimType reclaimType)
        {
            var carePackage = await _carePackageGateway
                              .GetPackageAsync(reclaimCreationDomain.CarePackageId, PackageFields.Details | PackageFields.Reclaims, true)
                              .EnsureExistsAsync($"Care package with id {reclaimCreationDomain.CarePackageId} not found");

            if (carePackage.Status.In(PackageStatus.Cancelled, PackageStatus.Ended))
            {
                throw new ApiException($"Can not create {reclaimType.GetDisplayName()} for care package status {carePackage.Status.GetDisplayName()}",
                                       HttpStatusCode.BadRequest);
            }

            var coreCostDetail = carePackage.Details
                                 .FirstOrDefault(d => d.Type is PackageDetailType.CoreCost)
                                 .EnsureExists($"Core cost for package with id {reclaimCreationDomain.CarePackageId} not found", HttpStatusCode.InternalServerError);

            ValidateProvisionalCareChargeAsync(reclaimCreationDomain, carePackage, coreCostDetail);

            //todo FK: ?
            reclaimCreationDomain.SubType = ReclaimSubType.CareChargeProvisional;
            var newReclaim = reclaimCreationDomain.ToEntity();

            //todo FK: ?
            newReclaim.Type       = ReclaimType.CareCharge;
            newReclaim.Status     = ReclaimStatus.Active;
            newReclaim.Subjective = SubjectiveConstants.CareChargeReclaimSubjectiveCode;

            carePackage.Reclaims.Add(newReclaim);

            carePackage.Histories.Add(new CarePackageHistory
            {
                Description = $"{reclaimType.GetDisplayName()} {reclaimCreationDomain.SubType.GetDisplayName()} Created",
            });

            // Change status of package to submitted for approval
            if (carePackage.Status == PackageStatus.Approved)
            {
                carePackage.Status = PackageStatus.SubmittedForApproval;
            }

            await _dbManager.SaveAsync("Could not save care package reclaim to database");

            return(newReclaim.ToDomain().ToResponse());
        }
Exemplo n.º 5
0
        public async Task <CarePackageReclaimResponse> ExecuteAsync(CarePackageReclaimCreationDomain requestedReclaim)
        {
            var package = await _carePackageGateway
                          .GetPackageAsync(requestedReclaim.CarePackageId, PackageFields.Details | PackageFields.Reclaims, true)
                          .EnsureExistsAsync($"Care package {requestedReclaim.CarePackageId} not found");

            ValidateReclaim(requestedReclaim, package);

            // two FNC items are created
            // - one for the real payment to home, which will be included in Core Cost
            // - another one is for reclaim, with negative amount, which will compensate payment item.
            // Just item with FNCPayment sub-type is used in UI / brokerage, reclaim item is for invoicing
            var fncPayment = CreateReclaimEntity(requestedReclaim, ReclaimSubType.FncPayment);
            var fncReclaim = CreateReclaimEntity(requestedReclaim, ReclaimSubType.FncReclaim);

            fncReclaim.Cost = Decimal.Negate(requestedReclaim.Cost);

            package.Reclaims.Add(fncPayment);
            package.Reclaims.Add(fncReclaim);

            package.Histories.Add(new CarePackageHistory {
                Description = "FNC Created"
            });

            if (package.Status is PackageStatus.Approved)
            {
                package.Status = PackageStatus.SubmittedForApproval;
            }

            ReclaimCostValidator.Validate(package);

            await using (var transaction = await _dbManager.BeginTransactionAsync())
            {
                await _createPackageResourceUseCase.CreateFileAsync(
                    package.Id, PackageResourceType.FncAssessmentFile, requestedReclaim.AssessmentFile);

                await _dbManager.SaveAsync("Could not save FNC reclaim to database");

                await transaction.CommitAsync();
            }

            return(fncPayment.ToDomain().ToResponse());
        }
 public static CarePackageReclaim ToEntity(this CarePackageReclaimCreationDomain input)
 {
     return(_mapper.Map <CarePackageReclaim>(input));
 }