package gw.job uses gw.coverage.CoverableCacheProxy uses gw.api.extension.ExtensionInterfaces uses gw.api.locale.DisplayKey uses gw.api.profiler.PCProfilerTag uses gw.pl.util.ArgCheck uses gw.validation.PCValidationContext uses gw.validation.PCValidationResult uses gw.validation.ValidationUtil uses gw.web.productmodel.IProductModelSyncIssueWrapper class JobProcessValidator { public static final var NO_OP_VALIDATOR : JobProcessValidator = new NoopJobProcessValidator() private var _lastValidationResult : PCValidationResult as LastResult function validatePeriodForUI(branch : PolicyPeriod, level : ValidationLevel) { validatePeriodForUI(branch, level, true) } /** * Performs full policy graph validation in a UI-friendly fashion. Errors always result in * an EntityValidationException being thrown. Warnings that appear twice in a row will be ignored * the second time. * * @param branch the PolicyPeriod branch to validate * @param level the ValidationLevel at which to validate * @param warningsThrowException Do warnings throw validation exceptions */ function validatePeriodForUI(branch : PolicyPeriod, level : ValidationLevel, warningsThrowException : boolean) { var context = validatePeriod(branch, level) var result = context.Result if (result.hasErrors() or (warningsThrowException and result.hasNewWarnings(_lastValidationResult))) { _lastValidationResult = result context.raiseExceptionIfProblemsFound() } // validation passed, so clear any previous failures _lastValidationResult = null } /** * Loops through the PolicyPeriod#OOSSlices and validate each future slice at the provided validation level. * The first exception encountered will trigger an exception an subsequent validaiton on other future slices * will not occur. Currently, this method is only supporting for the validation levels: "bindable" and "readyforissue" * * @param branch the policy period to validate future slices on * @param level the validation level to perform validation at. Only "bindable" and "readyforissue" are supported */ function validateOOSESlices(branch : PolicyPeriod, level : ValidationLevel) { if (!ExtensionInterfaces.IJobProcessValidatorExtensions.isSupportedValidationLevel(level)){ throw new UnsupportedOperationException(DisplayKey.get("Job.Operation.Validation.ValidateOOSNotSupportedForLevel", level)) } ArgCheck.nonNull(branch, "branch") ArgCheck.nonNull(level, "level") for (oosSlice in branch.OOSSlices){ var context = validatePeriod(oosSlice, level) context.raiseExceptionIfErrorsFound() } } function validatePrimarySliceForQuote(branch : PolicyPeriod, valLevel : ValidationLevel, errorDisplayer(issues : List), warningsThrowException : boolean) { validateForQuote(branch, errorDisplayer, \b, i, e, s -> validatePrimarySlice(b, valLevel, i, e, warningsThrowException)) } function validateOOSESlicesForQuote(branch : PolicyPeriod, errorDisplayer(issues : List)) { for ( ooseSlice in branch.OOSSlices ) { ooseSlice.syncComputedValues() validateOOSESliceForQuote(ooseSlice, errorDisplayer) } } function validateReinsurance(branch : PolicyPeriod){ var context = ValidationUtil.createContext(ExtensionInterfaces.IPolicyPeriodExtensions.getValidationLevel(branch)) var val = ExtensionInterfaces.IPolicyPeriodValidationFactory.newInstance(context, branch) val.checkReinsurance() var result = context.Result if (result.hasErrors() or result.hasNewWarnings(_lastValidationResult)) { _lastValidationResult = result context.raiseExceptionIfProblemsFound() } // validation passed, so clear any previous failures _lastValidationResult = null } function validateCancellationDateNotTooSoon(period : PolicyPeriod, cancellation : Cancellation) { // Do nothing, CancellationProcessValidator will do the work } private function validateOOSESliceForQuote(branch : PolicyPeriod, errorDisplayer(issues : List)) { validateForQuote(branch, errorDisplayer, \b, i, e, s -> validateOOSESliceForQuoteHelper(b, i, e, s)) } private function validateForQuote(branch : PolicyPeriod, errorDisplayer(issues : List), validationMethod(branch : PolicyPeriod, issues : List, something : block (issues : List), shouldHalt : boolean)) { // Start using the cache for coverable -- no changes to policy graph inside this context var issues : List try { CoverableCacheProxy.enter() issues = PCProfilerTag.PRODUCT_MODEL_VALIDATE.evaluate(\ ->ExtensionInterfaces.IJobProcessExtensions.checkBranchAgainstProductModel(branch)) } finally { // Stop using the cache for coverable CoverableCacheProxy.exit() } // Can't use the cache here as there will be changes to the graph... PCProfilerTag.PRODUCT_MODEL_FIX_ISSUES.execute(\-> fixIssuesForQuote(branch, issues)) var shouldHalt = issues.hasMatch(\i -> i.ShouldBlockQuote) try { // Start using the cache for coverable -- no changes to policy graph inside this context CoverableCacheProxy.enter() validationMethod(branch, issues, errorDisplayer, shouldHalt) } finally { // Stop using the cache for coverable CoverableCacheProxy.exit() } if (shouldHalt) { throw ExtensionInterfaces.IQuoteHaltedExceptionFactory.newInstance(issues) } } private function validatePrimarySlice(branch : PolicyPeriod, valLevel : ValidationLevel, issues : List, errorDisplayer : block (issues : List), warningsThrowException : boolean) { // We want to display errors BEFORE validating here, so that sync errors show up as well as validation // errors errorDisplayer(issues) validatePeriodForUI(branch, valLevel, warningsThrowException) } private function validateOOSESliceForQuoteHelper(branch : PolicyPeriod, issues : List, errorDisplayer : block (issues : List), shouldHalt : boolean ) { var context = validatePeriod(branch, TC_QUOTABLE ) var failedValidation = shouldHalt || context.Result.hasErrors(context.Level) branch.getSlice(branch.EditEffectiveDate).FailedOOSEValidation = failedValidation // Unlike the normal validation path, here we only bother adding messages if we're going to halt the quote if (failedValidation) { errorDisplayer(issues) } context.raiseExceptionIfErrorsFound() } private function fixIssuesForQuote(branch : PolicyPeriod, issues : List) { ExtensionInterfaces.IProductModelSyncIssueWrapperExtensions.fixDuringQuoteIfNecessary(issues, branch) } // Pulled out as a separate function so it can be overridden during testing to explicitly inject validation errors protected function validatePeriod(branch : PolicyPeriod, level : ValidationLevel) : PCValidationContext { return PCProfilerTag.VALIDATE_PERIOD.evaluate(\ -> ExtensionInterfaces.IPolicyPeriodExtensions.validatePeriod(branch, level)) } }