tool/salarysacrifice/configuration.js

/**
 * Description
 * @param {data_type} param_name Description
 * @returns {data_type} Description
 */
const buildInit = (
    skv_config,
) => {
    const skv_default_config = {
        // TODO: remove, deprecated by early termination insurance
        bch_contingency_percentage: 2,
        insurance_cost_pa: 700,
        employer_pays_insurance: true,
        // yes/no/net/percentage
        employer_keeps_ni: 'no',
        employer_keeps_ni_percentage: '',
        amaps: 0,
        charger_installation_cost: 0,
        charger_installation_available_for_phev: true,
        employer_can_reclaim_vat_on_bch: true,
        early_termination_ins_percent: 0,
        insurance_premium_tax_percentage: 0,
    };

    const skv_return_cfg = JSON.parse(JSON.stringify(skv_default_config));
    const args_config = JSON.parse(JSON.stringify(skv_config));

    const config_arg_keys = Object.keys(args_config);
    const cnt_keys = config_arg_keys.length;

    // loop over the arguments config
    for (let i = 0; i < cnt_keys; i += 1) {
        // config from the arguments
        const str_key = config_arg_keys[i];

        // move key/value from arguments config to the local config
        skv_return_cfg[str_key] = args_config[str_key];
    }

    // default service_fee to 0 if not set as some clients may not provide
    // split service fee and finance cost so we'll assume the bch cost is made
    // fully of finance cost rather than finance cost + service fee
    if (!skv_return_cfg.skv_price.service_fee) {
        skv_return_cfg.skv_price.service_fee = 0;
    }

    // work out the finance cost based on price (which is effectively the bch cost)
    skv_return_cfg.skv_price.finance_cost = skv_return_cfg.skv_price.price - skv_return_cfg.skv_price.service_fee;

    // check a employer ni percentage isn't passed in when we don't need it
    if (
        skv_return_cfg.employer_keeps_ni !== 'percentage'
        && skv_return_cfg.employer_keeps_ni_percentage !== ''
    ) {
        throw new Error('Employer NI percentage passed in but the employer_keeps_ni property is not set to "percentage"');
    }

    // check a employer ni percentage is passed in when required
    if (
        skv_return_cfg.employer_keeps_ni === 'percentage'
    ) {
        if (
            skv_return_cfg.employer_keeps_ni_percentage === ''
            || Number.isNaN(skv_return_cfg.employer_keeps_ni_percentage)
        ) {
            throw new Error('No Employer NI percentage value passed in or value NaN but the employer_keeps_ni property is set to "percentage"');
        }
    } else if (skv_return_cfg.employer_keeps_ni === 'yes') {
        skv_return_cfg.employer_keeps_ni_percentage = 100;
    } else if (skv_return_cfg.employer_keeps_ni === 'no') {
        skv_return_cfg.employer_keeps_ni_percentage = 0;
    }

    return skv_return_cfg;
};

/**
 * Description
 * @param {data_type} param_name Description
 * @returns {data_type} Description
 */
const buildWithoutSalsac = (
    skv_config,
) => ({
    months: skv_config.months,
    tax_region_code: skv_config.tax_region_code,
    salary_pa: skv_config.salary_pa,
    start_month: skv_config.start_month,
    start_year: skv_config.start_year,
    // no salary sacrificed at this point but pass it in for the calculation
    salary_sacrificed: 0,
});

/**
 * Description
 * @param {data_type} param_name Description
 * @returns {data_type} Description
 */
const buildWithSalsac = (
    skv_config,
    skv_extra_data,
) => {
    const skv_return_config = JSON.parse(JSON.stringify(skv_config));

    const num_salary_minus_sacrifice = skv_return_config.salary_pa - skv_extra_data.employer_break_even_avg_yr;

    // update the config with the reduced salary
    skv_return_config.salary_pa = num_salary_minus_sacrifice;
    skv_return_config.salary_sacrificed = skv_extra_data.employer_break_even_avg_yr;

    return skv_return_config;
};

/**
 * Build starting config
 * @param {struct} skv_config
 * @param {string} instruction init/withsalsac/withoutsalsac
 * @returns {struct} built config
 */
const create = (
    skv_config,
    stage,
    skv_extra_data,
) => {
    switch (stage) {
    case 'init':
        return buildInit(skv_config);
    case 'without_salsac':
        return buildWithoutSalsac(skv_config);
    case 'with_salsac':
        return buildWithSalsac(skv_config, skv_extra_data);
    default:
        throw new Error(`Unknown stage ${stage}`);
    }
};

export {
    create,
};