Skip to content

Instantly share code, notes, and snippets.

@theasteve
Created January 23, 2024 16:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save theasteve/34225aa7bef364bd390b31d371797a8a to your computer and use it in GitHub Desktop.
Save theasteve/34225aa7bef364bd390b31d371797a8a to your computer and use it in GitHub Desktop.
module InsurancePolicies
class ConfirmCancellationRequest
attr_reader :errors
include PolicyDocuments::DataConsolidation
include Shared::Log::Tagged
include FeatureFlagQueries
has_logger tags: -> {
[
"insurance-policy-#{insurance_policy.id}",
"cancellation-request-#{@cancellation_request.id}",
cancellation_type
]
}
##
# Accepts or declines a pending insurance_policy_cancellation_request
#
# If a cancellation_request is accepted, this also cancels any existing pending change_requests
# for that insurance_policy, and kicks off the worker that marks the policy as canceled and
# cancels the subscription in Stripe
#
# @param cancellation_request - an InsurancePolicyCancellationRequest instance
# @param params - attributes to be updated in the cancellation_request object
#
# Returns true if successful. Otherwise sets and returns an array of errors.
#
def initialize(cancellation_request, params)
@cancellation_request = cancellation_request
@params = params.merge(responded_at: Time.current)
@errors = {}
end
def run
logger.info("Starting cancellation request process")
assign_cancellation_request_attributes
unless @cancellation_request.valid?
add_validation_errors
return false
end
process_cancellation_request
end
def success?
errors.empty?
end
def full_error_messages
errors.map do |attribute, error_messages|
error_messages.map { |message| "#{attribute} #{message}".humanize }
end.flatten
end
private
attr_reader :params
def assign_cancellation_request_attributes
@cancellation_request.assign_attributes(params)
end
def process_cancellation_request
confirm_cancellation if @cancellation_request.confirmed?
if success?
save_and_log_success
else
add_process_errors
end
end
def save_and_log_success
@cancellation_request.save
logger.info("Successfully '#{@cancellation_request.status}' pending cancellation request")
consolidate_policy_documents_data(@cancellation_request.insurance_policy_id, :lr_715_doc_revision_for_termination)
logger.info("Scheduled the PolicyDocumentRevisions::ConsolidateDataWorker")
true
end
def add_validation_errors
error_details = @cancellation_request.errors.full_messages.join(", ")
logger.error("Invalid cancellation request #{@cancellation_request.id}: #{error_details}")
@errors.merge!(@cancellation_request.errors)
end
def add_process_errors
error_details = @cancellation_request.errors.full_messages.join(", ")
logger.error("Processing errors for cancellation request #{@cancellation_request.id}: #{error_details}")
@errors.merge!(@cancellation_request.errors)
end
def cancel_pending_change_request
if @cancellation_request.insurance_policy.change_request.present?
logger.info('Cancelling the change request')
@cancellation_request.insurance_policy.change_request.canceled!
end
end
def cancel_insurance_policy
logger.info('Scheduling worker to cancel the policy subscription')
InsurancePolicies::CancelSubscriptionWorker.perform_async(@cancellation_request.insurance_policy_id, {
'cancellation_reason' => @cancellation_request.reason,
'cancellation_request_date' => @cancellation_request.requested_at.strftime("%m-%d-%Y"),
'cancellation_acceptance_date' => @cancellation_request.responded_at.strftime("%m-%d-%Y")
})
end
def confirm_cancellation
logger.info("Starting confirmation of Policy cancellation")
cancel_renewal_policy if renewal_policy_exists?
update_non_renewal_reason
if early_termination?
ensure_policy_request_termination
revise_policy_service.run
@errors.merge!(revise_policy_service.errors) unless revise_policy_service.success?
else
cancel_insurance_policy
cancel_pending_change_request
end
end
def cancel_renewal_policy
logger.info("Cancelling renewal policy")
InsurancePolicies::CancelSubscriptionWorker.perform_async(insurance_policy.next_policy.id, {
'cancellation_reason' => policy_cancellation_non_renewal_reason,
'cancellation_request_date' => @cancellation_request.requested_at.strftime("%m-%d-%Y"),
'cancellation_acceptance_date' => @cancellation_request.responded_at.strftime("%m-%d-%Y")
})
end
def policy_cancellation_non_renewal_reason
InsurancePolicies::Constants::NON_RENEWAL_REASONS["Policy is canceled or scheduled to be canceled"]
end
def renewal_policy_exists?
insurance_policy.next_policy.present?
end
def update_non_renewal_reason
insurance_policy.update(non_renewal_reason: policy_cancellation_non_renewal_reason)
end
def early_termination?
if use_new_cancellations_experience?
@cancellation_request.early_termination?
else
@cancellation_request.moved_out? || @cancellation_request.other_reason?
end
end
def ensure_policy_request_termination
# The attribute terminated_at will be deprecated soon
return if @cancellation_request.terminated_at.present?
@cancellation_request.assign_attributes(terminated_at: @cancellation_request.requested_at)
end
def revise_policy_service
@revise_policy_service ||= InsurancePolicies::Revise.new(
@cancellation_request.insurance_policy,
{ lease_end_date: lease_end_date, terminated_early: true },
cancellation_request: @cancellation_request
)
end
def cancellation_type
early_termination? ? 'early-termination' : 'flat-cancellation'
end
def lease_end_date
cancellation_effective_from = \
if use_new_cancellations_experience?
@cancellation_request.effective_from
else
@cancellation_request.terminated_at
end
[@cancellation_request.insurance_policy.lease_start_date, cancellation_effective_from].max
end
def insurance_policy
@_insurance_policy ||= @cancellation_request.insurance_policy
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment