Calculation code comments Calculation controller
On GitHub: app/controllers/calculator_controller.rb
2 class CalculatorController < ApplicationController
Include code from each of the modules for the different styles of calculation.
5 include Calculations::BicameralBothHousesSitting
6 include Calculations::BicameralSiEitherHouseSitting
7 include Calculations::CommonsOnlySi
8 include Calculations::CommonsOnlySittingDays
9 include Calculations::Pnsi
10 include Calculations::Treaty
This is the code to provide a list of calculators.
13 def index
We set the meta information for the page.
16 @page_title = "Calculators"
17 @description = "Calculators made available by #{$SITE_TITLE}."
18 @crumb << { label: 'Calculators', url: nil }
19 @section = 'calculators'
20 end
This is the code to provide information for the form that users can fill in to calculate the scrutiny period by procedure.
23 def scrutiny_period
We find all the active procedures in display order - to populate the procedure radio buttons on the form.
26 @procedures = Procedure.all.where( 'active is true' ).order( 'display_order asc' )
We set the meta information for the page.
29 @page_title = "Scrutiny end date calculator"
30 @multiline_page_title = "Calculators <span class='subhead'>Scrutiny end date</span>".html_safe
31 @description = "A calculator to determine the estimated end date of scrutiny for instruments before Parliament."
32 @crumb << { label: 'Calculators', url: calculator_list_url }
33 @crumb << { label: 'Scrutiny end date', url: nil }
34 @section = 'calculators'
35 @subsection = 'scrutiny-calculator'
36 end
This is the code to provide information for the form that users wishing to run a specific calculation style can fill in.
39 def style
We get the calculation style if it's been passed as a parameter.
42 calculation_style = params['calculation-style']
43 @calculation_style = calculation_style.to_i if calculation_style
We set the meta information for the page.
46 @page_title = "Scrutiny end date calculator for a calculation style"
47 @multiline_page_title = "Calculators <span class='subhead'>Scrutiny end date for a calculation style</span>".html_safe
48 @description = "A calculator to determine the estimated end date of scrutiny for instruments before Parliament for a given calculation style."
49 @crumb << { label: 'About', url: meta_list_url }
50 @crumb << { label: 'Librarian tools', url: meta_librarian_tools_url }
51 @crumb << { label: 'Scrutiny period calculator by calculation style', url: nil }
52 end
This code runs the scrutiny period calculation.
55 def calculate
In order to calculate the anticipated end date of the scrutiny period, we need:
- the start date, for example: "2020-05-06"
60 start_date = params['start-date']
- the day count and
63 day_count = params['day-count']
- either the type of the procedure, which we refer to by a number
66 procedure = params['procedure']
- or the calculation style, which we also refer to by a number
69 calculation_style = params['calculation-style']
Calling this method also sets instance variables for start date, day count, procedure and calculation style.
If we don't have enough information to proceed with the calculation ...
73 unless calculation_can_proceed?( start_date, day_count, procedure, calculation_style )
... we call the insufficient information method.
76 insufficient_information
Otherwise, if we do have enough information to proceed with the calculation ...
79 else
... if the day count has not been provided or the day count is invalid ...
82 if !@day_count or is_day_count_invalid?( @day_count )
... we set the meta information for the page ...
85 @page_title = "Scrutiny end date - number of days to count required"
86 @multiline_page_title = "Calculators <span class='subhead'>Scrutiny end date - number of days to count required</span>".html_safe
87 @description = "Number of days to count required for a calculation to determine the estimated end date of scrutiny for instruments before Parliament."
88 @crumb << { label: 'Calculators', url: calculator_list_url }
89 @crumb << { label: 'Scrutiny end date', url: calculator_form_url }
90 @crumb << { label: 'Number of days to count required', url: nil }
91 @section = 'calculators'
92 @subsection = 'scrutiny-calculator'
... and we render the day count form.
95 render :template => 'calculator/day_count_form'
Otherwise, if the day count has been provided and the day count is not invalid ...
98 else
If the procedure has been passed as a parameter ...
101 if @procedure
... to calculate the anticipated end date, we select the calculation based on the type of procedure:
104 case @procedure.id
- Legislative Reform Orders, Public Body Orders, Localism Orders and enhanced affirmatives under the Investigatory Powers Act 2016
107 when 1, 17, 18, 19, 2, 4, 21, 22, 23
109 @start_date_type = "laying date"
110 @scrutiny_end_date = bicameral_calculation_both_houses_sitting( @start_date, @day_count )
- Proposed Statutory Instruments (PNSIs)
113 when 3
115 @start_date_type = "laying date"
116 @scrutiny_end_date = pnsi_calculation( @start_date, @day_count )
- Commons only negative Statutory Instruments
119 when 5
121 @start_date_type = "laying date"
122 @scrutiny_end_date = commons_only_si_calculation( @start_date, @day_count )
- Commons and Lords negative Statutory Instruments, proposed and draft affirmative remedial orders
125 when 6, 13, 14
127 @start_date_type = "laying date"
128 @scrutiny_end_date = bicameral_si_either_house_sitting_calculation( @start_date, @day_count )
- Some Commons only made affirmative Statutory Instruments
131 when 7
133 @start_date_type = "making date"
134 @scrutiny_end_date = commons_only_si_calculation( @start_date, @day_count )
- Commons and Lords made affirmative Statutory Instruments where both Houses are sitting
137 when 8
139 @start_date_type = "making date"
140 @scrutiny_end_date = bicameral_calculation_both_houses_sitting( @start_date, @day_count )
- Commons and Lords made affirmative Statutory Instruments where either House is sitting and made affirmative remedial orders
143 when 9, 15, 16
145 @start_date_type = "making date"
146 @scrutiny_end_date = bicameral_si_either_house_sitting_calculation( @start_date, @day_count )
- Treaty period A
149 when 10
151 @start_date_type = "laying date"
152 @scrutiny_end_date = treaty_calculation( @start_date, @day_count )
- Treaty period B
155 when 11
157 @start_date_type = "date of Ministerial statement"
158 @scrutiny_end_date = treaty_calculation( @start_date, @day_count )
- Published drafts under the European Union (Withdrawal) Act 2018
161 when 12
163 @start_date_type = "date of publication"
164 @scrutiny_end_date = bicameral_calculation_both_houses_sitting( @start_date, @day_count )
- National Policy Statements.
167 when 20
169 @start_date_type = "laying date"
170 @scrutiny_end_date = commons_only_sitting_days( @start_date, @day_count )
171 end
Otherwise, if the calculation style has been selected ...
174 elsif @calculation_style
... to calculate the anticipated end date, we select the calculation based on the calculation style:
177 case @calculation_style
- Calculation style 1
180 when 1
182 @scrutiny_end_date = bicameral_calculation_both_houses_sitting( @start_date, @day_count )
- Calculation style 2
185 when 2
187 @scrutiny_end_date = bicameral_si_either_house_sitting_calculation( @start_date, @day_count )
- Calculation style 3
190 when 3
192 @scrutiny_end_date = commons_only_si_calculation( @start_date, @day_count )
- Calculation style 4
195 when 4
197 @scrutiny_end_date = pnsi_calculation( @start_date, @day_count )
- Calculation style 5
200 when 5
202 @scrutiny_end_date = treaty_calculation( @start_date, @day_count )
- Calculation style 6
205 when 6
207 @scrutiny_end_date = commons_only_sitting_days( @start_date, @day_count )
208 else
... we add a reason to the missing information array ...
211 @missing_information << 'a valid calculation style'
... and call the insufficient information method.
214 insufficient_information
215 end
216 end
217 end
We set the meta information for the page.
220 @page_title = "Scrutiny end date calculation"
221 @multiline_page_title = "Calculators <span class='subhead'>Scrutiny end date calculation</span>".html_safe
222 @description = "A calculation to determine the estimated end date of scrutiny for instruments before Parliament."
223 @json_url = request.original_fullpath.sub '?', '.json?'
224 @calendar_links << ['Anticipated end date of the scrutiny period', request.original_fullpath.sub( '?', '.ics?' )]
225 @crumb << { label: 'Calculators', url: calculator_list_url }
226 @crumb << { label: 'Scrutiny end date', url: calculator_form_url }
227 @crumb << { label: 'Calculation', url: nil }
228 @section = 'calculators'
229 @subsection = 'scrutiny-calculator'
230 end
231 end
A method to check if the scrutiny period calculation can proceed.
This method also creates the start date, day count, procedure and calculation style as instance variables.
235 def calculation_can_proceed?( start_date, day_count, procedure, calculation_style )
We create a variable to hold a boolean, determining if the scrutiny period calculation can proceed.
238 calculation_can_proceed = true
We create an array to hold any errors we find as a result of missing information.
241 @missing_information = []
We check for the presence of a valid start date.
If the start date is present ...
245 if start_date
... we attempt to convert the start date string into a date, storing the result as a instance variable.
248 begin
249 @start_date = Date.parse( start_date )
If the start date string cannot be converted into a date ...
252 rescue ArgumentError
... we flag that the calculation cannot proceed ...
255 calculation_can_proceed = false
... and add a reason to the missing information array.
258 @missing_information << 'a valid start date'
259 end
Otherwise, if the start date is not present ...
262 else
... we flag that the calculation cannot proceed ...
265 calculation_can_proceed = false
... and add a reason to the missing information array.
268 @missing_information << 'a start date'
269 end
We check for the presence of a valid day count.
If a day count has been passed ...
273 if day_count
... we convert the day count to an integer, storing the result as a instance variable.
276 @day_count = day_count.to_i
If the day count is an invalid day count ...
279 if is_day_count_invalid?( @day_count )
... we do not flag that the calculation cannot proceed because this will be picked up by the day count form.
We add a reason to the missing information array.
284 @missing_information << 'a valid day count'
285 end
Otherwise, if a day count has not been passed ...
288 else
... we do not flag that the calculation cannot proceed because this will be picked up by the day count form.
We add a reason to the missing information array.
293 @missing_information << 'a day count'
294 end
We check for the presence of a valid procedure or a valid calculation style.
If the calculation has been passed neither a procedure, nor a calculation style ...
298 if !procedure and !calculation_style
... we flag that the calculation cannot proceed ...
301 calculation_can_proceed = false
... and add a reason to the missing information array.
304 @missing_information << 'a procedure or calculation style'
Otherwise, if the calculation has been passed a procedure ...
307 elsif procedure
... we attempt to find the procedure, storing the result as a instance variable.
310 @procedure = Procedure.find_by_id( procedure )
If we fail to find the procedure ...
313 unless @procedure
... we flag that the calculation cannot proceed ...
316 calculation_can_proceed = false
... and add a reason to the missing information array.
319 @missing_information << 'a valid procedure'
320 end
Otherwise, if the calculation has been passed a calculation style ...
323 elsif calculation_style
... we convert the calculation style ID to an integer, storing the result as a instance variable.
326 @calculation_style = calculation_style.to_i
If the calculation style is an invalid calculation style ...
329 if is_calculation_style_invalid?( @calculation_style )
... we flag that the calculation cannot proceed ...
332 calculation_can_proceed = false
... and add a reason to the missing information array.
335 @missing_information << 'a valid calculation style'
336 end
337 end
We return the calculation can proceed boolean.
340 calculation_can_proceed
341 end
A method to check if the day count is valid.
344 def is_day_count_valid?( day_count )
We create a boolean to hold the validity of the day count.
347 is_day_count_valid = true
If the day count is zero or a negative number ...
350 if day_count == 0 or day_count.negative?
... we set the is day count valid boolean to false.
353 is_day_count_valid = false
354 end
We return the is day count valid boolean.
357 is_day_count_valid
358 end
A method to check if the day count is invalid.
361 def is_day_count_invalid?( day_count )
We flip the boolean returned by the is day count valid method.
364 !is_day_count_valid?( day_count )
365 end
A method to check if the calculation style is valid.
368 def is_calculation_style_valid?( calculation_style )
We create a boolean to hold the validity of the calculation style.
371 is_calculation_style_valid = true
If the calculation style is zero or a negative number ...
374 if calculation_style == 0 or calculation_style.negative?
... we set the is calculation style valid boolean to false.
377 is_calculation_style_valid = false
378 end
We return the is calculation style valid boolean.
381 is_calculation_style_valid
382 end
A method to check if the calculation style is invalid.
385 def is_calculation_style_invalid?( calculation_style )
We flip the boolean returned by the is calculation style valid method.
388 !is_calculation_style_valid?( calculation_style )
389 end
A method to report that we have insufficient information for the scrutiny period calculation to proceed.
392 def insufficient_information
We set the meta information for the page ...
395 @page_title = "Scrutiny end date - more information required"
396 @multiline_page_title = "Calculators <span class='subhead'>Scrutiny end date - more information required</span>".html_safe
397 @description = "More information required for a calculation to determine the estimated end date of scrutiny for instruments before Parliament."
398 @crumb << { label: 'Calculators', url: calculator_list_url }
399 @crumb << { label: 'Scrutiny end date', url: calculator_form_url }
400 @crumb << { label: 'More information required', url: nil }
401 @section = 'calculators'
402 @subsection = 'scrutiny-calculator'
... and display the not enough information message.
405 render :template => 'calculator/not_enough_information'
406 end
407 end