Added CLI arg for indicating input file date separator character. Also cleaned up Cli struct. Takes care of one item from #48.

This commit is contained in:
scoobybejesus 2019-10-06 14:04:38 -04:00
parent 8dfb79ed9b
commit 8567dd04b0
5 changed files with 56 additions and 17 deletions

View File

@ -52,6 +52,7 @@ pub struct ImportProcessParameters {
pub enable_like_kind_treatment: bool,
pub costing_method: InventoryCostingMethod,
pub lk_cutoff_date_string: String,
pub date_separator: String,
}
pub(crate) fn import_and_process_final(
@ -62,7 +63,7 @@ pub(crate) fn import_and_process_final(
HashMap<u16, RawAccount>,
HashMap<u32, ActionRecord>,
HashMap<u32, Transaction>,
Option<LikeKindSettings>
Option<LikeKindSettings>,
), Box<dyn Error>> {
let mut transactions_map: HashMap<u32, Transaction> = HashMap::new();
@ -76,7 +77,8 @@ pub(crate) fn import_and_process_final(
&mut transactions_map,
&mut action_records_map,
&mut raw_account_map,
&mut account_map
&mut account_map,
&settings.date_separator,
) {
Ok(()) => { println!("Successfully imported csv file."); }
Err(err) => {
@ -93,6 +95,7 @@ pub(crate) fn import_and_process_final(
action_records: &mut HashMap<u32, ActionRecord>,
raw_acct_map: &mut HashMap<u16, RawAccount>,
acct_map: &mut HashMap<u16, Account>,
date_separator: &str,
) -> Result<(), Box<dyn Error>> {
let file = File::open(import_file_path)?; println!("CSV ledger file opened successfully.\n");
@ -107,6 +110,7 @@ pub(crate) fn import_and_process_final(
&mut rdr,
transactions_map,
action_records,
date_separator,
)?;
Ok(())

View File

@ -111,6 +111,7 @@ pub(crate) fn import_transactions(
rdr: &mut csv::Reader<File>,
txns_map: &mut HashMap<u32, Transaction>,
action_records: &mut HashMap<u32, ActionRecord>,
sep: &str,
) -> Result<(), Box<dyn Error>> {
let mut this_tx_number = 0;
@ -199,9 +200,12 @@ pub(crate) fn import_transactions(
None => {}
}
let tx_date = NaiveDate::parse_from_str(this_tx_date, "%m/%d/%y")
.unwrap_or(NaiveDate::parse_from_str(this_tx_date, "%m/%d/%Y")
.expect("%m/%d/%y (or %Y) format required for ledger import")
let format_yy: &str = &("%m".to_owned() + sep + &"%d" + sep + "%y");
let format_yyyy: &str = &("%m".to_owned() + sep + &"%d" + sep + "%Y");
let tx_date = NaiveDate::parse_from_str(this_tx_date, format_yy)
.unwrap_or(NaiveDate::parse_from_str(this_tx_date, format_yyyy)
.expect("\nFailed to parse date in input file. Check date separator character. Also %m/%d/%y (or %Y) format is required.\n")
);
let transaction = Transaction {

View File

@ -33,6 +33,9 @@ mod skip_wizard;
#[structopt(name = "cryptools")]
pub(crate) struct Cli {
#[structopt(flatten)]
flags: Flags,
/// File to be imported. (Currently, the only supported date format is %m/%d/%y.)
#[structopt(name = "file", parse(from_os_str))]
file_to_import: Option<PathBuf>,
@ -41,16 +44,18 @@ pub(crate) struct Cli {
#[structopt(name = "output directory", short, long = "output", default_value = ".", parse(from_os_str))]
output_dir_path: PathBuf,
/// This will prevent the program from writing the CSV to file. This will be ignored if -a is not set (the wizard will always ask to output).
#[structopt(name = "suppress reports", short, long = "suppress")]
suppress_reports: bool,
/// Choose "h" or "s" for hyphen or slash (i.e., "-" or "/") to indicate the separator character used
/// in the input file txDate column (i.e. 2017/12/31 or 2017-12-31).
#[structopt(name = "date separator character", short, long = "date-separator", default_value = "h", parse(from_os_str))]
date_separator: OsString,
/// Cutoff date through which like-kind exchange treatment should be applied.
/// Please use %y-%m-%d (or %Y-%m-%d) format for like-kind cutoff date entry.
#[structopt(name = "like-kind cutoff date", short, long = "cutoff", parse(from_os_str))]
cutoff_date: Option<OsString>,
#[structopt(name = "like-kind cutoff date", short, long = "lk-cutoff", parse(from_os_str))]
lk_cutoff_date: Option<OsString>,
/// Inventory costing method (in terms of lot selection, i.e., LIFO, FIFO, etc.). There are currently four options (1 through 4).
/// Inventory costing method (in terms of lot selection, i.e., LIFO, FIFO, etc.).
/// There are currently four options (1 through 4).
#[structopt(name = "method", short, long, default_value = "1", parse(from_os_str), long_help =
r" 1. LIFO according to the order the lot was created.
2. LIFO according to the basis date of the lot.
@ -59,13 +64,24 @@ pub(crate) struct Cli {
")]
inv_costing_method: OsString,
/// Home currency (currency in which all resulting reports are denominated). (Only available as a command line setting.)
/// Home currency (currency in which all resulting reports are denominated).
/// (Only available as a command line setting.)
#[structopt(name = "home currency", short = "c", long = "currency", default_value = "USD", parse(from_os_str))]
home_currency: OsString,
}
/// User is instructing the program to skip the data entry wizard. When set, program will error without required command-line args.
#[derive(StructOpt, Debug)]
pub(crate) struct Flags {
/// User is instructing the program to skip the data entry wizard.
/// When set, program will error without required command-line args.
#[structopt(name = "accept args", short, long = "accept")]
accept_args: bool,
/// This will prevent the program from writing reports to files.
/// This will be ignored if -a is not set (the wizard will always ask to output).
#[structopt(name = "suppress reports", short, long = "suppress")]
suppress_reports: bool,
}
@ -92,7 +108,7 @@ fn main() -> Result<(), Box<dyn Error>> {
let like_kind_settings;
let should_export;
if !args.accept_args {
if !args.flags.accept_args {
let (
account_map1,

View File

@ -3,6 +3,7 @@
use std::error::Error;
use std::collections::{HashMap};
use std::process;
use crate::cli_user_choices;
use crate::core_functions::{self, LikeKindSettings, ImportProcessParameters};
@ -19,6 +20,12 @@ pub(crate) fn skip_wizard(args: super::Cli) -> Result<(
bool
), Box<dyn Error>> {
let date_separator = match args.date_separator.into_string().unwrap().as_str() {
"h" => {"-"}
"s" => {"/"}
_ => { println!("\nFATAL: The date-separator arg requires either an 'h' or an 's'.\n"); process::exit(1) }
};
let input_file_path;
if let Some(file) = args.file_to_import {
@ -37,7 +44,7 @@ pub(crate) fn skip_wizard(args: super::Cli) -> Result<(
let like_kind_election;
let like_kind_cutoff_date_string: String;
if let Some(date) = args.cutoff_date {
if let Some(date) = args.lk_cutoff_date {
like_kind_election = true;
like_kind_cutoff_date_string = date.into_string().unwrap();
} else {
@ -51,6 +58,7 @@ pub(crate) fn skip_wizard(args: super::Cli) -> Result<(
costing_method: costing_method_choice,
enable_like_kind_treatment: like_kind_election,
lk_cutoff_date_string: like_kind_cutoff_date_string,
date_separator: date_separator.to_string(),
};
let (
@ -61,7 +69,7 @@ pub(crate) fn skip_wizard(args: super::Cli) -> Result<(
like_kind_settings1
) = core_functions::import_and_process_final(input_file_path, &settings)?;
let should_export = !args.suppress_reports;
let should_export = !args.flags.suppress_reports;
Ok((account_map1, raw_acct_map1, action_records_map1, transactions_map1, like_kind_settings1, settings, should_export))
}

View File

@ -24,6 +24,12 @@ pub(crate) fn wizard(args: super::Cli) -> Result<(
shall_we_proceed()?;
let date_separator = match args.date_separator.into_string().unwrap().as_str() {
"h" => {"-"}
"s" => {"/"}
_ => { println!("\nFATAL: The date-separator arg requires either an 'h' or an 's'.\n"); process::exit(1) }
};
let input_file_path;
if let Some(file) = args.file_to_import {
@ -40,7 +46,7 @@ pub(crate) fn wizard(args: super::Cli) -> Result<(
let lk_cutoff_date_opt_string;
if let Some(lk_cutoff) = args.cutoff_date {
if let Some(lk_cutoff) = args.lk_cutoff_date {
lk_cutoff_date_opt_string = Some(lk_cutoff.into_string().unwrap())
} else {
lk_cutoff_date_opt_string = None
@ -54,6 +60,7 @@ pub(crate) fn wizard(args: super::Cli) -> Result<(
costing_method: costing_method_choice,
enable_like_kind_treatment: like_kind_election,
lk_cutoff_date_string: like_kind_cutoff_date,
date_separator: date_separator.to_string(),
};
let (