Add numeric accounts as property to lib, redistribute floating point errors for each account in overhead allocation
This commit is contained in:
@@ -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!))
|
||||
|
||||
@@ -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!))
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user