app/services/claims/fee_calculator/graduated_price.rb
# Use this service for prices that are determined
# with the supply of multiple unit values.
#
# This includes LGFS (and AGFS?? TODO) graduated fees
#
module Claims
module FeeCalculator
class GraduatedPrice < CalculatePrice
attr_reader :ppe, :pw, :days, :pages_of_prosecuting_evidence
private
def setup(options)
@fee_type = Fee::BaseFeeType.find(options[:fee_type_id])
@advocate_category = options.fetch(:advocate_category, advocate_category)
@pages_of_prosecuting_evidence = options.fetch(:pages_of_prosecuting_evidence, prosecution_evidence)
@days = options.fetch(:days, 0)
@ppe = options.fetch(:ppe, 0)
@pw = options.fetch(:pw, 0)
exclusions
rescue StandardError
raise 'insufficient_data'
end
def prosecution_evidence
prosecution_evidence?.to_i
end
# TODO: warrant fees to be excluded until
# - fee calculator amended to have codes for warrant fee scenarios
# - CCCD is able to apply the sub category of warrant fee scenario logic
#
# TODO: retrial basic (basic) fee excluded where retrial starts before trial ends
# - validation in place to prevent this now
#
# TODO: cracked before retrial basic (basic) fee excluded until
# - we expose retrial_reduction on these case types
# - we find out how to determine retrial interval.
# - expose `trial_concluded_at`?
# - months between `trial_concluded_at` and `cracked_at`
# - we confirm how to handle situations where retrial started before tria concluded
#
def exclusions
raise Exceptions::InterimWarrantExclusion if fee_type.unique_code.eql?('INWAR')
raise Exceptions::RetrialReductionExclusion if uncalculatable_retrial_reduction_required?
raise Exceptions::CrackedBeforeRetrialExclusion if cracked_before_retrial_interval_required?
end
def amount
fee_scheme.calculate(**calculator_options)
end
def calculator_options
opts = {}
opts[:scenario] = scenario.id
opts[:offence_class] = offence_class_or_default
opts[:advocate_type] = advocate_type
opts[:pages_of_prosecuting_evidence] = pages_of_prosecuting_evidence
opts[:fee_type_code] = fee_type_code_for(fee_type)
opts[:day] = days.to_i
opts[:ppe] = ppe.to_i if ppe.to_i.nonzero?
opts[:pw] = pw.to_i if pw.to_i.nonzero?
opts[:trial_length] = trial_length
opts[:number_of_defendants] = number_of_defendants
opts[:retrial_interval] = retrial_interval
opts[:third_cracked] = third_cracked
opts.keep_if { |_k, v| v.present? }
end
def trial_length
days.to_i if trial_length_required?
end
def trial_length_required?
%w[INTDT INRST].include?(fee_type.unique_code)
end
def number_of_defendants
defendants.size if lgfs?
end
def retrial_interval
super if retrial_interval_required?
end
def retrial_interval_required?
[
agfs?,
case_type&.fee_type_code.eql?('GRRTR'),
retrial_reduction
].all?
end
def third_cracked
super if third_cracked_required?
end
def third_cracked_required?
agfs? && %w[GRRAK GRCBR].include?(case_type&.fee_type_code)
end
end
end
end