/// <summary> /// Load historical reserves/payments/recovery reserves/recovery receipts for the specified claim /// </summary> /// <param name="transactionSource">transaction source</param> /// <param name="productClaimDefinition">claim product</param> /// <param name="claimDetailProductMap">claim details used for filtering</param> /// <param name="claimHeader">claim header</param> /// <param name="reserves">resulting reserves</param> /// <param name="payments">resulting payments and recovery receipts</param> /// <param name="recoveryReserves">resulting recovery reserves</param> private static void LoadFinancialAmounts(StaticValues.ClaimTransactionSource transactionSource, ProductClaimDefinition productClaimDefinition, IDictionary<string, ProductClaimDetail> claimDetailProductMap, ClaimHeader claimHeader, ClaimTransactionHeader claimtransactionheader, out IEnumerable<ClaimFinancialAmount> reserves, out IEnumerable<ClaimFinancialAmount> payments, out IEnumerable<ClaimFinancialAmount> recoveryReserves) { var inProgressData = ObjectFactory.Resolve<IInProgressFinancialAmountData>(); var historicalData = ObjectFactory.Resolve<IHistoricalFinancialAmountData>(); var claimHeaderArg = new ClaimHeaderArgument(AmountDataSource.Both, claimHeader, claimtransactionheader); var validClaimDetails = claimDetailProductMap .Where(a => a.Value.ClaimDetailAutomaticDeductibleProcessingMethod == (short)StaticValues.ClaimDetailAutomaticDeductibleProcessingMethod.FromClaimHeader) .Select(a => a.Key); var reserveCalculation = new TotalClaimReserveFinancialCalculation(inProgressData, historicalData); var paymentCalcuation = new TotalClaimPaymentFinancialCalculation(inProgressData, historicalData); var recoveryReceiptCalculation = new TotalClaimReceiptFinancialCalculation(inProgressData, historicalData); var recoveryRerserveCalculation = new TotalClaimRecoveryReserveFinancialCalculation(inProgressData, historicalData); bool includeEstimated = productClaimDefinition.IncurredAmountDerivationMethod == (short)StaticValues.IncurredAmountDerivationMethod.PaymentsReservesincludingEstimated; bool includeRecoveryEstimated = productClaimDefinition.RecoveryIncurredAmountDerivationMethod == (short)StaticValues.RecoveryIncurredAmountDerivationMethod.ReceiptsRecoveryReservesincludingEstimated; reserves = reserveCalculation.ReadLatestClaimReserves(claimHeaderArg, includeEstimated).Where(a => validClaimDetails.Contains(a.ClaimDetailReference)); payments = paymentCalcuation.ReadClaimPayments(claimHeaderArg).Where(a => validClaimDetails.Contains(a.ClaimDetailReference)); payments = payments.Concat(recoveryReceiptCalculation.ReadClaimReceipts(claimHeaderArg).Where(a => validClaimDetails.Contains(a.ClaimDetailReference))); recoveryReserves = recoveryRerserveCalculation.ReadLatestClaimRecoveryReserves(claimHeaderArg, includeRecoveryEstimated).Where(a => validClaimDetails.Contains(a.ClaimDetailReference)); var excludedMovementTypes = ClaimsBusinessLogicHelper.GetExcludedMovementTypesFromAutomaticDeductibleCalculations(); reserves = FilterExcludedMovementTypes(reserves, excludedMovementTypes); recoveryReserves = FilterExcludedMovementTypes(recoveryReserves, excludedMovementTypes); payments = FilterExcludedMovementTypes(payments, excludedMovementTypes); reserves = CreateAmountsForCalculation(reserves); recoveryReserves = CreateAmountsForCalculation(recoveryReserves); payments = CreateAmountsForCalculation(payments); }
/// <summary> /// Load historical reserves/payments/recovery reserves/recovery receipts for the specified claim detail /// </summary> /// <param name="transactionSource">transaction source</param> /// <param name="productClaimDefinition">claim product</param> /// <param name="claimDetail">claim detail</param> /// <param name="reserves">resulting reserves</param> /// <param name="payments">resulting payments and recovery receipts</param> /// <param name="recoveryReserves">resulting recovery reserves</param> private static void LoadFinancialAmounts(StaticValues.ClaimTransactionSource transactionSource, ProductClaimDefinition productClaimDefinition, ClaimDetail claimDetail, ClaimTransactionHeader claimtransactionheader, out IEnumerable<ClaimFinancialAmount> reserves, out IEnumerable<ClaimFinancialAmount> payments, out IEnumerable<ClaimFinancialAmount> recoveryReserves) { var inProgressData = ObjectFactory.Resolve<IInProgressFinancialAmountData>(); var historicalData = ObjectFactory.Resolve<IHistoricalFinancialAmountData>(); var claimDetailArg = new ClaimDetailArgument(AmountDataSource.Both, claimDetail, null); var reserveCalculation = new TotalClaimDetailReserveFinancialCalculation(inProgressData, historicalData); var paymentCalcuation = new TotalClaimDetailPaymentFinancialCalculation(inProgressData, historicalData); var recoveryReceiptCalculation = new TotalClaimDetailReceiptFinancialCalculation(inProgressData, historicalData); var recoveryRerserveCalculation = new TotalClaimDetailRecoveryReserveFinancialCalculation(inProgressData, historicalData); bool includeEstimated = productClaimDefinition.RecoveryIncurredAmountDerivationMethod == (short)StaticValues.RecoveryIncurredAmountDerivationMethod.ReceiptsRecoveryReservesincludingEstimated; bool includeRecoveryEstimated = productClaimDefinition.RecoveryIncurredAmountDerivationMethod == (short)StaticValues.RecoveryIncurredAmountDerivationMethod.ReceiptsRecoveryReservesincludingEstimated; reserves = reserveCalculation.ReadLatestClaimDetailReserves(claimDetailArg, includeEstimated); payments = paymentCalcuation.ReadClaimDetailPayments(claimDetailArg); payments = payments.Concat(recoveryReceiptCalculation.ReadClaimDetailReceipt(claimDetailArg)); recoveryReserves = recoveryRerserveCalculation.ReadLatestClaimDetailRecoveryReserves(claimDetailArg, includeRecoveryEstimated); var excludedMovementTypes = ClaimsBusinessLogicHelper.GetExcludedMovementTypesFromAutomaticDeductibleCalculations(); reserves = FilterExcludedMovementTypes(reserves, excludedMovementTypes); recoveryReserves = FilterExcludedMovementTypes(recoveryReserves, excludedMovementTypes); payments = FilterExcludedMovementTypes(payments, excludedMovementTypes); reserves = CreateAmountsForCalculation(reserves); recoveryReserves = CreateAmountsForCalculation(recoveryReserves); payments = CreateAmountsForCalculation(payments); }
private static bool IsCalculatingDeductibles(ProductClaimDetail productClaimDetail, ProductClaimDefinition productClaimDefinition, ClaimHeader claimHeader) { return productClaimDetail.ClaimDetailAutomaticDeductibleProcessingMethod == (short)StaticValues.ClaimDetailAutomaticDeductibleProcessingMethod.FromClaimHeader && productClaimDefinition.ClaimHeaderAutomaticDeductibleProcessingMethod == (short)StaticValues.ClaimHeaderAutomaticDeductibleProcessingMethod.StandardClaimHeaderDeductible && claimHeader.IsAutomaticDeductibleProcessingApplied == true; }
private static decimal CalculateTotalIncurred(ProductClaimDefinition productClaimDefinition, decimal totalPaid, IEnumerable<ClaimFinancialAmount> reserves) { if (productClaimDefinition.IncurredAmountDerivationMethod != (short)StaticValues.IncurredAmountDerivationMethod.PaymentsOnly) { totalPaid += reserves.Sum(a => a.TransactionAmountClaimCurrency.GetValueOrDefault(0)); } return totalPaid; }
/// <summary> /// For each deductible associated with this transaction we need to calculate how the latest transaction has affected the the current deductibles and generate any new deductibles as required /// </summary> /// <param name="productClaimDefinition">calim product</param> /// <param name="financialContext">context variables</param> /// <param name="deductibleDefinitions">deductibles associated with this transaction</param> /// <param name="reserves">historical reserves</param> /// <param name="payments">historical payments</param> /// <param name="recoveryReserves">recovery reserves</param> /// <returns>Deductible Result</returns> private static DeductibleResult CalculateDeductibles(ProductClaimDefinition productClaimDefinition, FinancialTransactionContext financialContext, IEnumerable<DeductibleDefinition> deductibleDefinitions, IEnumerable<ClaimFinancialAmount> reserves, IEnumerable<ClaimFinancialAmount> payments, IEnumerable<ClaimFinancialAmount> recoveryReserves) { var deductibleResult = new DeductibleResult { Success = true }; var deductibleMovementTypes = deductibleDefinitions.SelectMany(a => a.GetMovementTypes()); var recoveryDeductibleMovementTypes = deductibleDefinitions.SelectMany(a => a.GetRecoveryMovementTypes()); var claimDetailRefs = financialContext.ClaimHeader.ClaimDetails.Select(a => a.ClaimDetailReference); var deductibleReserveContext = new DeductibleReserveCapacity(claimDetailRefs, reserves, deductibleMovementTypes); var deductibleRecoveryReserveContext = new DeductibleReserveCapacity(claimDetailRefs, recoveryReserves, recoveryDeductibleMovementTypes); bool isRecovery = IsRecovery(financialContext.TransactionSource); decimal sumOfLowerDeductibles = 0; decimal totalPaid = payments.Where(a => !deductibleMovementTypes.Contains(a.MovementType)).Sum(a => a.TransactionAmountClaimCurrency.GetValueOrDefault()); decimal totalIncurred = CalculateTotalIncurred(productClaimDefinition, totalPaid, reserves.Where(a => !deductibleMovementTypes.Contains(a.MovementType))); decimal totalRecoveryIncurred = totalIncurred + recoveryReserves.Where(a => !recoveryDeductibleMovementTypes.Contains(a.MovementType)).Sum(a => a.TransactionAmountClaimCurrency.GetValueOrDefault(0)); foreach (var deductible in deductibleDefinitions) { decimal deductiblePaid = CalculateDeductiblePayment(deductible, totalPaid, sumOfLowerDeductibles, payments); if (deductiblePaid != 0) { var amountType = isRecovery ? StaticValues.AmountType.RecoveryReceipt : StaticValues.AmountType.Payment; AddClaimTransactionDetails(financialContext.ClaimTransactionHeader.TransactionDate.GetValueOrDefault(DateTime.MinValue), financialContext.ClaimTransactionGroup, amountType, deductible, deductiblePaid); } if (isRecovery && deductible.RecoveryNonFundedMovementType != null) { ClaimFinancialAmount latestReserve = LatestReserveOrNull(recoveryReserves, financialContext, deductible.RecoveryNonFundedMovementType); decimal deductibleRecoveryReserve = CalculateDeductibleRecoveryReserves(deductible, latestReserve, totalIncurred, totalRecoveryIncurred, sumOfLowerDeductibles, recoveryReserves); // although a deductible recovery reserve is a negative amount we want to keep it as a positive for now so we can apply deductible reserve adjustments deductibleRecoveryReserve = -deductibleRecoveryReserve; var reserveAdjResult = ApplyDeductibleReserveAdjustments(deductible.RecoveryNonFundedMovementType, deductible, deductibleRecoveryReserveContext, financialContext, recoveryReserves, latestReserve, deductibleRecoveryReserve); deductibleRecoveryReserveContext.AppendToLowerDeductibles(deductible.RecoveryNonFundedMovementType); if (!reserveAdjResult.Success) { deductibleResult = reserveAdjResult; } } if (financialContext.TransactionSource != StaticValues.ClaimTransactionSource.RecoveryReserve) { ClaimFinancialAmount latestReserve = LatestReserveOrNull(reserves, financialContext, deductible.NonFundedMovementType); decimal deductibleReserve = CalculateDeductibleReserves(deductible, latestReserve, totalPaid, totalIncurred, sumOfLowerDeductibles, reserves); var reserveAdjResult = ApplyDeductibleReserveAdjustments(deductible.NonFundedMovementType, deductible, deductibleReserveContext, financialContext, reserves, latestReserve, deductibleReserve); deductibleReserveContext.AppendToLowerDeductibles(deductible.NonFundedMovementType); if (!reserveAdjResult.Success) { deductibleResult = reserveAdjResult; } } sumOfLowerDeductibles += deductible.Amount; } return deductibleResult; }
public void Initialise() { var container = new UnityContainer(); this.RegisterAuthorityChecks(container); var claimTransaction = new BusinessComponentBuilder<ClaimTransactionHeader>(); this.currentUser = CreateUser("CurrenUserIdentity", 1, 10); this.targetUser1 = CreateUser("TargetUser1Identity", 2, 10); this.targetUser2 = CreateUser("TargetUser2Identity", 3, 0); var componentMetadata = MockRepository.GenerateStub<IComponentMetadata>(); container.RegisterInstance<IComponentMetadata>(componentMetadata); var product = new ProductBuilder<ProductVersion>(componentMetadata) .SetProperty(a => a.GradeStructureType = GradeStructureCode) .Add(new ProductBuilder<ProductClaimDefinition>(componentMetadata) .SetProperty(a => a.IsManualAuthorisationAlwaysAllowedIfNoChecksAreActive = true)) .Build(); this.productClaimDefinition = product.ProductClaimDefinition; ObjectFactory.Instance = new ObjectFactory(container); var clmHeader = new BusinessComponentBuilder<ClaimHeader>() .Add(new BusinessComponentBuilder<ClaimDetail>() .As(out claimDetailRef) .SetProperty(a => a.PolicyLinkLevel = (short)StaticValues.PolicyLinkLevel.Header) .SetProperty(a => a.ProductClaimDetailID = 1) .SetProperty(a => a.ClaimDetailReference = "Claim Detail Reference")) .Add(new BusinessComponentBuilder<ClaimTransactionHeader>() .SetProperty(a => a.IsInProgress = true) .Add(new BusinessComponentBuilder<ClaimTransactionGroup>() .AddRef(claimDetailRef) .SetProperty(a => a.AdministerClaimMethod = 2))) .Build(); clmHeader.ClaimHeaderAnalysisCode01 = ClaimConstants.CH_ANALYSISCODE_MOTOR; this.claimHeader = clmHeader; var claimsEntities = MockRepository.GenerateStub<IClaimsQuery>(); claimsEntities.Stub(a => a.GetClaimTransactionHeader(0)).IgnoreArguments().Return(this.claimHeader.InProgressClaimTransactionHeaders.Single()); container.RegisterInstance<IClaimsQuery>(claimsEntities); this.gradesforStructure = new List<Grade> { CreateGrade(GradeCode2, 3), CreateGrade(GradeCode1, 1) }; this.usersForGradeCode1 = new List<User> { this.currentUser, this.targetUser1 }; this.usersForGradeCode2 = new List<User>(); this.eventDestinations = new List<IEventDestination> { CreateEventDestination(this.targetUser1.UserIdentity, "1"), CreateEventDestination(this.targetUser1.UserIdentity, "2") }; this.metadataEntities = MockRepository.GenerateStub<IMetadataQuery>(); this.metadataEntities.Stub(a => a.GetUserIdByUserIdentity(this.currentUser.UserIdentity)).Return(this.currentUser.UserID); this.metadataEntities.Stub(a => a.GetUserGradeCode(this.currentUser.UserID, GradeStructureCode, StaticValues.GradeType.Claims)).Do(new Func<long, string, StaticValues.GradeType, string>((x, y, z) => this.userGradeCode)); this.metadataEntities.Stub(a => a.GetGradesForGradeStructure(GradeStructureCode)).Return(this.gradesforStructure); this.metadataEntities.Stub(a => a.GetUsersByGradeCode(GradeCode1)).Return(this.usersForGradeCode1); this.metadataEntities.Stub(a => a.GetUsersByGradeCode(GradeCode2)).Return(this.usersForGradeCode2); container.RegisterInstance(this.metadataEntities); var taskService = MockRepository.GenerateStub<ITaskService>(); taskService.Stub(a => a.GetActiveEventDestinations(null, null, DateTime.Now, DateTime.Now)).IgnoreArguments().Return(this.eventDestinations); taskService.Stub(a => a.GetFinishedEventDestinationByDateRange(null, null, DateTime.Now, DateTime.Now)).IgnoreArguments().Return(this.eventDestinations); container.RegisterInstance(taskService); IAXAClaimsQuery claimsQuery = MockRepository.GenerateStub<IAXAClaimsQuery>(); claimsQuery.Stub(s => s.IsUserOutOfOffice(Arg<long>.Is.Anything, out Arg<string>.Out(String.Empty).Dummy)).Return(false); container.RegisterInstance<IAXAClaimsQuery>(claimsQuery); this.businessSupportRole = ClaimsBusinessLogicHelper.ResolveMandatoryConfig<string>("BusinessSupportRole"); }
/// <summary> /// method used to get funded deductible movement types from the Metadata. /// </summary> /// <param name="entities">Metadata Entity value</param> /// <param name="productVersion">long value</param> /// <param name="attachedPolicyRef">string value</param> /// <param name="fundedDeductiblePolicies">Dictionary collection</param> /// <param name="pcd">Product Claim Definition Type</param> /// <param name="recoveryReserveMovementType">string value</param> /// <param name="reserveMovementType">string value</param> /// <param name="isRecoveryReserve">bool value</param> /// <param name="movementTypes">Dictionary collection - Passed by reference</param> /// <returns>Dictionary collection</returns> private static Dictionary<string, string> GetFundedDeductibleMovementTypes(MetadataEntities entities, long productVersion, string attachedPolicyRef, Dictionary<string, string> fundedDeductiblePolicies, ProductClaimDefinition pcd, string recoveryReserveMovementType, string reserveMovementType, bool isRecoveryReserve, ref Dictionary<string, string> movementTypes) { if (_Logger.IsInfoEnabled) { _Logger.Info("ClaimTransferDataCollection.GetFundedDeductibleMovementTypes"); } // For each of the five Deductible codes, check if we are adding to the list of Dedctible moment type codes. AddDeductibleMovemnentTypeCodes(ClaimConstants.DED_DEDUCTIBLE01, pcd.InsurerFundedDeductible01MovementTypeCode, attachedPolicyRef, fundedDeductiblePolicies, recoveryReserveMovementType, reserveMovementType, isRecoveryReserve, ref movementTypes); AddDeductibleMovemnentTypeCodes(ClaimConstants.DED_DEDUCTIBLE02, pcd.InsurerFundedDeductible02MovementTypeCode, attachedPolicyRef, fundedDeductiblePolicies, recoveryReserveMovementType, reserveMovementType, isRecoveryReserve, ref movementTypes); AddDeductibleMovemnentTypeCodes(ClaimConstants.DED_DEDUCTIBLE03, pcd.InsurerFundedDeductible03MovementTypeCode, attachedPolicyRef, fundedDeductiblePolicies, recoveryReserveMovementType, reserveMovementType, isRecoveryReserve, ref movementTypes); AddDeductibleMovemnentTypeCodes(ClaimConstants.DED_DEDUCTIBLE04, pcd.InsurerFundedDeductible04MovementTypeCode, attachedPolicyRef, fundedDeductiblePolicies, recoveryReserveMovementType, reserveMovementType, isRecoveryReserve, ref movementTypes); AddDeductibleMovemnentTypeCodes(ClaimConstants.DED_DEDUCTIBLE05, pcd.InsurerFundedDeductible05MovementTypeCode, attachedPolicyRef, fundedDeductiblePolicies, recoveryReserveMovementType, reserveMovementType, isRecoveryReserve, ref movementTypes); return movementTypes; }