diff --git a/README.md b/README.md index 08ac2361..8f9b606a 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,15 @@ Calculators This is an application to contain custom-built calculators. These will initially replace some smart-answers that have outgrown the framework. +## Child benefit tax calculator +Currently the only calculator in this application is the Child benefit tax calculator. + +This calculator reports how much child benefit tax you are entitled during a tax year. + +There is a cut-off date of 7 January 2013. This is the date [High Income Child Benefit Tax Charge](https://www.gov.uk/child-benefit-tax-charge/overview) came in effect. +This means that if the 2012 tax year is selected the calculator will only calculate the child benefit you are entitled to from 7 Jan 2013 to 5 Apr 2013, not for the entire tax year. + + ## Running the app ``` diff --git a/app/assets/javascripts/child-benefit-tax-calculator.js b/app/assets/javascripts/child-benefit-tax-calculator.js index 2a183077..94d68d16 100644 --- a/app/assets/javascripts/child-benefit-tax-calculator.js +++ b/app/assets/javascripts/child-benefit-tax-calculator.js @@ -1,4 +1,4 @@ -(function () { +(function() { "use strict"; var root = this, @@ -7,17 +7,45 @@ var calculator = { childrenCountInput: $("#children_count"), - childrenContainer: $("fieldset#children"), - - setEventHandlers: function () { - calculator.childrenCountInput.on('change', calculator.updateChildrenFields); + partYearChildrenCountInput: function(){ + return $("div#children #part_year_children_count") + }, + childrenContainerTemplate: $("div#children-template"), + taxClaimContainer: $("fieldset#is-part-year-claim"), + taxClaimDurationInputs: $("input[id^='is_part_year_claim_']"), + childrenContainer: function() { + return $("div#children"); + }, + setEventHandlers: function() { + calculator.taxClaimDurationInputs.on('change', calculator.triggerChildrenFieldsEvent); + calculator.setUpForm(); + }, + setUpForm: function(){ + var choosenTaxClaim = calculator.taxClaimDurationInputs.filter(":checked").val(); + calculator.toggleChildrenFields(choosenTaxClaim); + }, + triggerChildrenFieldsEvent: function(event){ + calculator.toggleChildrenFields($(event.currentTarget).val()); }, - updateChildrenFields: function () { - var numStartingChildren = calculator.childrenCountInput.val(), - childFields = calculator.childrenContainer.find('> div.child'), + toggleChildrenFields: function(choosen){ + if (choosen == "yes") { + if (calculator.childrenContainer().length == 0) { + var childrenTag = calculator.childrenContainerTemplate.clone(); + calculator.taxClaimContainer.append(childrenTag); + childrenTag.attr("id", "children").show(); + calculator.partYearChildrenCountInput().on('change', calculator.updateChildrenFields); + calculator.updateChildrenFields(); + } + } else { + calculator.partYearChildrenCountInput().off('change'); + calculator.childrenContainer().remove(); + } + }, + updateChildrenFields: function() { + var numStartingChildren = calculator.partYearChildrenCountInput().val(), + childFields = calculator.childrenContainer().find("> div.child"), numChildFields = childFields.size(), numNewFields = numStartingChildren - numChildFields; - if (numStartingChildren < 1 || numStartingChildren > 10) { return false; } @@ -31,7 +59,7 @@ } } }, - appendChildField: function (index) { + appendChildField: function(index) { var newChild = calculator.childFieldToClone().clone(); newChild.find('.child-number').text(index+1); @@ -44,14 +72,14 @@ $(this).attr('for', calculator.replaceIndex(index, $(this).attr('for'))); }); - newChild.appendTo(calculator.childrenContainer); + newChild.appendTo(calculator.childrenContainer()); }, - childFieldToClone: function () { + childFieldToClone: function() { // Always clone the first field so that we don't have to guess // the index (it will always be zero) - return calculator.childrenContainer.find("> div.child").first(); + return calculator.childrenContainer().find("> div.child").first(); }, - replaceIndex: function (index, str) { + replaceIndex: function(index, str) { return str.replace("0", index); } }; diff --git a/app/assets/stylesheets/calculators/child_benefit.scss b/app/assets/stylesheets/calculators/child_benefit.scss index 4524de86..60948029 100644 --- a/app/assets/stylesheets/calculators/child_benefit.scss +++ b/app/assets/stylesheets/calculators/child_benefit.scss @@ -104,6 +104,7 @@ li { // scss-lint:disable IdSelector #children { margin-bottom: 0; + float: left; h3 { @include bold-19; diff --git a/app/controllers/child_benefit_tax_controller.rb b/app/controllers/child_benefit_tax_controller.rb index f31e6769..4977399a 100644 --- a/app/controllers/child_benefit_tax_controller.rb +++ b/app/controllers/child_benefit_tax_controller.rb @@ -1,7 +1,7 @@ class ChildBenefitTaxController < ApplicationController before_filter :setup_slimmer - CALC_PARAM_KEYS = [:adjusted_net_income, :children_count, :starting_children, :year, :results] + + CALC_PARAM_KEYS = [:adjusted_net_income, :children_count, :starting_children, :year, :results, :part_year_children_count] + AdjustedNetIncomeCalculator::PARAM_KEYS def landing diff --git a/app/models/adjusted_net_income_calculator.rb b/app/models/adjusted_net_income_calculator.rb index af205113..5d37ad8d 100644 --- a/app/models/adjusted_net_income_calculator.rb +++ b/app/models/adjusted_net_income_calculator.rb @@ -2,7 +2,7 @@ class AdjustedNetIncomeCalculator PARAM_KEYS = [:gross_income, :other_income, :pension_contributions_from_pay, :retirement_annuities, :cycle_scheme, :childcare, :pensions, :property, - :non_employment_income, :gift_aid_donations, :outgoing_pension_contributions] + :non_employment_income, :gift_aid_donations, :outgoing_pension_contributions, :is_part_year_claim] def initialize(params) PARAM_KEYS.each do |key| diff --git a/app/models/child_benefit_tax_calculator.rb b/app/models/child_benefit_tax_calculator.rb index 552fb7e2..433f68b5 100644 --- a/app/models/child_benefit_tax_calculator.rb +++ b/app/models/child_benefit_tax_calculator.rb @@ -4,7 +4,7 @@ class ChildBenefitTaxCalculator include ActiveModel::Validations attr_reader :adjusted_net_income_calculator, :adjusted_net_income, :children_count, - :starting_children, :tax_year + :starting_children, :tax_year, :is_part_year_claim, :part_year_children_count NET_INCOME_THRESHOLD = 50000 TAX_COMMENCEMENT_DATE = Date.parse('7 Jan 2013') @@ -18,15 +18,19 @@ class ChildBenefitTaxCalculator } validate :valid_child_dates + validates_presence_of :is_part_year_claim, message: "select part year tax claim" validates_inclusion_of :tax_year, in: TAX_YEARS.keys.map(&:to_i), message: "select a tax year" + validate :valid_number_of_children validate :tax_year_contains_at_least_one_child def initialize(params = {}) @adjusted_net_income_calculator = AdjustedNetIncomeCalculator.new(params) @adjusted_net_income = calculate_adjusted_net_income(params[:adjusted_net_income]) @children_count = params[:children_count] ? params[:children_count].to_i : 1 - @starting_children = process_starting_children(params[:starting_children]) + @part_year_children_count = params[:part_year_children_count] ? params[:part_year_children_count].to_i : 0 + @is_part_year_claim = params[:is_part_year_claim] @tax_year = params[:year].to_i + @starting_children = process_starting_children(params[:starting_children]) end def self.valid_date_params?(params) @@ -37,8 +41,10 @@ def valid_date_params?(params) self.class.valid_date_params?(params) end + # Return the date of the Monday in the future that is closest to the date supplied. + # If the date supplied is a Monday, do not adjust it. def monday_on_or_after(date) - date + ((1 - date.wday) % 7) + date.monday? ? date : date.next_week(:monday) end def nothing_owed? @@ -46,7 +52,11 @@ def nothing_owed? end def has_errors? - errors.any? || starting_children.select { |c| c.errors.any? }.any? + errors.any? || starting_children_errors? + end + + def starting_children_errors? + is_part_year_claim == 'yes' && starting_children.select { |c| c.errors.any? }.any? end def percent_tax_charge @@ -68,7 +78,7 @@ def child_benefit_end_date end def can_calculate? - valid? && !has_errors? && @starting_children.any? + valid? && !has_errors? end def selected_tax_year @@ -81,12 +91,16 @@ def can_estimate? def benefits_claimed_amount all_weeks_children = {} + full_year_children = @children_count - @part_year_children_count (child_benefit_start_date...child_benefit_end_date).each_slice(7) do |week| monday = monday_on_or_after(week.first) all_weeks_children[monday] = 0 @starting_children.each do |child| all_weeks_children[monday] += 1 if eligible?(child, tax_year, monday) end + full_year_children.times do + all_weeks_children[monday] += 1 + end end # calculate total for all weeks total = all_weeks_children.values.inject(0) do |sum, n| @@ -102,8 +116,14 @@ def tax_estimate private def process_starting_children(children) + if selected_tax_year.present? + number_of_children = @part_year_children_count + else + number_of_children = @children_count + end + [].tap do |ary| - @children_count.times do |n| + number_of_children.times do |n| if children && children[n.to_s] && valid_date_params?(children[n.to_s][:start]) ary << StartingChild.new(children[n.to_s]) else @@ -114,8 +134,10 @@ def process_starting_children(children) end def eligible?(child, tax_year, week_start_date) + adjusted_start_date = monday_on_or_after(child.start_date) + eligible_for_tax_year?(child, tax_year) && - days_include_week?(child.adjusted_start_date, child.benefits_end, week_start_date) + days_include_week?(adjusted_start_date, child.benefits_end, week_start_date) end def eligible_for_tax_year?(child, tax_year) @@ -171,7 +193,13 @@ def parse_child_date(date) end def valid_child_dates - @starting_children.each(&:valid?) + is_part_year_claim == 'yes' && @starting_children.each(&:valid?) + end + + def valid_number_of_children + if @is_part_year_claim == 'yes' && (@children_count < @part_year_children_count) + errors.add(:part_year_children_count, "the number of children you're claiming a part year for can't be more than the total number of children you're claiming for") + end end def tax_year_contains_at_least_one_child diff --git a/app/models/starting_child.rb b/app/models/starting_child.rb index dda40449..82ade811 100644 --- a/app/models/starting_child.rb +++ b/app/models/starting_child.rb @@ -20,12 +20,6 @@ def benefits_end @end_date ? @end_date : tax_years[tax_years.keys.sort.last].last end - # Return the next Monday if start_date is not nil. - def adjusted_start_date - return nil if start_date.nil? - start_date + (start_date.wday < 1 ? 1 : (1 - start_date.wday) + 7) - end - private def valid_dates diff --git a/app/views/child_benefit_tax/_starting_child.html.erb b/app/views/child_benefit_tax/_starting_child.html.erb index f9c7680d..7b118fb7 100644 --- a/app/views/child_benefit_tax/_starting_child.html.erb +++ b/app/views/child_benefit_tax/_starting_child.html.erb @@ -15,5 +15,5 @@ <% end %> <%= select_date (child ? child.end_date : nil), :prefix => "starting_children[#{index}][stop]", :prompt => {:day => "Day", :month => "Month", :year => "Year" }, :order => [:day, :month, :year], - :start_year => 2.years.ago(Date.today).year, :end_year => 10.years.since(Date.today).year %> + :start_year => 3.years.ago(Date.today).year, :end_year => 10.years.since(Date.today).year %> diff --git a/app/views/child_benefit_tax/_starting_children.html.erb b/app/views/child_benefit_tax/_starting_children.html.erb index 46776fe0..2f719cab 100644 --- a/app/views/child_benefit_tax/_starting_children.html.erb +++ b/app/views/child_benefit_tax/_starting_children.html.erb @@ -1,9 +1,16 @@ -<% @calculator.starting_children.each_with_index do |child, index| -%> -
- <% child.errors.each do |key, message| -%> -

<%= message %>

- <% end -%> -

Child <%= index + 1 %>

- <%= render "starting_child", :index => index, :child => child %> +<% if @calculator.starting_children.count == 0 %> +
+

Child 1

+ <%= render "starting_child", index: 0, child: StartingChild.new %>
-<% end -%> +<% else %> + <% @calculator.starting_children.each_with_index do |child, index| -%> +
+ <% child.errors.each do |key, message| -%> +

<%= message %>

+ <% end -%> +

Child <%= index + 1 %>

+ <%= render "starting_child", :index => index, :child => child %> +
+ <% end -%> +<% end %> diff --git a/app/views/child_benefit_tax/main.html.erb b/app/views/child_benefit_tax/main.html.erb index 8c93f801..78e48d58 100644 --- a/app/views/child_benefit_tax/main.html.erb +++ b/app/views/child_benefit_tax/main.html.erb @@ -29,23 +29,14 @@ <% end -%>
- <%= step(1, "Enter the number of children Child Benefit is claimed for:") %> + <%= step(1, "How many children do you want to claim Child Benefit for?") %> <%= select_tag "children_count", options_for_select((1..10).collect{|n| [n,n]}, @calculator.children_count) %> <%= submit_tag "Update", :name => "children", :class => "button update-button" %>
-
- <%= step(2, "Enter the Child Benefit start and stop dates:") %> - - <%= render "starting_children" %> -
-
- <%= step(3, "Choose a tax year:") %> + <%= step(2, "Which tax year are you claiming for?") %>

Tax years run from 6 April to 5 April the following year.

<% @calculator.errors[:tax_year].each do |message| %> @@ -60,16 +51,31 @@
+
+ <%= step(3, "Are you claiming for only a part of the tax year for any of your children?") %> +
+ <% @calculator.errors[:is_part_year_claim].each do |message| %> +

<%= message %>

+ <% end -%> + <% ["yes", "no"].each do |option| -%> + + <% end -%> +
+
+
- <%= step(4, "Enter income details for the tax year (optional):") %> + <%= step(4, "Enter your income details for the tax year (optional):") %> <%= label_tag "gross_income", "Salary before tax" %> <%= money_input "gross_income", @adjusted_net_income_calculator.gross_income, 'aria-describedby' => 'step-4-description' %> - <%= label_tag "other_income", "Other employment income - eg taxable benefits (like a company car or medical insurance), bonuses" %> + <%= label_tag "other_income", "Other employment income - for example taxable benefits (like a company car or medical insurance) or bonuses" %> <%= money_input "other_income", @adjusted_net_income_calculator.other_income, 'aria-describedby' => 'step-4-description' %> <%= label_tag "pension_contributions_from_pay", "Pension contributions deducted from your pay (don't include contributions deducted before tax)" %> <%= money_input "pension_contributions_from_pay", @adjusted_net_income_calculator.pension_contributions_from_pay, 'aria-describedby' => 'step-4-description' %> @@ -77,13 +83,13 @@ <%= money_input "retirement_annuities", @adjusted_net_income_calculator.retirement_annuities, 'aria-describedby' => 'step-4-description' %> <%= label_tag "cycle_scheme", "Cycle scheme" %> <%= money_input "cycle_scheme", @adjusted_net_income_calculator.cycle_scheme, 'aria-describedby' => 'step-4-description' %> - <%= label_tag "childcare", "Childcare paid directly by your employer - eg childcare vouchers (for the whole year but no more than £55 a week), the value of any workplace nursery places" %> + <%= label_tag "childcare", "Childcare paid directly by your employer - for example childcare vouchers (for the whole year but no more than £55 a week) or the value of any workplace nursery places" %> <%= money_input "childcare", @adjusted_net_income_calculator.childcare, 'aria-describedby' => 'step-4-description' %> - <%= label_tag "pensions", "Income from pension(s) - eg from a state pension" %> + <%= label_tag "pensions", "Income from pension(s) - for example from a state pension" %> <%= money_input "pensions", @adjusted_net_income_calculator.pensions, 'aria-describedby' => 'step-4-description' %> - <%= label_tag "property", "Income from property - eg rental income" %> + <%= label_tag "property", "Income from property - for example rental income" %> <%= money_input "property", @adjusted_net_income_calculator.property, 'aria-describedby' => 'step-4-description' %> - <%= label_tag "non_employment_income", "Other income before tax - eg profits from self-employment, taxable savings, dividends" %> + <%= label_tag "non_employment_income", "Other income before tax - for example profits from self-employment, taxable savings, dividends" %> <%= money_input "non_employment_income", @adjusted_net_income_calculator.non_employment_income, 'aria-describedby' => 'step-4-description' %> <%= label_tag "gift_aid_donations", "Gift Aid donations" %> <%= money_input "gift_aid_donations", @adjusted_net_income_calculator.gift_aid_donations, 'aria-describedby' => 'step-4-description' %> @@ -93,6 +99,21 @@ <%= submit_tag "Calculate", :name => "results", :class => "button" %> <% end %> + <% if can_haz_results? -%>
diff --git a/spec/features/child_benefit_tax_calculator_spec.rb b/spec/features/child_benefit_tax_calculator_spec.rb index ccc6417b..586a534b 100644 --- a/spec/features/child_benefit_tax_calculator_spec.rb +++ b/spec/features/child_benefit_tax_calculator_spec.rb @@ -1,7 +1,7 @@ # encoding: utf-8 require "spec_helper" -feature "Child Benefit Tax Calculator" do +feature "Child Benefit Tax Calculator", js: true do specify "inspecting the landing page" do visit "/child-benefit-tax-calculator" @@ -35,32 +35,134 @@ expect(page).to have_no_css(".results") end - it "should display validation errors" do - visit "/child-benefit-tax-calculator" - click_on "Start now" - click_on "Calculate" + context "page errors" do + before :each do + visit "/child-benefit-tax-calculator" + click_on "Start now" + end - within ".validation-summary" do - expect(page).to have_content("select a tax year") - expect(page).to have_content("enter the date Child Benefit started") + context "when tax claim duration isn't selected" do + it "should display validation errors" do + click_on "Calculate" + within ".validation-summary" do + expect(page).to have_content("select a tax year") + expect(page).to have_content("select part year tax claim") + expect(page).to have_no_content("enter the date Child Benefit started") + end + + within "#tax-year" do + expect(page).to have_css(".validation-error") + expect(page).to have_content("select a tax year") + end + + within "#is-part-year-claim" do + expect(page).to have_css(".validation-error") + expect(page).to have_no_css("#children") + expect(page).to have_content("select part year tax claim") + end + end end - within "#tax-year" do - expect(page).to have_css(".validation-error") - expect(page).to have_content("select a tax year") + context "when NO is selected for tax claim duration" do + it "should display validation errors" do + choose "No" + click_on "Calculate" + within ".validation-summary" do + expect(page).to have_content("select a tax year") + expect(page).to have_no_content("enter the date Child Benefit started") + end + + within "#tax-year" do + expect(page).to have_css(".validation-error") + expect(page).to have_content("select a tax year") + end + + within "#is-part-year-claim" do + expect(page).to have_no_css(".validation-error") + expect(page).to have_no_css("#children") + expect(page).to have_no_content("select part year tax claim") + end + end end - within "#children" do - expect(page).to have_css(".validation-error") - expect(page).to have_content("enter the date Child Benefit started") + + context "when YES is selected for tax claim duration" do + it "should display validation errors" do + choose "Yes" + click_on "Calculate" + within ".validation-summary" do + expect(page).to have_content("select a tax year") + expect(page).to have_content("enter the date Child Benefit started") + end + + within "#tax-year" do + expect(page).to have_css(".validation-error") + expect(page).to have_content("select a tax year") + end + + within "#is-part-year-claim" do + expect(page).to have_css(".validation-error") + expect(page).to have_no_content("select part year tax claim") + + within "#children" do + expect(page).to have_css(".validation-error") + expect(page).to have_content("enter the date Child Benefit started") + end + end + end + + it "should ask how many children are being claimed for a part year" do + choose "Yes" + within "#is-part-year-claim" do + within "#children" do + expect(page).to have_select("part_year_children_count") + end + end + end + it "should show two date selectors if two part year children are selected" do + choose "Yes" + select "2", from: "part_year_children_count" + click_button "Update Children" + + within "#is-part-year-claim" do + within "#children" do + expect(page).to have_select("part_year_children_count", selected: "2") + + expect(page).to have_css("#starting_children_0_start_year") + expect(page).to have_css("#starting_children_0_start_month") + expect(page).to have_css("#starting_children_0_start_day") + expect(page).to have_css("#starting_children_1_start_year") + expect(page).to have_css("#starting_children_1_start_month") + expect(page).to have_css("#starting_children_1_start_day") + end + end + end + end + + context "when NO, then YES is selected for tax claim duration" do + it "should display a date selector for one part year child" do + choose "year_2015" + choose "No" + click_button "Calculate" + + choose "Yes" + within "#is-part-year-claim" do + within "#children" do + expect(page).to have_css("#starting_children_0_start_year") + expect(page).to have_css("#starting_children_0_start_month") + expect(page).to have_css("#starting_children_0_start_day") + end + end + end end end - it "should disallow dates with too many days for the selected month", js: true do + it "should disallow dates with too many days for the selected month" do Timecop.travel "2014-09-01" visit "/child-benefit-tax-calculator" click_on "Start now" + choose "Yes" - select "2", from: "children_count" + select "2", from: "part_year_children_count" select "2012", from: "starting_children[0][start][year]" select "February", from: "starting_children[0][start][month]" @@ -85,13 +187,98 @@ ) end + it "should reload children with valid dates if one child has a date error" do + visit "/child-benefit-tax-calculator" + click_on "Start now" + choose "year_2014" + choose "Yes" + select "2", from: "children_count" + select "2", from: "part_year_children_count" + click_button "Update Children" + + + select "2014", from: "starting_children[0][start][year]" + select "April", from: "starting_children[0][start][month]" + select "31", from: "starting_children[0][start][day]" + + select "2014", from: "starting_children[1][start][year]" + select "June", from: "starting_children[1][start][month]" + select "1", from: "starting_children[1][start][day]" + + select "2014", from: "starting_children[1][stop][year]" + select "September", from: "starting_children[1][stop][month]" + select "1", from: "starting_children[1][stop][day]" + + click_button "Calculate" + + expect(page).to have_selector( + ".validation-error", + text: "enter a valid date - there are only 30 days in April", + count: 1, + ) + + expect(page).to have_select("children_count", selected: "2") + expect(page).to have_select("part_year_children_count", selected: "2") + + expect(page).to have_select("starting_children_1_start_year", selected: "2014") + expect(page).to have_select("starting_children_1_start_month", selected: "June") + expect(page).to have_select("starting_children_1_start_day", selected: "1") + + expect(page).to have_select("starting_children_1_stop_year", selected: "2014") + expect(page).to have_select("starting_children_1_stop_month", selected: "September") + expect(page).to have_select("starting_children_1_stop_day", selected: "1") + end + + it "should reload part year children with the correct dates" do + Timecop.travel "2014-05-01" + visit "/child-benefit-tax-calculator" + click_on "Start now" + choose "year_2014" + choose "Yes" + select "2", from: "children_count" + select "1", from: "part_year_children_count" + click_button "Update Children" + + select "2014", from: "starting_children[0][start][year]" + select "June", from: "starting_children[0][start][month]" + select "1", from: "starting_children[0][start][day]" + + select "2014", from: "starting_children[0][stop][year]" + select "September", from: "starting_children[0][stop][month]" + select "1", from: "starting_children[0][stop][day]" + + click_button "Calculate" + + expect(page).to have_select("children_count", selected: "2") + expect(page).to have_select("part_year_children_count", selected: "1") + + expect(page).to have_select("starting_children_0_start_year", selected: "2014") + expect(page).to have_select("starting_children_0_start_month", selected: "June") + expect(page).to have_select("starting_children_0_start_day", selected: "1") + + expect(page).to have_select("starting_children_0_stop_year", selected: "2014") + expect(page).to have_select("starting_children_0_stop_month", selected: "September") + expect(page).to have_select("starting_children_0_stop_day", selected: "1") + end + + it "should allow stop date to be three years in the past" do + Timecop.freeze('2014-04-04') + visit "/child-benefit-tax-calculator" + click_on "Start now" + choose "Yes" + + expected_year_list = ("2011".."2024").to_a + expect(page).to have_select("starting_children_0_stop_year", options: expected_year_list.unshift("Year")) + end + it "should show error if no children are present in the selected tax year" do Timecop.travel "2014-09-01" visit "/child-benefit-tax-calculator" click_on "Start now" + choose "Yes" - select "1", from: "children_count" - click_button "Update" + select "1", from: "part_year_children_count" + click_button "Update Children" page.find("#starting_children_0_start_year").select("2011") page.find("#starting_children_0_start_month").select("January") @@ -118,12 +305,13 @@ before(:each) do visit "/child-benefit-tax-calculator" click_on "Start now" - select "2", from: "children_count" - click_button "Update" + choose "Yes" + select "2", from: "part_year_children_count" + click_button "Update Children" end it "should show the required number of date inputs" do - expect(page).to have_select("children_count", selected: "2") + expect(page).to have_select("part_year_children_count", selected: "2") expect(page).to have_css("#starting_children_0_start_year") expect(page).to have_css("#starting_children_0_start_month") @@ -136,11 +324,11 @@ page.find("#starting_children_0_start_month").select("January") page.find("#starting_children_0_start_day").select("1") - select "3", from: "children_count" + select "3", from: "part_year_children_count" - click_button "Update" + click_button "Update Children" - expect(page).to have_select("children_count", selected: "3") + expect(page).to have_select("part_year_children_count", selected: "3") expect(page).to have_select("starting_children_0_start_year", selected: "2011") expect(page).to have_select("starting_children_0_start_month", selected: "January") @@ -154,17 +342,21 @@ select "January", from: "starting_children_1_start_month" select "7", from: "starting_children_1_start_day" - select "1", from: "children_count" + select "1", from: "part_year_children_count" - click_button "Update" + click_button "Update Children" expect(page).to have_no_css("#starting_children_1_start_year") expect(page).to have_no_css("#starting_children_1_start_month") expect(page).to have_no_css("#starting_children_1_start_day") end - it "should show the required number of date inputs without reloading the page", js: true do - expect(page).to have_select("children_count", selected: "2") + it "should show the required number of date inputs without reloading the page" do + choose "Yes" + select "2", from: "part_year_children_count" + click_button "Update Children" + + expect(page).to have_select("part_year_children_count", selected: "2") expect(page).to have_css("#starting_children_0_start_year") expect(page).to have_css("#starting_children_0_start_month") @@ -177,7 +369,7 @@ page.find("#starting_children_0_start_month").select("January") page.find("#starting_children_0_start_day").select("1") - select "3", from: "children_count" + select "3", from: "part_year_children_count" expect(page).to have_select("starting_children_0_start_year", selected: "2011") expect(page).to have_select("starting_children_0_start_month", selected: "January") @@ -191,7 +383,7 @@ select "January", from: "starting_children_1_start_month" select "7", from: "starting_children_1_start_day" - select "1", from: "children_count" + select "1", from: "part_year_children_count" expect(page).to have_no_css("#starting_children_1_start_year") expect(page).to have_no_css("#starting_children_1_start_month") @@ -204,6 +396,11 @@ end it "calculates the overall benefits received for both children" do + select "2", from: "children_count" + choose "Yes" + select "2", from: "part_year_children_count" + click_button "Update Children" + select "2011", from: "starting_children_0_start_year" select "January", from: "starting_children_0_start_month" select "1", from: "starting_children_0_start_day" @@ -211,6 +408,7 @@ select "2012", from: "starting_children_1_start_year" select "February", from: "starting_children_1_start_month" select "5", from: "starting_children_1_start_day" + choose "year_2012" click_button "Calculate" @@ -227,10 +425,12 @@ allow_any_instance_of(ChildBenefitTaxCalculator).to receive(:benefits_claimed_amount).and_return(500000) visit "/child-benefit-tax-calculator" click_on "Start now" + choose "Yes" end it "should give an estimated total of tax due related to income" do allow_any_instance_of(ChildBenefitTaxCalculator).to receive(:tax_estimate).and_return(500000) + select "2011", from: "starting_children[0][start][year]" select "January", from: "starting_children[0][start][month]" select "1", from: "starting_children[0][start][day]" @@ -262,9 +462,12 @@ end describe "calculating adjusted net income" do + before(:each) do + visit "/child-benefit-tax-calculator" + click_on "Start now" + choose "Yes" + end it "should use the adjusted net income calculator inputs" do - visit "/child-benefit-tax-calculator/main" - select "2011", from: "starting_children[0][start][year]" select "January", from: "starting_children[0][start][month]" select "1", from: "starting_children[0][start][day]" @@ -294,8 +497,6 @@ end it "should update the adjusted_net_income when the calculator values are updated." do - visit "/child-benefit-tax-calculator/main" - select "2011", from: "starting_children[0][start][year]" select "January", from: "starting_children[0][start][month]" select "1", from: "starting_children[0][start][day]" @@ -332,10 +533,14 @@ end describe "displaying the results" do + before(:each) do + visit "/child-benefit-tax-calculator" + click_on "Start now" + choose "Yes" + end + context "without the tax estimate" do before :each do - visit "/child-benefit-tax-calculator/main" - select "2011", from: "starting_children_0_start_year" select "January", from: "starting_children_0_start_month" select "1", from: "starting_children_0_start_day" @@ -376,8 +581,6 @@ context "with the tax estimate" do before :each do - visit "/child-benefit-tax-calculator/main" - select "2011", from: "starting_children_0_start_year" select "January", from: "starting_children_0_start_month" select "1", from: "starting_children_0_start_day" @@ -451,8 +654,6 @@ context "with an Adjusted Net Income below the threshold" do it "should say there's nothing to pay" do - visit "/child-benefit-tax-calculator/main" - select "2011", from: "starting_children_0_start_year" select "January", from: "starting_children_0_start_month" select "1", from: "starting_children_0_start_day" @@ -479,11 +680,49 @@ end # ANI below threshold end + describe "displaying results for full year children only" do + before(:each) do + visit "/child-benefit-tax-calculator" + click_on "Start now" + end + + context "one child" do + it "should correctly display the amount for one child" do + choose "year_2015" + choose "No" + + click_button "Calculate" + + within ".results" do + expect(page).to have_content("£1,097.10") + end + end + end + + context "two children" do + it "should correctly display the amount for two children" do + select "2", from: "children_count" + choose "year_2015" + choose "No" + + click_button "Calculate" + + within ".results" do + expect(page).to have_content("£1,823.20") + end + end + end + end + describe "child benefit week runs Monday to Sunday" do + before(:each) do + visit "/child-benefit-tax-calculator" + click_on "Start now" + choose "Yes" + end + context "tax year is 2012/2013" do specify "should have no child benefit when start date is 07/01/2013" do - visit "/child-benefit-tax-calculator/main" - select "2013", from: "starting_children_0_start_year" select "January", from: "starting_children_0_start_month" select "7", from: "starting_children_0_start_day" @@ -494,8 +733,6 @@ end specify "should have no child benefit when start date is 01/04/2013" do - visit "/child-benefit-tax-calculator/main" - select "2013", from: "starting_children_0_start_year" select "April", from: "starting_children_0_start_month" select "1", from: "starting_children_0_start_day" @@ -507,8 +744,6 @@ end specify "should have no child benefit when start date is 05/04/2013" do - visit "/child-benefit-tax-calculator/main" - select "2013", from: "starting_children_0_start_year" select "April", from: "starting_children_0_start_month" select "5", from: "starting_children_0_start_day" @@ -522,8 +757,6 @@ context "tax year is 2013/2014" do specify "should have no child benefit when start date is 31/03/2014" do - visit "/child-benefit-tax-calculator/main" - select "2014", from: "starting_children_0_start_year" select "March", from: "starting_children_0_start_month" select "31", from: "starting_children_0_start_day" @@ -535,8 +768,6 @@ end specify "should have no child benefit when start date is 01/04/2014" do - visit "/child-benefit-tax-calculator/main" - select "2014", from: "starting_children_0_start_year" select "April", from: "starting_children_0_start_month" select "1", from: "starting_children_0_start_day" @@ -548,8 +779,6 @@ end specify "should have no child benefit when start date is 05/04/2014" do - visit "/child-benefit-tax-calculator/main" - select "2014", from: "starting_children_0_start_year" select "April", from: "starting_children_0_start_month" select "5", from: "starting_children_0_start_day" diff --git a/spec/models/child_benefit_tax_calculator_spec.rb b/spec/models/child_benefit_tax_calculator_spec.rb index cd442a55..9c896065 100644 --- a/spec/models/child_benefit_tax_calculator_spec.rb +++ b/spec/models/child_benefit_tax_calculator_spec.rb @@ -15,6 +15,8 @@ it "is valid if given enough detail" do expect(ChildBenefitTaxCalculator.new( year: "2012", children_count: "1", + is_part_year_claim: "yes", + part_year_children_count: "1", starting_children: { "0" => { start: { year: "2011", month: "01", day: "01" } } }, ).can_calculate?).to eq(true) end @@ -24,9 +26,35 @@ expect(calc.adjusted_net_income).to eq(100900) end + describe "#monday_on_or_after" do + subject { ChildBenefitTaxCalculator.new } + + it "should return the tomorrow if the date is a Sunday" do + sunday = Date.parse("1 January 2012") + monday = Date.parse("2 January 2012") + + expect(subject.monday_on_or_after(sunday)).to eq(monday) + end + + it "should return today if today is a Monday" do + monday = Date.parse("2 January 2012") + + expect(subject.monday_on_or_after(monday)).to eq(monday) + end + + it "should return the following Monday for days between Tueday and Saturday" do + tuesday = Date.parse("3 January 2012") + saturday = Date.parse("7 January 2012") + next_monday = Date.parse("9 January 2012") + + expect(subject.monday_on_or_after(tuesday)).to eq(next_monday) + expect(subject.monday_on_or_after(saturday)).to eq(next_monday) + end + end + describe "input validation" do before(:each) do - @calc = ChildBenefitTaxCalculator.new(children_count: "1") + @calc = ChildBenefitTaxCalculator.new(children_count: "1", is_part_year_claim: "yes") @calc.valid? end it "should contain errors for year if none is given" do @@ -37,8 +65,30 @@ @calc.valid? expect(@calc.errors).to have_key(:tax_year) end + it "should contain errors if number of children is less than those being part claimed" do + @calc = ChildBenefitTaxCalculator.new( + year: "2013", + children_count: "1", + part_year_children_count: "2", + is_part_year_claim: "yes", + starting_children: { + "0" => { + start: { year: "2013", month: "01", day: "01" }, + stop: { year: "2014", month: "01", day: "01" }, + }, + "1" => { + start: { year: "2013", month: "03", day: "01" }, + stop: { year: "2014", month: "03", day: "01" }, + }, + }, + ) + @calc.valid? + + expect(@calc.errors).to have_key(:part_year_children_count) + end it "should validate dates provided for children" do expect(@calc.starting_children.first.errors.has_key?(:start_date)).to eq(true) + @calc.starting_children << StartingChild.new( start: { year: "2012", month: "02", day: "01" }, stop: { year: "2012", month: "01", day: "01" }, @@ -50,6 +100,8 @@ @calc = ChildBenefitTaxCalculator.new( year: "2013", children_count: "1", + is_part_year_claim: "yes", + part_year_children_count: "1", starting_children: { "0" => { start: { year: "2011", month: "01", day: "01" }, @@ -65,6 +117,8 @@ @calc = ChildBenefitTaxCalculator.new( year: "2013", children_count: "1", + is_part_year_claim: "yes", + part_year_children_count: "1", starting_children: { "0" => { start: { year: "2011", month: "01", day: "01" }, @@ -80,6 +134,8 @@ @calc = ChildBenefitTaxCalculator.new( year: "2013", children_count: "3", + is_part_year_claim: "yes", + part_year_children_count: "3", starting_children: { "0" => { start: { year: "2011", month: "01", day: "01" }, @@ -105,22 +161,91 @@ expect(@calc.errors.size).to eq(1) end it "should be true if any starting children have errors" do - calc = ChildBenefitTaxCalculator.new(year: "2012", children_count: "1") + calc = ChildBenefitTaxCalculator.new( + year: "2012", + children_count: "1", + is_part_year_claim: "yes", + part_year_children_count: "1" + ) calc.valid? expect(calc.errors).to be_empty - #puts calc.starting_children.first.errors.full_messages expect(calc.has_errors?).to eq(true) end it "should be false if the tax year and starting date are valid" do expect(ChildBenefitTaxCalculator.new( year: "2012", children_count: "1", + is_part_year_claim: "yes", + part_year_children_count: "1", starting_children: { "0" => { start: { year: "2012", month: "01", day: "07" } }, }, ).has_errors?).to eq(false) end end + + describe "#is_part_year_claim" do + it "should contain errors if tax claim duration is not provided" do + calc = ChildBenefitTaxCalculator.new(children_count: "1", year: 2012) + calc.valid? + expect(calc.errors).to have_key(:is_part_year_claim) + expect(calc.errors.size).to eq(1) + end + it "should not contain errors if tax claim duration is set to no" do + calc = ChildBenefitTaxCalculator.new(children_count: "1", year: 2012, is_part_year_claim: "no") + calc.valid? + expect(calc.errors).to be_empty + end + it "should not contain errors if tax claim duration is set to yes" do + calc = ChildBenefitTaxCalculator.new(children_count: "1", + year: 2012, + is_part_year_claim: "yes", + part_year_children_count: "1", + starting_children: { + "0" => { start: { year: "2012", month: "01", day: "07" } }, + } + ) + calc.valid? + expect(calc.errors).to be_empty + end + end + end + + describe "full year children only" do + it "should be able to calculate the child benefit amount" do + calc = ChildBenefitTaxCalculator.new( + children_count: 1, + year: "2015", + is_part_year_claim: "no", + starting_children: {} + ) + expect(calc.can_calculate?).to eq(true) + end + end + + describe "full year and part year children" do + it "should not contain errors if valid part year and full year children" do + calc = ChildBenefitTaxCalculator.new( + children_count: "3", + year: "2016", + is_part_year_claim: "yes", + part_year_children_count: "2", + starting_children: { + "0" => { + start: { year: "2016", month: "06", day: "13" }, + stop: { year: "2016", month: "06", day: "19" }, + }, + "1" => { + start: { year: "2016", month: "06", day: "20" }, + stop: { year: "2016", month: "06", day: "26" }, + } + } + ) + calc.valid? + calc.starting_children.each do |child| + expect(child.errors).to be_empty + end + end end describe "calculating benefits received" do @@ -128,30 +253,22 @@ expect(ChildBenefitTaxCalculator.new( year: "2012", children_count: "1", - starting_children: { - "0" => { - start: { year: "2011", month: "02", day: "01" }, - stop: { year: "2013", month: "05", day: "01" }, - }, - }, + is_part_year_claim: "no" ).benefits_claimed_amount.round(2)).to eq(263.9) end it "should give the total amount of benefits received for a full tax year 2013" do expect(ChildBenefitTaxCalculator.new( year: "2013", children_count: "1", - starting_children: { - "0" => { - start: { year: "2013", month: "04", day: "06" }, - stop: { year: "2014", month: "04", day: "05" }, - }, - }, + is_part_year_claim: "no" ).benefits_claimed_amount.round(2)).to eq(1055.6) end it "should give the total amount of benefits received for a partial tax year" do expect(ChildBenefitTaxCalculator.new( year: "2012", children_count: "1", + is_part_year_claim: "yes", + part_year_children_count: "1", starting_children: { "0" => { start: { year: "2012", month: "06", day: "01" }, @@ -164,6 +281,8 @@ expect(ChildBenefitTaxCalculator.new( year: "2012", children_count: "2", + is_part_year_claim: "yes", + part_year_children_count: "2", starting_children: { "0" => { start: { year: "2012", month: "06", day: "01" }, @@ -185,6 +304,7 @@ other_income: "0", year: "2012", children_count: 2, + is_part_year_claim: "no", ).adjusted_net_income).to eq(50099) end @@ -202,6 +322,7 @@ childcare: "£1500", year: "2012", children_count: 2, + is_part_year_claim: "no", ).adjusted_net_income).to eq(66950) end @@ -220,6 +341,7 @@ childcare: "£1500", year: "2012", children_count: 2, + is_part_year_claim: "no", ).adjusted_net_income).to eq(66950) end end @@ -230,6 +352,7 @@ adjusted_net_income: "50099", year: "2012", children_count: 2, + is_part_year_claim: "no", ).percent_tax_charge).to eq(0.0) end it "should be 1.0 for an income of 50199" do @@ -237,6 +360,7 @@ adjusted_net_income: "50199", year: "2012", children_count: 2, + is_part_year_claim: "no", ).percent_tax_charge).to eq(1.0) end it "should be 2.0 for an income of 50200" do @@ -244,6 +368,7 @@ adjusted_net_income: "50200", year: "2012", children_count: 2, + is_part_year_claim: "no", ).percent_tax_charge).to eq(2.0) end it "should be 40.0 for an income of 54013" do @@ -251,6 +376,7 @@ adjusted_net_income: "54013", year: "2012", children_count: 2, + is_part_year_claim: "no", ).percent_tax_charge).to eq(40.0) end it "should be 40.0 for an income of 54089" do @@ -258,12 +384,14 @@ adjusted_net_income: "54089", year: "2012", children_count: 2, + is_part_year_claim: "no", ).percent_tax_charge).to eq(40.0) end it "should be 99.0 for an income of 59999" do expect(ChildBenefitTaxCalculator.new( adjusted_net_income: "59999", year: "2012", + is_part_year_claim: "no", children_count: 2, ).percent_tax_charge).to eq(99.0) end @@ -272,6 +400,7 @@ adjusted_net_income: "60000", year: "2012", children_count: 2, + is_part_year_claim: "no", ).percent_tax_charge).to eq(100.0) end it "should be 100.0 for an income of 60001" do @@ -279,6 +408,7 @@ adjusted_net_income: "60001", year: "2012", children_count: 2, + is_part_year_claim: "no", ).percent_tax_charge).to eq(100.0) end end @@ -288,7 +418,9 @@ it "should be true for incomes under the threshold" do expect(ChildBenefitTaxCalculator.new( adjusted_net_income: "49999", + is_part_year_claim: "yes", children_count: 1, + part_year_children_count: "1", starting_children: { "0" => { start: { year: "2011", month: "01", day: "01" } }, }, @@ -298,7 +430,9 @@ it "should be true for incomes over the threshold" do expect(ChildBenefitTaxCalculator.new( adjusted_net_income: "50100", + is_part_year_claim: "yes", children_count: 1, + part_year_children_count: "1", starting_children: { "0" => { start: { year: "2011", month: "01", day: "01" } }, }, @@ -311,6 +445,9 @@ it "calculates the correct amount owed for % charge of 100" do expect(ChildBenefitTaxCalculator.new( adjusted_net_income: "60001", + children_count: "1", + is_part_year_claim: "yes", + part_year_children_count: "1", starting_children: { "0" => { start: { year: "2011", month: "01", day: "01" } }, }, @@ -322,6 +459,8 @@ expect(ChildBenefitTaxCalculator.new( adjusted_net_income: "59900", children_count: 1, + is_part_year_claim: "yes", + part_year_children_count: "1", starting_children: { "0" => { start: { year: "2011", month: "01", day: "01" } }, }, @@ -333,6 +472,8 @@ expect(ChildBenefitTaxCalculator.new( adjusted_net_income: "54000", children_count: 1, + is_part_year_claim: "yes", + part_year_children_count: "1", starting_children: { "0" => { start: { year: "2011", month: "01", day: "01" } }, }, @@ -346,6 +487,8 @@ calc = ChildBenefitTaxCalculator.new( adjusted_net_income: "60001", children_count: 1, + is_part_year_claim: "yes", + part_year_children_count: "1", starting_children: { "0" => { start: { year: "2013", month: "01", day: "01" } }, }, @@ -357,6 +500,8 @@ calc = ChildBenefitTaxCalculator.new( adjusted_net_income: "59900", children_count: 1, + is_part_year_claim: "yes", + part_year_children_count: "1", starting_children: { "0" => { start: { year: "2013", month: "01", day: "01" } }, }, @@ -368,6 +513,8 @@ calc = ChildBenefitTaxCalculator.new( adjusted_net_income: "54000", children_count: "1", + is_part_year_claim: "yes", + part_year_children_count: "1", starting_children: { "0" => { start: { year: "2011", month: "01", day: "01" }, @@ -387,6 +534,8 @@ calc = ChildBenefitTaxCalculator.new( adjusted_net_income: "61000", children_count: 1, + is_part_year_claim: "yes", + part_year_children_count: "1", starting_children: { "0" => { start: { year: "2013", month: "03", day: "01" }, @@ -402,6 +551,8 @@ calc = ChildBenefitTaxCalculator.new( adjusted_net_income: "61000", children_count: 1, + is_part_year_claim: "yes", + part_year_children_count: "1", starting_children: { "0" => { start: { year: "2012", month: "05", day: "01" }, @@ -417,6 +568,8 @@ calc = ChildBenefitTaxCalculator.new( adjusted_net_income: "61000", children_count: 1, + is_part_year_claim: "yes", + part_year_children_count: "1", starting_children: { "0" => { start: { year: "2013", month: "02", day: "01" }, @@ -435,6 +588,8 @@ calc = ChildBenefitTaxCalculator.new( adjusted_net_income: "61000", children_count: 1, + is_part_year_claim: "yes", + part_year_children_count: "1", starting_children: { "0" => { start: { year: "2014", month: "02", day: "22" }, @@ -454,6 +609,8 @@ expect(ChildBenefitTaxCalculator.new( year: "2012", children_count: 3, + is_part_year_claim: "yes", + part_year_children_count: "3", starting_children: { "0" => { start: { day: "06", month: "01", year: "2013" }, @@ -473,7 +630,10 @@ it "should calculate 3 children for 2012/2013 one child starting on 7 Jan 2013" do calc = ChildBenefitTaxCalculator.new( adjusted_net_income: "56000", - year: "2012", children_count: 3, starting_children: { + year: "2012", children_count: 3, + is_part_year_claim: "yes", + part_year_children_count: "3", + starting_children: { "0" => { start: { day: "06", month: "01", year: "2013" }, stop: { day: "05", month: "04", year: "2013" }, @@ -488,40 +648,29 @@ }, }, ) - expect(calc.benefits_claimed_amount.round(2)).to eq(598.90) - expect(calc.tax_estimate).to eq(359) + expect(calc.benefits_claimed_amount.round(2)).to eq(612.30) + expect(calc.tax_estimate).to eq(367) end - it "should calculate one week for one child observing the 'next Monday' rule." do + it "should calculate two weeks for one child observing the 'Monday' rules." do expect(ChildBenefitTaxCalculator.new( year: "2012", children_count: 1, + is_part_year_claim: "yes", + part_year_children_count: "1", starting_children: { "0" => { start: { day: "14", month: "01", year: "2013" }, stop: { day: "21", month: "01", year: "2013" }, }, }, - ).benefits_claimed_amount.round(2)).to eq(20.30) + ).benefits_claimed_amount.round(2)).to eq(40.60) end it "should calculate 3 children already in the household for 2013/2014" do calc = ChildBenefitTaxCalculator.new( adjusted_net_income: "52000", year: "2013", children_count: 3, - starting_children: { - "0" => { - start: { day: "06", month: "04", year: "2013" }, - stop: { day: "", month: "", year: "" }, - }, - "1" => { - start: { day: "06", month: "04", year: "2013" }, - stop: { day: "", month: "", year: "" }, - }, - "2" => { - start: { day: "06", month: "04", year: "2013" }, - stop: { day: "", month: "", year: "" }, - }, - }, + is_part_year_claim: "no" ) expect(calc.benefits_claimed_amount.round(2)).to eq(2449.20) expect(calc.tax_estimate.round(2)).to eq(489) @@ -531,16 +680,10 @@ adjusted_net_income: "53000", year: "2013", children_count: 3, + is_part_year_claim: "yes", + part_year_children_count: "1", starting_children: { "0" => { - start: { day: "06", month: "04", year: "2013" }, - stop: { day: "", month: "", year: "" }, - }, - "1" => { - start: { day: "06", month: "04", year: "2013" }, - stop: { day: "", month: "", year: "" }, - }, - "2" => { start: { day: "06", month: "04", year: "2013" }, stop: { day: "14", month: "06", year: "2013" }, }, @@ -554,9 +697,11 @@ adjusted_net_income: "61000", year: "2013", children_count: 1, + is_part_year_claim: "yes", + part_year_children_count: "1", starting_children: { "0" => { - start: { day: "24", month: "06", year: "2013" }, + start: { day: "01", month: "07", year: "2013" }, stop: { day: "", month: "", year: "" }, }, }, @@ -570,20 +715,7 @@ expect(ChildBenefitTaxCalculator.new( year: "2014", children_count: 3, - starting_children: { - "0" => { - start: { day: "06", month: "04", year: "2014" }, - stop: { day: "", month: "", year: "" }, - }, - "1" => { - start: { day: "06", month: "04", year: "2014" }, - stop: { day: "", month: "", year: "" }, - }, - "2" => { - start: { day: "06", month: "04", year: "2014" }, - stop: { day: "", month: "", year: "" }, - }, - }, + is_part_year_claim: "no" ).benefits_claimed_amount.round(2)).to eq(2475.2) end @@ -591,12 +723,7 @@ expect(ChildBenefitTaxCalculator.new( year: "2014", children_count: "1", - starting_children: { - "0" => { - start: { year: "2014", month: "04", day: "06" }, - stop: { year: "2015", month: "04", day: "05" }, - }, - }, + is_part_year_claim: "no" ).benefits_claimed_amount.round(2)).to eq(1066.0) end @@ -604,12 +731,10 @@ expect(ChildBenefitTaxCalculator.new( year: "2014", children_count: 2, + is_part_year_claim: "yes", + part_year_children_count: "1", starting_children: { "0" => { - start: { day: "06", month: "04", year: "2014" }, - stop: { day: "", month: "", year: "" }, - }, - "1" => { start: { day: "06", month: "04", year: "2014" }, stop: { day: "06", month: "11", year: "2014" }, }, @@ -621,6 +746,8 @@ calc = ChildBenefitTaxCalculator.new( year: "2014", children_count: 1, + is_part_year_claim: "yes", + part_year_children_count: "1", starting_children: { "0" => { start: { day: "06", month: "04", year: "2014" }, @@ -637,57 +764,39 @@ expect(ChildBenefitTaxCalculator.new( year: "2015", children_count: 3, - starting_children: { - "0" => { - start: { day: "06", month: "04", year: "2015" }, - stop: { day: "", month: "", year: "" }, - }, - "1" => { - start: { day: "06", month: "04", year: "2015" }, - stop: { day: "", month: "", year: "" }, - }, - "2" => { - start: { day: "06", month: "04", year: "2015" }, - stop: { day: "", month: "", year: "" }, - }, - }, - ).benefits_claimed_amount.round(2)).to eq(2501.2) + is_part_year_claim: "no" + ).benefits_claimed_amount.round(2)).to eq(2549.3) end it "should give the total amount of benefits received for a full tax year 2015" do expect(ChildBenefitTaxCalculator.new( year: "2015", children_count: "1", - starting_children: { - "0" => { - start: { year: "2015", month: "04", day: "06" }, - stop: { year: "2016", month: "04", day: "05" }, - }, - }, - ).benefits_claimed_amount.round(2)).to eq(1076.4) + is_part_year_claim: "no" + ).benefits_claimed_amount.round(2)).to eq(1097.1) end it "should give total amount of benefits one child full year one child half a year" do expect(ChildBenefitTaxCalculator.new( year: "2015", children_count: 2, + is_part_year_claim: "yes", + part_year_children_count: "1", starting_children: { "0" => { - start: { day: "06", month: "04", year: "2015" }, - stop: { day: "", month: "", year: "" }, - }, - "1" => { start: { day: "06", month: "04", year: "2015" }, stop: { day: "06", month: "11", year: "2016" }, }, }, - ).benefits_claimed_amount.round(2)).to eq(1788.8) + ).benefits_claimed_amount.round(2)).to eq(1823.2) end it "should give total amount of benefits for one child for half a year" do calc = ChildBenefitTaxCalculator.new( year: "2015", children_count: 1, + is_part_year_claim: "yes", + part_year_children_count: "1", starting_children: { "0" => { start: { day: "06", month: "04", year: "2015" }, @@ -695,7 +804,7 @@ }, }, ) - expect(calc.benefits_claimed_amount.round(2)).to eq(621.0) + expect(calc.benefits_claimed_amount.round(2)).to eq(641.7) end end @@ -704,20 +813,7 @@ expect(ChildBenefitTaxCalculator.new( year: "2016", children_count: 3, - starting_children: { - "0" => { - start: { day: "06", month: "04", year: "2016" }, - stop: { day: "", month: "", year: "" }, - }, - "1" => { - start: { day: "06", month: "04", year: "2016" }, - stop: { day: "", month: "", year: "" }, - }, - "2" => { - start: { day: "06", month: "04", year: "2016" }, - stop: { day: "", month: "", year: "" }, - }, - }, + is_part_year_claim: "no" ).benefits_claimed_amount.round(2)).to eq(2501.2) end @@ -725,12 +821,7 @@ expect(ChildBenefitTaxCalculator.new( year: "2016", children_count: "1", - starting_children: { - "0" => { - start: { year: "2016", month: "04", day: "06" }, - stop: { year: "2017", month: "04", day: "05" }, - }, - }, + is_part_year_claim: "no" ).benefits_claimed_amount.round(2)).to eq(1076.4) end @@ -738,12 +829,10 @@ expect(ChildBenefitTaxCalculator.new( year: "2016", children_count: 2, + is_part_year_claim: "yes", + part_year_children_count: "1", starting_children: { "0" => { - start: { day: "06", month: "04", year: "2016" }, - stop: { day: "", month: "", year: "" }, - }, - "1" => { start: { day: "06", month: "04", year: "2016" }, stop: { day: "06", month: "10", year: "2016" }, }, @@ -755,6 +844,8 @@ calc = ChildBenefitTaxCalculator.new( year: "2016", children_count: 1, + is_part_year_claim: "yes", + part_year_children_count: "1", starting_children: { "0" => { start: { day: "06", month: "04", year: "2016" }, @@ -764,6 +855,53 @@ ) expect(calc.benefits_claimed_amount.round(2)).to eq(621.0) end + + it "should set the start date to start of the selected tax year" do + calc = ChildBenefitTaxCalculator.new( + year: "2015", + children_count: 1, + is_part_year_claim: "no" + ) + + expect(calc.child_benefit_start_date).to eq(Date.parse("06 April 2015")) + expect(calc.child_benefit_end_date).to eq(Date.parse("05 April 2016")) + end + + it "should set the stop date to end of the selected tax year" do + calc = ChildBenefitTaxCalculator.new( + year: "2015", + children_count: 1, + is_part_year_claim: "yes", + part_year_children_count: "1", + starting_children: { + "0" => { + start: { day: "06", month: "04", year: "2015" }, + stop: { day: "", month: "", year: "" }, + }, + }, + ) + + expect(calc.child_benefit_end_date).to eq(Date.parse("05 April 2016")) + end + + it "should correctly calculate the benefit amount for multiple full year and part year children" do + expect(ChildBenefitTaxCalculator.new( + year: "2016", + children_count: 4, + is_part_year_claim: "yes", + part_year_children_count: "2", + starting_children: { + "0" => { + start: { day: "01", month: "06", year: "2016" }, + stop: { day: "01", month: "09", year: "2016" } + }, + "1" => { + start: { day: "01", month: "01", year: "2017" }, + stop: { day: "01", month: "04", year: "2017" } + } + } + ).benefits_claimed_amount.round(2)).to eq(2145) + end end end end diff --git a/spec/models/starting_child_spec.rb b/spec/models/starting_child_spec.rb index d5aaf37d..0a2ea535 100644 --- a/spec/models/starting_child_spec.rb +++ b/spec/models/starting_child_spec.rb @@ -45,32 +45,4 @@ ) expect(child).to be_valid end - - describe "adjusted_start_date" do - it "should return the next Monday if start date is 7th January 2013" do - child = StartingChild.new(start: { year: "2013", month: "01", day: "07" }) - expect(child.adjusted_start_date).to eq(Date.parse("14 January 2013")) - end - - it "should return the next Monday for the provided start date" do - child = StartingChild.new(start: { year: "2012", month: "01", day: "01" }) - expect(child.adjusted_start_date).to eq(Date.parse("2 January 2012")) - - child = StartingChild.new(start: { year: "2013", month: "05", day: "08" }) - expect(child.adjusted_start_date).to eq(Date.parse("13 May 2013")) - - child = StartingChild.new(start: { year: "2013", month: "08", day: "13" }) - expect(child.adjusted_start_date).to eq(Date.parse("19 August 2013")) - - child = StartingChild.new(start: { year: "2013", month: "01", day: "06" }) - expect(child.adjusted_start_date).to eq(Date.parse("7 January 2013")) - - child = StartingChild.new(start: { year: "2013", month: "01", day: "14" }) - expect(child.adjusted_start_date).to eq(Date.parse("21 January 2013")) - end - - it "should not blow up with a nil start date" do - expect(StartingChild.new(start: {}).adjusted_start_date).to be_nil - end - end end