import { Forecast } from '../forecast/forecast';
/**
* salsac is based on an average over the period so get an average of the employer
* NI
* @param {array} arr_tax_years
* @returns {number}
*/
const getAverageErNIrate = (
arr_tax_years,
) => {
const cnt_years = arr_tax_years.length;
let total = 0;
let months = 0;
for (let i = 0; i < cnt_years; i += 1) {
const { months_occupied } = arr_tax_years[i];
months += months_occupied;
const coverage_ratio = months_occupied / 12;
const { skv_tax_charges } = arr_tax_years[i];
total += (skv_tax_charges.national_insurance.employer.class1A * coverage_ratio);
}
return total / (months / 12);
};
/**
* Do the forecast for the period covered
* @param {struct} skv_config
* @param {array} arr_tax_charges income tax, nic rates for the period retrieved from pluto
* @param {array} arr_tax_company_vehicle vehicle benefit, co2 percentage charge for the period retrieved from pluto
* @returns {array} Tax years
*/
const getTaxYears = (
skv_config,
arr_tax_charges,
arr_tax_company_vehicle = [],
) => {
const config = JSON.parse(JSON.stringify(skv_config));
const skv_forecast_config = {
start_month: config.start_month,
start_year: config.start_year,
period_months: config.months,
region_code: config.tax_region_code,
arr_injectors: [{
type: 'salary',
args: {
salary: config.salary_pa,
},
}],
};
// if no tax info for company vehicle don't include the company vehicle injector
// as we'll be calculating without salary sacrifice and no company vehicle
if (arr_tax_company_vehicle.length) {
skv_forecast_config.arr_injectors.push(
{
type: 'company_vehicle',
args: {
co2_after_options: config.co2_after_options,
p11d_inc_taxable_options: config.p11d + config.num_total_options_taxable,
fuel_type: config.fuel_type,
explicit_zero_fuel: true,
with_fuel: config.with_private_fuel,
},
},
);
}
const forecast = new Forecast(
skv_forecast_config,
arr_tax_charges,
arr_tax_company_vehicle,
);
return forecast.calculateTaxes();
};
/**
* calculate bch costs inc irrecoverable vat
* @param {struct} skv_config
* @returns {struct} bch cost and irrecoverable vat
*/
const calculateBCHcost = (
skv_config,
) => {
const skv_return = {};
// if employer can reclaim vat, they'll be able to reclaim half the vat
// otherwise they put the full amount of vat
const non_recoverable_vat_rate = skv_config.vat_percentage / (skv_config.employer_can_reclaim_vat_on_bch ? 2 : 1);
const non_recoverable_vat_rate_dec = non_recoverable_vat_rate / 100;
const { finance_cost, service_fee, num_options_net } = skv_config;
// work out bch cost portion that company can't reclaim
const bch_cost = finance_cost + num_options_net;
skv_return.non_recoverable_vat = bch_cost * non_recoverable_vat_rate_dec;
// company can't reclaim vat on service fee so tack that on top
skv_return.bch_cost = bch_cost + service_fee;
return skv_return;
};
/**
* Description
* @param {data_type} param_name Description
* @returns {data_type} Description
*/
const applyEmployerKeepsNIpercentage = (
status,
employer_keeps_ni,
employer_keeps_ni_percentage,
employer_break_even_avg_yr,
arr_tax_years_no_salsac,
) => {
// handle employer keeps ni net option so we can get a percentage
const temp_employer_keeps_ni_percentage = employer_keeps_ni === 'net' ? 100 : employer_keeps_ni_percentage;
// the salsac is an average over the period and the employer ni rate may
// have changed over the period so get an average
const avg_rate_dec = (getAverageErNIrate(arr_tax_years_no_salsac) / 100) + 1;
// i.e if its 100% ni kept on top of employer_break_even_avg_yr
const full_ni_kept = employer_break_even_avg_yr * avg_rate_dec;
// work out how much of it is additional ni for the employer
let amount_ni_kept = full_ni_kept - employer_break_even_avg_yr;
// apply the % the employer keeps
amount_ni_kept *= (temp_employer_keeps_ni_percentage / 100);
return employer_break_even_avg_yr + amount_ni_kept;
};
export {
getAverageErNIrate,
getTaxYears,
calculateBCHcost,
applyEmployerKeepsNIpercentage,
};