Add numeric accounts as property to lib, redistribute floating point errors for each account in overhead allocation

This commit is contained in:
Piv
2023-03-09 22:28:05 +10:30
parent 5603ccfd25
commit 568a66c6cf
4 changed files with 35 additions and 5 deletions

View File

@@ -80,6 +80,7 @@ pub extern "C" fn allocate_overheads_from_text(
areas: *const c_char,
cost_centres: *const c_char,
account_type: *const c_char,
use_numeric_accounts: bool,
) -> *mut c_char {
let lines = unsafe {
assert!(!lines.is_null());
@@ -113,7 +114,7 @@ pub extern "C" fn allocate_overheads_from_text(
csv::Reader::from_reader(areas.to_bytes()),
csv::Reader::from_reader(cost_centres.to_bytes()),
&mut output_writer,
true,
use_numeric_accounts,
false,
true,
account_type.to_str().unwrap().to_owned(),

View File

@@ -549,7 +549,7 @@ fn do_solve_reciprocal<T: ReciprocalAllocationSolver>(
let calculated_overheads = solver.solve(&overhead_costs_vec);
let mut operating_slice_costs = vec![0.; operating_department_mappings.len()];
for cost in total_costs.summed_department_costs {
for cost in &total_costs.summed_department_costs {
if operating_department_mappings.contains_key(&cost.department) {
let elem = &mut operating_slice_costs
[*operating_department_mappings.get(&cost.department).unwrap()];
@@ -579,9 +579,30 @@ fn do_solve_reciprocal<T: ReciprocalAllocationSolver>(
value: *calculated.get(*index).unwrap(),
})
.collect();
// Redistribute floating point errors (only for ccs we actually allocated from/to)
// TODO: Still not sure if this is 100% correct, however it appears with this we match up
// with the line totals. I think this is because ppm just evenly redistributes floating point
// errors, whereas we keep the amounts proportional to the intial amounts
let initial_cost: f64 = total_costs
.summed_department_costs
.iter()
.filter(|cost| {
operating_department_mappings.contains_key(&cost.department)
|| overhead_department_mappings.contains_key(&cost.department)
})
.map(|cost| cost.value)
.sum();
let new_cost: f64 = converted_result.iter().map(|cost| cost.value).sum();
let diff = initial_cost - new_cost;
final_account_costs.push(AccountCost {
account: total_costs.account,
summed_department_costs: converted_result,
summed_department_costs: converted_result
.into_iter()
.map(|cost| TotalDepartmentCost {
department: cost.department,
value: cost.value + cost.value / new_cost * diff,
})
.collect(),
});
}
Ok(final_account_costs)