Remove smush rules, fix warnings
This commit is contained in:
@@ -8,7 +8,6 @@ use std::{
|
|||||||
|
|
||||||
use chrono::NaiveDateTime;
|
use chrono::NaiveDateTime;
|
||||||
use csv::Position;
|
use csv::Position;
|
||||||
use itertools::Itertools;
|
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
#[derive(Hash, PartialEq, PartialOrd, Ord, Eq)]
|
#[derive(Hash, PartialEq, PartialOrd, Ord, Eq)]
|
||||||
|
|||||||
@@ -5,9 +5,6 @@ use std::ffi::CString;
|
|||||||
|
|
||||||
pub use self::move_money::*;
|
pub use self::move_money::*;
|
||||||
|
|
||||||
mod smush_rules;
|
|
||||||
pub use self::smush_rules::*;
|
|
||||||
|
|
||||||
mod overhead_allocation;
|
mod overhead_allocation;
|
||||||
pub use self::overhead_allocation::*;
|
pub use self::overhead_allocation::*;
|
||||||
|
|
||||||
@@ -50,7 +47,8 @@ pub extern "C" fn move_money_from_text(
|
|||||||
&mut output_writer,
|
&mut output_writer,
|
||||||
use_numeric_accounts,
|
use_numeric_accounts,
|
||||||
true,
|
true,
|
||||||
);
|
)
|
||||||
|
.expect("Failed to move money");
|
||||||
// TODO: Replace all these unwraps with something more elegant
|
// TODO: Replace all these unwraps with something more elegant
|
||||||
let inner = output_writer.into_inner().unwrap();
|
let inner = output_writer.into_inner().unwrap();
|
||||||
CString::new(String::from_utf8(inner).unwrap())
|
CString::new(String::from_utf8(inner).unwrap())
|
||||||
@@ -119,7 +117,8 @@ pub extern "C" fn allocate_overheads_from_text(
|
|||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
account_type.to_str().unwrap().to_owned(),
|
account_type.to_str().unwrap().to_owned(),
|
||||||
);
|
)
|
||||||
|
.expect("Failed to allocate overheads");
|
||||||
let inner = output_writer.into_inner().unwrap();
|
let inner = output_writer.into_inner().unwrap();
|
||||||
CString::new(String::from_utf8(inner).unwrap())
|
CString::new(String::from_utf8(inner).unwrap())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|||||||
33
src/main.rs
33
src/main.rs
@@ -1,8 +1,6 @@
|
|||||||
use std::{collections::HashMap, error::Error, io::Write, path::PathBuf};
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
use coster_rs::CsvCost;
|
|
||||||
use serde::Deserialize;
|
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
#[command(name = "coster-rs")]
|
#[command(name = "coster-rs")]
|
||||||
@@ -17,7 +15,7 @@ struct Cli {
|
|||||||
#[derive(Subcommand)]
|
#[derive(Subcommand)]
|
||||||
enum Commands {
|
enum Commands {
|
||||||
/// Moves money between accounts and departments, using the given rules and lines
|
/// Moves money between accounts and departments, using the given rules and lines
|
||||||
move_money {
|
MoveMoney {
|
||||||
#[arg(short = 'r', long, value_name = "FILE")]
|
#[arg(short = 'r', long, value_name = "FILE")]
|
||||||
rules: PathBuf,
|
rules: PathBuf,
|
||||||
|
|
||||||
@@ -39,16 +37,8 @@ enum Commands {
|
|||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
flush_pass: bool,
|
flush_pass: bool,
|
||||||
},
|
},
|
||||||
/// Combines rules to the minimum set required
|
|
||||||
smush_rules {
|
|
||||||
#[arg(short = 'r', long, value_name = "FILE")]
|
|
||||||
rules: PathBuf,
|
|
||||||
|
|
||||||
#[arg(short, long, value_name = "FILE")]
|
|
||||||
output: Option<PathBuf>,
|
|
||||||
},
|
|
||||||
/// Allocates servicing department amounts to operating departments
|
/// Allocates servicing department amounts to operating departments
|
||||||
allocate_overheads {
|
AllocateOverheads {
|
||||||
#[arg(short, long, value_name = "FILE")]
|
#[arg(short, long, value_name = "FILE")]
|
||||||
lines: PathBuf,
|
lines: PathBuf,
|
||||||
|
|
||||||
@@ -79,7 +69,7 @@ fn main() -> anyhow::Result<()> {
|
|||||||
let cli = Cli::parse();
|
let cli = Cli::parse();
|
||||||
|
|
||||||
match cli.command {
|
match cli.command {
|
||||||
Commands::move_money {
|
Commands::MoveMoney {
|
||||||
rules,
|
rules,
|
||||||
lines,
|
lines,
|
||||||
accounts,
|
accounts,
|
||||||
@@ -96,8 +86,7 @@ fn main() -> anyhow::Result<()> {
|
|||||||
use_numeric_accounts,
|
use_numeric_accounts,
|
||||||
flush_pass,
|
flush_pass,
|
||||||
),
|
),
|
||||||
Commands::smush_rules { rules, output } => smush_rules(rules, output),
|
Commands::AllocateOverheads {
|
||||||
Commands::allocate_overheads {
|
|
||||||
lines,
|
lines,
|
||||||
accounts,
|
accounts,
|
||||||
allocation_statistics,
|
allocation_statistics,
|
||||||
@@ -139,10 +128,6 @@ fn move_money(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn smush_rules(rules_path: PathBuf, output: Option<PathBuf>) -> anyhow::Result<()> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn allocate_overheads(
|
fn allocate_overheads(
|
||||||
lines: PathBuf,
|
lines: PathBuf,
|
||||||
accounts: PathBuf,
|
accounts: PathBuf,
|
||||||
@@ -166,11 +151,3 @@ fn allocate_overheads(
|
|||||||
account_type,
|
account_type,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
|
||||||
struct CsvOverheadAllocationRule {
|
|
||||||
from_overhead_department: String,
|
|
||||||
to_department: String,
|
|
||||||
percent: f64,
|
|
||||||
to_department_type: String,
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
use std::{
|
use std::collections::{HashMap, HashSet};
|
||||||
collections::{HashMap, HashSet},
|
|
||||||
thread::current,
|
|
||||||
};
|
|
||||||
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use serde::{Deserialize, Serialize, Serializer};
|
use serde::{Deserialize, Serialize, Serializer};
|
||||||
@@ -26,15 +23,6 @@ struct CsvMovementRule {
|
|||||||
dest_from_account: String,
|
dest_from_account: String,
|
||||||
#[serde(rename = "AccountDestTo", default)]
|
#[serde(rename = "AccountDestTo", default)]
|
||||||
dest_to_account: String,
|
dest_to_account: String,
|
||||||
// TODO: Check how these actually work, they're somehow integrated into other columns
|
|
||||||
#[serde(default)]
|
|
||||||
all_from_departments: bool,
|
|
||||||
#[serde(default)]
|
|
||||||
all_to_departments: bool,
|
|
||||||
#[serde(default)]
|
|
||||||
all_from_accounts: bool,
|
|
||||||
#[serde(default)]
|
|
||||||
all_to_accounts: bool,
|
|
||||||
#[serde(rename = "AmountValue")]
|
#[serde(rename = "AmountValue")]
|
||||||
amount: Option<f64>,
|
amount: Option<f64>,
|
||||||
#[serde(rename = "AmountType", default)]
|
#[serde(rename = "AmountType", default)]
|
||||||
@@ -166,7 +154,7 @@ where
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
let mut accounts_reader = accounts_reader;
|
let accounts_reader = accounts_reader;
|
||||||
let all_accounts = accounts_reader
|
let all_accounts = accounts_reader
|
||||||
.deserialize()
|
.deserialize()
|
||||||
.collect::<Result<Vec<CsvAccount>, csv::Error>>()?;
|
.collect::<Result<Vec<CsvAccount>, csv::Error>>()?;
|
||||||
@@ -203,7 +191,6 @@ where
|
|||||||
.unique()
|
.unique()
|
||||||
.sorted()
|
.sorted()
|
||||||
.collect();
|
.collect();
|
||||||
let mut rules_reader = rules_reader;
|
|
||||||
let mut rules: Vec<MovementRule> = vec![];
|
let mut rules: Vec<MovementRule> = vec![];
|
||||||
for movement_rule in rules_reader.deserialize() {
|
for movement_rule in rules_reader.deserialize() {
|
||||||
// TODO: Consider reclass rule group, how does that even work?
|
// TODO: Consider reclass rule group, how does that even work?
|
||||||
@@ -375,10 +362,10 @@ pub fn move_money_2(
|
|||||||
// to add a new line
|
// to add a new line
|
||||||
let mut running_total = HashMap::from(initial_totals);
|
let mut running_total = HashMap::from(initial_totals);
|
||||||
let mut temp_total = running_total.clone();
|
let mut temp_total = running_total.clone();
|
||||||
let mut moveMoneyResult: Vec<MoveMoneyResult> = vec![];
|
let mut move_money_result: Vec<MoveMoneyResult> = vec![];
|
||||||
let mut current_pass = 0;
|
let mut current_pass = 0;
|
||||||
if flush_pass {
|
if flush_pass {
|
||||||
moveMoneyResult.push(MoveMoneyResult {
|
move_money_result.push(MoveMoneyResult {
|
||||||
pass: current_pass,
|
pass: current_pass,
|
||||||
totals: running_total.clone(),
|
totals: running_total.clone(),
|
||||||
})
|
})
|
||||||
@@ -388,7 +375,7 @@ pub fn move_money_2(
|
|||||||
if flush_pass {
|
if flush_pass {
|
||||||
current_pass += 1;
|
current_pass += 1;
|
||||||
// Flush the totals at the end of this pass (more specifically the change)
|
// Flush the totals at the end of this pass (more specifically the change)
|
||||||
moveMoneyResult.push(MoveMoneyResult {
|
move_money_result.push(MoveMoneyResult {
|
||||||
pass: current_pass,
|
pass: current_pass,
|
||||||
totals: temp_total
|
totals: temp_total
|
||||||
.iter()
|
.iter()
|
||||||
@@ -433,12 +420,12 @@ pub fn move_money_2(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
moveMoneyResult.push(MoveMoneyResult {
|
move_money_result.push(MoveMoneyResult {
|
||||||
pass: current_pass,
|
pass: current_pass,
|
||||||
totals: temp_total,
|
totals: temp_total,
|
||||||
});
|
});
|
||||||
|
|
||||||
moveMoneyResult
|
move_money_result
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -453,6 +440,7 @@ mod tests {
|
|||||||
&mut csv::Writer::from_path("output.csv").unwrap(),
|
&mut csv::Writer::from_path("output.csv").unwrap(),
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
);
|
)
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
use std::{collections::{HashMap, HashSet}, io::Read, path::Path};
|
use std::{
|
||||||
|
collections::{HashMap, HashSet},
|
||||||
|
io::Read,
|
||||||
|
};
|
||||||
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use nalgebra::{DMatrix, Dynamic, LU};
|
use nalgebra::{DMatrix, Dynamic, LU};
|
||||||
@@ -26,8 +29,6 @@ impl DepartmentType {
|
|||||||
pub struct CsvAllocationStatistic {
|
pub struct CsvAllocationStatistic {
|
||||||
#[serde(rename = "Name")]
|
#[serde(rename = "Name")]
|
||||||
name: String,
|
name: String,
|
||||||
#[serde(rename = "Description")]
|
|
||||||
description: Option<String>,
|
|
||||||
#[serde(rename = "AccountType")]
|
#[serde(rename = "AccountType")]
|
||||||
account_type: String,
|
account_type: String,
|
||||||
#[serde(rename = "AccountRanges")]
|
#[serde(rename = "AccountRanges")]
|
||||||
@@ -39,8 +40,6 @@ pub struct AllocationStatisticAccountRange {
|
|||||||
end: usize,
|
end: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
type CsvArea = HashMap<String, String>;
|
|
||||||
|
|
||||||
// Note: remember these are overhead departments only when calculating the lu decomposition or pseudoinverse, and for each department,
|
// Note: remember these are overhead departments only when calculating the lu decomposition or pseudoinverse, and for each department,
|
||||||
// you either need -1 or rest negative for a row to subtract the initial amounts so we end up effectively 0 (simultaneous equations end
|
// you either need -1 or rest negative for a row to subtract the initial amounts so we end up effectively 0 (simultaneous equations end
|
||||||
// up with negative there so yes this is expected)
|
// up with negative there so yes this is expected)
|
||||||
@@ -247,7 +246,7 @@ where
|
|||||||
if current_area_ccs.is_none() {
|
if current_area_ccs.is_none() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let mut current_area_ccs = current_area_ccs.unwrap().clone();
|
let current_area_ccs = current_area_ccs.unwrap().clone();
|
||||||
|
|
||||||
for cc in current_area_ccs {
|
for cc in current_area_ccs {
|
||||||
overhead_ccs.insert(cc);
|
overhead_ccs.insert(cc);
|
||||||
@@ -592,7 +591,6 @@ fn do_solve_reciprocal<T: ReciprocalAllocationSolver>(
|
|||||||
mod tests {
|
mod tests {
|
||||||
use crate::reciprocal_allocation;
|
use crate::reciprocal_allocation;
|
||||||
use crate::AccountCost;
|
use crate::AccountCost;
|
||||||
use crate::CsvCost;
|
|
||||||
use crate::DepartmentType;
|
use crate::DepartmentType;
|
||||||
use crate::OverheadAllocationRule;
|
use crate::OverheadAllocationRule;
|
||||||
use crate::TotalDepartmentCost;
|
use crate::TotalDepartmentCost;
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
// Rules get parsed from file, converted into matrix format (for the in-memory movement),
|
|
||||||
// then combined (smushed) into a single matrix + vector/rule for each . The list of units can then have the rules applied
|
|
||||||
//
|
|
||||||
// For now just ignore the all from/to stuff, it's kind of a shit thing to do, and can
|
|
||||||
// be worked around by actually inputting every type into the rules
|
|
||||||
|
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use crate::MovementRule;
|
|
||||||
|
|
||||||
pub fn smush_rules(rules: Vec<MovementRule>) -> Vec<MovementRule> {
|
|
||||||
let ruleMapping: HashMap<String, usize> = HashMap::new();
|
|
||||||
// First build out the list/map of all departments (store index of each element in the array)
|
|
||||||
// TODO: We could make this more advanced by only smushing per divider, so that only the departments
|
|
||||||
// needed between each pass is actually required
|
|
||||||
for rule in rules {
|
|
||||||
for department in rule.from_departments {
|
|
||||||
// ruleMapping.entry(department).or_insert(ruleMapping.len());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
vec![]
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user