/**
* Brings various whole life cost components
* @module
*/
import { requiredKeys } from '../../../keys/required';
// import { calculate as calculateFuelAndElectric } from './components/fuelandelectric/ppm';
import { buildConfig } from './components/config';
import { getCost as fuelAndElectricCosts } from '../result';
/**
*
* @returns {struct}
*/
const checkRequiredKeys = (skv_config) => {
// ensure we have the basic keys required
const required_keys = [
'total_miles',
'vehicle',
'include_components',
];
const rst_required_keys = requiredKeys(skv_config, required_keys);
// check to see if any keys missing
if (
!rst_required_keys.success
|| rst_required_keys.data.length > 0
) {
let missing_keys_msg = '';
if (rst_required_keys.data.length > 0) {
missing_keys_msg = ` // Missing required keys: ${rst_required_keys.data}`;
}
throw new Error(` ${rst_required_keys.msg}${missing_keys_msg} for running.vehicle.journey`);
}
};
/**
* check should calculate is specifies a list of components to calculate
* @param {any} value
*/
const checkIncludeComponents = (data) => {
// valid values for include_components
const valid_values = [
'fuel and electric',
'depreciation',
'mot',
'ved',
'servicing',
// contract hire (bch, flb, pch, pcp?)
// non reclaimable vat
// class 1a nic vehicle benefit
// amount paid
// residual value
];
// check passed in value is an array
if (!Array.isArray(data)) {
throw new Error('include_components is not an array');
}
// check passed in value is not empty
if (data.length === 0) {
throw new Error('No calculations requested');
}
// check only valid strings are passed in
data.forEach((value) => {
if (!valid_values.includes(value)) {
throw new Error('Invalid value in include_components');
}
});
};
/**
* change a component name in to a valid key format to return
* => convert component name to lowercase and spaces for underscores
* @param {string} str_component_name
* @returns {string}
*/
const changeStringToKey = (str_component_name) => str_component_name.toLowerCase().replace(/ /g, '_');
/**
* bring together individual components to form a wlc calculation
* @param {struct} skv_config
* @returns {struct}
*/
const combineComponents = (skv_config) => {
const skv_return = {};
let skv_component_cfg = {};
let skv_component_data = {};
// loop over skv_config.include_components
skv_config.include_components.forEach((component_name) => {
if (component_name === 'fuel and electric') {
// do any manipulation of the config here before passing to the component
skv_component_cfg = buildConfig(skv_config, 'fuel and electric');
skv_component_data = fuelAndElectricCosts(skv_component_cfg);
}
const component_key = changeStringToKey(component_name);
skv_return[component_key] = skv_component_data;
});
return skv_return;
};
/**
* overall wlc calculation
* @param {struct} skv_config
* @returns {struct}
*/
const calculate = (skv_config) => {
let skv_return = {
total: {},
};
// check to see if we have the required keys
checkRequiredKeys(skv_config);
// check should calculate is an array and not empty
checkIncludeComponents(skv_config.include_components);
// merge the results from all the components calculating and existing
// skv_return object with total key
skv_return = { ...combineComponents(skv_config), ...skv_return };
// TODO: finish totals when more components
return skv_return;
};
export {
calculate,
checkRequiredKeys,
checkIncludeComponents,
combineComponents,
changeStringToKey,
};