package gw.plugin.policy.impl uses gw.api.locale.DisplayKey uses gw.plugin.policy.IPolicyPlugin uses java.util.Date uses java.lang.StringBuilder uses gw.api.job.EffectiveDateCalculator uses gw.api.archive.PCArchivingUtil @Export class PolicyPlugin implements IPolicyPlugin { // ------------------------------------------------------------------------ Issuance /** * Returns whether or not an Issuance job can be started for this policy. * This will be true if the following conditions are met: * * * @param policy The policy on which the job is to be started * @return Null if the job can be started and a non-null error message if it cannot */ override function canStartIssuance( policy: Policy ) : String { var period = entity.Policy.finder.findMostRecentBoundPeriodByPolicy(policy) if (period == null) { return DisplayKey.get("Job.Error.NoPeriodForEffectiveDate") } else if (period.PolicyTerm.CheckArchived) { return DisplayKey.get("Web.Job.Warning.ArchivedTerm", period.EditEffectiveDate.ShortFormat) } var sb = new StringBuilder() appendIfFalse(policy.OpenJobs.Count == 0, DisplayKey.get("Job.Error.OtherOpenJobs"), sb) appendIfFalse(not policy.Issued, DisplayKey.get("Job.Error.PolicyIssuedAlready"), sb) appendIfFalse(perm.Issuance.create, DisplayKey.get("Job.Error.NoIssuancePermission"), sb) appendIfFalse(period.CancellationDate == null, DisplayKey.get("Job.Cancellation.Error.IssuePolicy"), sb) return errorString(sb) } // ------------------------------------------------------------------------ Policy Change /** * Returns whether or not this PolicyPeriod can be changed. * This will be true if the following conditions are met: * * * @param policy The policy on which the job is to be started * @param effectiveDate The effective dated at which the job is to be started * @return Null if the job can be started and a non-null error message if it cannot */ override function canStartPolicyChange( policy: Policy, effectiveDate: Date ) : String { if (effectiveDate == null) { return DisplayKey.get("Job.Error.EnterValidEffectiveDate") } var period = entity.Policy.finder.findPolicyPeriodByPolicyAndAsOfDate(policy, effectiveDate) if (period == null) { return DisplayKey.get("Job.Error.NoPeriodForEffectiveDate") } else if (period.PolicyTerm.CheckArchived) { return DisplayKey.get("Web.Job.Warning.ArchivedTerm", period.EditEffectiveDate.ShortFormat) } else if (PCArchivingUtil.hasFutureArchivedTerms(period)) { return DisplayKey.get("Web.Job.Warning.ArchivedFutureTerm", period.EditEffectiveDate.ShortFormat) } var sb = new StringBuilder() appendIfFalse(policy.Issued, DisplayKey.get("Job.Error.PolicyNotIssued"), sb) appendIfFalse(perm.PolicyPeriod.change(period), DisplayKey.get("Job.Error.NoChangePermission"), sb) appendIfFalse(not policy.hasOpenRewriteJob(), DisplayKey.get("Job.Error.OpenRewriteJob"), sb) appendIfFalse(not policy.hasOpenIssuanceJob(), DisplayKey.get("Job.Error.OpenIssuanceJob"), sb) appendIfFalse(not policy.hasOpenRewriteNewAccountJobOnNewPolicy(), DisplayKey.get("Job.RewriteNewAccount.Error.OpenRewriteNewAccountJob"), sb) var destinationPolicy = policy.RewrittenToNewAccountDestination if (destinationPolicy != null) { var startDate = destinationPolicy.findEarliestPeriodStart() appendIfFalse(effectiveDate < startDate, DisplayKey.get("Job.RewriteNewAccount.Error.PeriodStartAfterDestinationStart", startDate.ShortFormat), sb) } return errorString(sb) } // ------------------------------------------------------------------------ Cancellation /** * Returns whether or not this Policy can be canceled. * This will be true if the following conditions are met: * * * @param policy The policy on which the job is to be started * @param effectiveDate The effective dated at which the job is to be started * @return Null if the job can be started and a non-null error message if it cannot */ override function canStartCancellation( policy: Policy, effectiveDate: Date ) : String { if (effectiveDate == null) { return DisplayKey.get("Job.Error.EnterValidEffectiveDate") } var period = entity.Policy.finder.findPolicyPeriodByPolicyAndAsOfDate(policy, effectiveDate) if (period == null) { return DisplayKey.get("Job.Error.NoPeriodForEffectiveDate") } else if (period.PolicyTerm.CheckArchived) { return DisplayKey.get("Web.Job.Warning.ArchivedTerm", period.EditEffectiveDate.ShortFormat) } else if (PCArchivingUtil.hasFutureArchivedTerms(period)) { return DisplayKey.get("Web.Job.Warning.ArchivedFutureTerm", period.EditEffectiveDate.ShortFormat) } var sb = new StringBuilder() appendIfFalse(perm.PolicyPeriod.cancel(period), DisplayKey.get("Job.Cancellation.Error.NoCancelPermission"), sb) appendIfFalse(not period.Canceled or effectiveDate < period.CancellationDate, DisplayKey.get("Job.Cancellation.Error.AlreadyCanceled"), sb) appendIfFalse(not policy.hasOpenRewriteJob(), DisplayKey.get("Job.Error.OpenRewriteJob"), sb) appendIfFalse(not policy.hasOpenIssuanceJob(), DisplayKey.get("Job.Error.OpenIssuanceJob"), sb) appendIfFalse(not policy.hasOpenRewriteNewAccountJobOnNewPolicy(), DisplayKey.get("Job.RewriteNewAccount.Error.OpenRewriteNewAccountJob"), sb) return errorString(sb) } // ------------------------------------------------------------------------ Reinstate /** * Returns whether or not this PolicyPeriod can be reinstated. * This will be true if the following conditions are met: * * * @param policyPeriod The policy period that is canceled and needs reinstatement * @return Null if the job can be started and a non-null error message if it cannot */ override function canStartReinstatement( policyPeriod: PolicyPeriod ) : String { var period = entity.Policy.finder.findMostRecentBoundPeriodByPolicyPeriod(policyPeriod) if (period == null) { return DisplayKey.get("Job.Reinstatement.Error.NoRecentBoundPeriod") } else if (period.PolicyTerm.CheckArchived) { return DisplayKey.get("Web.Job.Warning.ArchivedTerm", period.EditEffectiveDate.ShortFormat) } else if (PCArchivingUtil.hasFutureArchivedTerms(period)) { return DisplayKey.get("Web.Job.Warning.ArchivedFutureTerm", period.EditEffectiveDate.ShortFormat) } var sb = new StringBuilder() appendIfFalse(perm.PolicyPeriod.reinstate(period), DisplayKey.get("Job.Reinstatement.Error.NoReinstatePermission"), sb) appendIfFalse(period.CancellationDate != null, DisplayKey.get("Job.Error.PolicyNotCanceled"), sb) appendIfFalse(not period.Policy.hasOpenRewriteJob(), DisplayKey.get("Job.Error.OpenRewriteJob"), sb) appendIfFalse(not period.Policy.hasOpenIssuanceJob(), DisplayKey.get("Job.Error.OpenIssuanceJob"), sb) appendIfFalse(not period.Policy.hasOpenReinstateJobForPeriod(period), DisplayKey.get("Job.Reinstatement.Error.OpenReinstate"), sb) appendIfFalse(not period.Policy.hasOpenRewriteNewAccountJobOnNewPolicy(), DisplayKey.get("Job.RewriteNewAccount.Error.OpenRewriteNewAccountJob"), sb) appendIfFalse(not period.isRewrittenToNewAccountAndCanceledLocked(), DisplayKey.get("Job.RewriteNewAccount.Error.CanceledAndExistingRewriteNewAccountJob"), sb) appendIfFalse(period.Policy.Issued, DisplayKey.get("Job.Error.PolicyNotIssued"), sb) if (period.CancellationDate != null) { //check if there is a window for the reinstatement to exist without an overlap var reinstatementExpDate = EffectiveDateCalculator.instance().getReinstatementExpirationDate(period.CancellationDate, period.PeriodEnd, period, null) appendIfFalse(reinstatementExpDate > period.CancellationDate, DisplayKey.get("Job.Reinstatement.Error.OverlapPeriod"), sb) } return errorString(sb) } // ------------------------------------------------------------------------ Rewrite /** * Returns whether or not this PolicyPeriod can be rewritten. * This will be true if the following conditions are met: * * * @param policy The policy on which the job is to be started * @param effDate The effective date of the rewrite period * @param expDate The expiration date of the rewrite period * @return Null if the job can be started and a non-null error message if it cannot */ override function canStartRewrite( policy: Policy, effectiveDate: Date, expirationDate: Date ) : String { var period = entity.Policy.finder.findPolicyPeriodByPolicyAndAsOfDate(policy, effectiveDate) if (period == null) { return DisplayKey.get("Job.Error.NoPeriodForEffectiveDate") } else if (period.PolicyTerm.CheckArchived) { return DisplayKey.get("Web.Job.Warning.ArchivedTerm", period.EditEffectiveDate.ShortFormat) } var sb = new StringBuilder() appendIfFalse(perm.PolicyPeriod.rewrite(period), DisplayKey.get("Job.Rewrite.Error.NoRewritePermission"), sb) appendIfFalse(period.CancellationDate != null, DisplayKey.get("Job.Error.PolicyNotCanceled"), sb) appendIfFalse(effectiveDate >= period.CancellationDate, DisplayKey.get("Job.Rewrite.Error.EffectiveBeforeCancelDate"), sb) appendIfFalse(policy.OpenJobs.countWhere(\j -> j.Subtype != TC_AUDIT) == 0, DisplayKey.get("Job.Rewrite.Error.OpenJobs"), sb) appendIfFalse(not period.Policy.hasOpenRewriteNewAccountJobOnNewPolicy(), DisplayKey.get("Job.RewriteNewAccount.Error.OpenRewriteNewAccountJob"), sb) appendIfFalse(not period.isRewrittenToNewAccountAndCanceledLocked(), DisplayKey.get("Job.RewriteNewAccount.Error.CanceledAndExistingRewriteNewAccountJob"), sb) appendIfFalse(policy.Issued, DisplayKey.get("Job.Error.PolicyNotIssued"), sb) var hasOverlap = period.isOverlappingBoundPeriods(effectiveDate, expirationDate) appendIfFalse(!hasOverlap, DisplayKey.get("Job.Rewrite.Error.OverlapPeriod"), sb) return errorString(sb) } /** * Returns whether or not this policy can be rewritten to a new account. This method will return * null (indicating that the rewrite can be started) if the following conditions are met: * * * * @param policyPeriod The period on which the job is to be started. This will never be null. * If the rewrite is started against an expired policy, then this will be the most * recent PolicyPeriod in force. Otherwise if the rewrite is started against a * canceled policy, this will be the PolicyPeriod in force as of "effDate". * @param effDate The desired effective date of the rewritten period. This will never be null, * and it will always be on or after the PeriodStart date of "policyPeriod". * @param expDate The desired expiration date of the rewritten period. This will never be null. * @param account The new account to which the policy will be rewritten. This will never be null. * @return Null if the job can be started and a non-null error message if it cannot. */ override function canStartRewriteNewAccount(basedOn : PolicyPeriod, effectiveDate : Date, expirationDate : Date, account : Account) : String { if (basedOn.PolicyTerm.CheckArchived) { return DisplayKey.get("Web.Job.Warning.ArchivedTerm", basedOn.EditEffectiveDate.ShortFormat) } var sb = new StringBuilder() var earliestDate = basedOn.Canceled ? basedOn.CancellationDate : basedOn.PeriodEnd appendIfFalse(effectiveDate.afterOrEqual(earliestDate), DisplayKey.get("Job.RewriteNewAccount.Error.NotCanceledOrExpired", effectiveDate), sb) appendIfFalse(perm.PolicyPeriod.rewritenewaccount(basedOn), DisplayKey.get("Job.RewriteNewAccount.Error.NoPermission"), sb) appendIfFalse(basedOn.Policy.findMostRecentNoncancelledBoundPeriodWithinDateRange(effectiveDate, null) == null, DisplayKey.get("Job.RewriteNewAccount.Error.PolicyInForce"), sb) appendIfFalse(basedOn.Policy.Issued, DisplayKey.get("Job.Error.PolicyNotIssued"), sb) appendIfFalse(basedOn.Policy.OpenJobs.countWhere(\j -> j.Subtype != typekey.Job.TC_AUDIT) == 0, DisplayKey.get("Job.RewriteNewAccount.Error.OpenJobs"), sb) appendIfFalse(basedOn.Policy.Account != account, DisplayKey.get("Job.RewriteNewAccount.Error.SameAccount"), sb) return errorString(sb) } // ------------------------------------------------------------------------ Renewal /** * Returns whether or not this PolicyPeriod can be rewritten. * This will be true if the following conditions are met: * * If the most-recent-bound period is a cancelled period, make a second search for * the most-recent-noncancelled-bound period that has a start date within 90 (or so) days * of the cancelled period. If one exists, a rewrite for example, use that period. * * @param policy The policy on which the job is to be started * @param effDate The effective date of the rewrite period * @param expDate The expiration date of the rewrite period * @return Null if the job can be started and a non-null error message if it cannot */ override function canStartRenewal( policy: Policy ) : String { var period = policy.getMostRecentBoundPeriodOnMostRecentTerm() if (period == null) { return DisplayKey.get("Job.Renewal.Error.NoPeriod") } if (period.PolicyTerm.CheckArchived) { return DisplayKey.get("Web.Job.Warning.ArchivedTerm", period.EditEffectiveDate.ShortFormat) } var sb = new StringBuilder() appendIfFalse(perm.Renewal.create, DisplayKey.get("Job.Renewal.Error.NoCreateRenewPermission"), sb) appendIfFalse(policy.Issued, DisplayKey.get("Job.Error.PolicyNotIssued"), sb) appendIfFalse(not policy.hasOpenRewriteJob(), DisplayKey.get("Job.Error.OpenRewriteJob"), sb) appendIfFalse(not policy.hasOpenRenewalJob(), DisplayKey.get("Job.Renewal.Error.OpenRenewal"), sb) appendIfFalse(policy.RewrittenToNewAccountDestination == null, DisplayKey.get("Job.RewriteNewAccount.Error.ExistingRewriteNewAccountJob"), sb) appendIfFalse(perm.PolicyPeriod.renew(period), DisplayKey.get("Job.Renewal.Error.NoRenewPermission"), sb) appendIfFalse(not period.Canceled, DisplayKey.get("Job.Renewal.Error.PolicyCanceled"), sb) return errorString(sb) } // ------------------------------------------------------------------------ Audit /** * Returns whether or not an audit can be started on this policy. * This will be true if the following conditions are met: * * * @param policy The policy on which the job is to be started * @param effectiveDate The date at which the audit should be started * @return Null if the job can be started and a non-null error message if it cannot */ override function canStartAudit( policy: Policy, effectiveDate : Date ) : String { if (effectiveDate == null) { return DisplayKey.get("Job.Error.EnterValidEffectiveDate") } var period = entity.Policy.finder.findPolicyPeriodByPolicyAndAsOfDate(policy, effectiveDate) if (period == null) { return DisplayKey.get("Job.Error.NoPeriodForEffectiveDate") } else if (period.PolicyTerm.CheckArchived) { return DisplayKey.get("Web.Job.Warning.ArchivedTerm", period.EditEffectiveDate.ShortFormat) } var sb = new StringBuilder() appendIfFalse(perm.Audit.start, DisplayKey.get("Job.Error.NoAuditPermission"), sb) appendIfFalse(policy.Issued, DisplayKey.get("Job.Error.PolicyNotIssued"), sb) return errorString(sb) } // ------------------------------------------------------------------------ private private static function appendIfFalse(condition: boolean, message: String, sb: StringBuilder) { if (not condition) { appendMessage( message, sb ) } } private static function appendMessage( message : String, sb : StringBuilder ) { sb.append(message + ", ") } private static function errorString(sb: StringBuilder): String { var s = sb.toString().trim() if (s.endsWith(",")) { s = s.substring(0, s.size - 1) } return s.length() == 0 ? null : s } }