package gw.rating.rtm.valueprovider uses gw.api.domain.covterm.CovTerm uses gw.api.locale.DisplayKey uses gw.api.productmodel.CovTermPattern uses gw.api.productmodel.PolicyLinePattern uses gw.api.upgrade.PCCoercions uses gw.lang.reflect.IType uses gw.rating.flow.util.CovTermValueVisitor uses gw.rating.flow.util.InScopeUsage uses gw.rating.flow.util.RatingEntityGraphTraverser uses gw.rating.flow.util.TypeMaps uses gw.rating.rtm.domain.PersistenceAdapter uses gw.rating.rtm.matchop.CoverageParam uses gw.rating.rtm.util.AvailableAttributePresenter /** *

* Value provider implementation for coverage term options of a specific coverage term * of a specific policy line coverage configured in PC product model. *

* This value provider should be used for rate table columns satisfying one of * the following conditions: *

    *
  1. A rate table column depends on another rate table column that contains coverage term code.
  2. *
  3. Two arguments are specified for this value provider: 1) coverage code, 2) coverage term code
  4. *
* In both cases value provider will retrieve coverage term options of a specific coverage term, * either from another column or the second argument. *

* Example 1: When a value provider is configured with arguments - * gw.rating.rtm.valueprovider.CovTermOptionValueProvider(PACollisionCov,PACollDeductible), * rate table column does not need to depend on any other column in the rate table and * will return all coverage term options under the coverage term identified by PACollDeductible * code under coverage identified by PACollisionCov code. *

* Example 2: When a value provider is configured without arguments - * gw.rating.rtm.valueprovider.CovTermOptionValueProvider, * rate table column must depend on another column in the rate table that defines * coverage term code which in turn must depend on the column defining coverage code. *

* This value provider should be usually used together with * {@link gw.rating.rtm.valueprovider.CovTermValueProvider CovTermValueProvider} and * {@link gw.rating.rtm.valueprovider.CoverageValueProvider CoverageValueProvider} value providers. * In that case, a column that uses CovTermOptionValueProvider should depend * on a column that uses CovTermValueProvider which in turn should depend on * a column that uses CoverageValueProvider. *

*/ class CovTermOptionValueProvider extends AbstractCovTermOptionValueProvider { private var _covTermColumn : RateTableColumn as readonly CovTermColumn private var _covColumn : RateTableColumn as readonly CovColumn construct(column : RateTableColumn) { super(column) _covTermColumn = ColumnDefinition.DependsOn _covColumn = _covTermColumn.DependsOn } /** * Returns coverage term code. * * * @see gw.rating.rtm.valueprovider.AbstractCovTermOptionValueProvider#getCovTermCode(KeyableBean) */ override function getCovTermCode(adapter : PersistenceAdapter) : String { if (Arguments != null and Arguments.length > 1) { return Arguments[1] } if (adapter == null) { return null } return getDependsOnValue(_covTermColumn, adapter) } /** * Returns coverage code. * * * @see gw.rating.rtm.valueprovider.AbstractCovTermOptionValueProvider#getCovTermCode(KeyableBean) */ override function getCovCode(adapter : PersistenceAdapter) : String { if (Arguments != null and Arguments.length > 0) return Arguments[0] return getDependsOnValue(_covColumn, adapter) } protected function createDefaultAttributePresenter(cov : entity.CalcRoutineParameter) : AvailableAttributePresenter { return new AvailableAttributePresenter(cov.Code, "CovTermOption", false, DisplayKey.get("Web.Rating.CovTermOptionValueProvider.CovTermOption")) } protected function covtermOptionIsAssignable(featureType : IType) : boolean { // If the underlying column is a string, RTM permits all cov term options. So should we...BUT // we don't want to return the CovTerms, only the option values. var restriction = TypeRestrictionForAvailableAttributes if (restriction.Count == 1 and restriction.single() == String) { return not CalcStepValueDelegate.isCovTermType(featureType) // don't accept the CovTerm itself and not CalcStepValueDelegate.isCoverageType(featureType) // don't include the Coverage either! } else { return TypeMaps.isAssignable(TypeRestrictionForAvailableAttributes, featureType) } } override function availableAttributes(line : PolicyLinePattern, paramSet : CalcRoutineParameterSet) : List { if (paramSet == null) { return {} } var results = new RatingEntityGraphTraverser(paramSet).getImmutableTargetableElementsForParameterSet(paramSet) if (Arguments == null or Arguments.IsEmpty) { var covParams = paramSet.Parameters.where(\ p -> p.ParamType == "entity.Coverage") var ret : List = {} covParams.each(\ cov -> { if (cov.CoveragePattern == null) { ret.add(createDefaultAttributePresenter(cov)) } else { var usages : List = {} results.asMap().eachKeyAndValue(\ k, l -> usages.addAll(l.where(\ v -> v.Root == cov.Code.Code))) usages = usages.where(\ v -> covtermOptionIsAssignable(v.FeatureType)) ret.addAll(usages.toTypedArray().map(\ u -> new AvailableAttributePresenter(u)).toList()) } }) return ret } else { var coverages = paramSet.Parameters.where(\ p -> coveragePatternMatchesCoverageArgument(p)).map(\ c -> c.Code) if (coverages.HasElements) { // If we got here, we have an explicitly-typed Coverage whose code matches the one that was given // as Argument[0]. In this case we want to allow corresponding CovTerm values to be inserted. var usages : List = {} results.asMap().eachKeyAndValue(\ k, l -> usages.addAll(l.where(\ v -> v.CovTermPattern != null))) usages = usages.where(\ v -> covtermOptionIsAssignable(v.FeatureType)) if (Arguments != null and Arguments.length > 1 and Arguments[1] != null) { // When we know argument 1, we should be able to restrict this completely. var ret = usages.where(\ v -> v.CovTermPattern == PCCoercions.makeProductModel(Arguments[1])).toTypedArray().map(\ u -> new AvailableAttributePresenter(u)).toList() return ret } else { // We can't fully restrict if we don't know Arguments[1] return usages.toTypedArray().map(\ u -> new AvailableAttributePresenter(u)).toList() } } else { // we have a specified Coverage, but nothing matches it. // Should we be returning anything at all here??? var covParams = paramSet.Parameters.where(\ p -> p.ParamType == "entity.Coverage") return covParams.map(\ cov -> createDefaultAttributePresenter(cov)).toList() } } } private function getDependsOnValue(column : RateTableColumn, adapter : PersistenceAdapter) : String { if (column == null) return null var value = adapter.getFieldValue(column.PhysicalColumnName) if (value == null) return null return value as String } override function getQueryParamValue(cov : Coverage) : String { if (cov.CovTerms.IsEmpty) return null return getCovTermValue(cov.CovTerms.first()) } override function getQueryParam(cov : Coverage) : CoverageParam { var value = getQueryParamValue(cov) // this gets the optionCode which is what we need to query the rate tables if (value == null) return null; // don't make a wrapper if the value is null return new CoverageParam(:codeIdentifier = value, :patternCode = value) } private function getCovTermValue(covTerm : CovTerm) : String { var visitor = new CovTermValueVisitor() covTerm.Pattern.acceptVisitor(visitor) return visitor.getValueAsString(covTerm) } override property get ArgumentsHelpText(): String { return DisplayKey.get("Web.Rating.RateTableDefinition.ValueProvider.HelpText.CovTermOptionValueProvider") } }