From 568a66c6cf84c41f7ac0f21d9028dc7a60c71776 Mon Sep 17 00:00:00 2001 From: Piv <18462828+Piv200@users.noreply.github.com> Date: Thu, 9 Mar 2023 22:28:05 +1030 Subject: [PATCH] Add numeric accounts as property to lib, redistribute floating point errors for each account in overhead allocation --- FastCoster/FastCoster/MoveMoney.swift | 10 +++++++- .../FastCoster/OverheadAllocation.swift | 2 +- src/lib.rs | 3 ++- src/overhead_allocation.rs | 25 +++++++++++++++++-- 4 files changed, 35 insertions(+), 5 deletions(-) diff --git a/FastCoster/FastCoster/MoveMoney.swift b/FastCoster/FastCoster/MoveMoney.swift index fe3a4ff..7fa7fac 100644 --- a/FastCoster/FastCoster/MoveMoney.swift +++ b/FastCoster/FastCoster/MoveMoney.swift @@ -13,6 +13,8 @@ struct MoveMoney: View { @State private var document: CsvDocument? @State private var lines: String? @State private var rules: String? + @State private var costCentres: String? + @State private var accounts: String? var body: some View { VStack { FileButtonSelector(label: "Select Rules File") { result in @@ -21,6 +23,12 @@ struct MoveMoney: View { FileButtonSelector(label: "Select Lines File") { result in lines = result } + FileButtonSelector(label: "Select Cost Centres File") { result in + costCentres = result + } + FileButtonSelector(label: "Select Accounts File") { result in + accounts = result + } Button { move_money() } label: { @@ -43,7 +51,7 @@ struct MoveMoney: View { func move_money() { DispatchQueue.global(qos: .userInitiated).async { // Run move money - let result = move_money_from_text(rules, lines, true) + let result = move_money_from_text(rules, lines, accounts, costCentres, false) DispatchQueue.main.async { document = CsvDocument(data: String(cString: result!)) diff --git a/FastCoster/FastCoster/OverheadAllocation.swift b/FastCoster/FastCoster/OverheadAllocation.swift index cfdcd37..cfb0d41 100644 --- a/FastCoster/FastCoster/OverheadAllocation.swift +++ b/FastCoster/FastCoster/OverheadAllocation.swift @@ -55,7 +55,7 @@ struct OverheadAllocation: View { func allocate_overheads() { DispatchQueue.global(qos: .userInitiated).async { // Run move money - let result = allocate_overheads_from_text(lines, accounts, allocationStatistics, areas, costCentres, accountType); + let result = allocate_overheads_from_text(lines, accounts, allocationStatistics, areas, costCentres, accountType, false); DispatchQueue.main.async { document = CsvDocument(data: String(cString: result!)) diff --git a/src/lib.rs b/src/lib.rs index e0e301e..e9b9785 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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(), diff --git a/src/overhead_allocation.rs b/src/overhead_allocation.rs index 26ee9a7..53c6972 100644 --- a/src/overhead_allocation.rs +++ b/src/overhead_allocation.rs @@ -549,7 +549,7 @@ fn do_solve_reciprocal( 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( 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)