Compare commits
5 Commits
90c55062bf
...
f117b155cf
Author | SHA1 | Date |
---|---|---|
scoobybejesus | f117b155cf | |
scoobybejesus | 059e2b2a90 | |
scoobybejesus | 78fa173ceb | |
scoobybejesus | 396a084fcd | |
scoobybejesus | 51b021b298 |
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "cryptools"
|
name = "cryptools"
|
||||||
version = "0.9.0"
|
version = "0.9.1"
|
||||||
authors = ["scoobybejesus <scoobybejesus@users.noreply.github.com>"]
|
authors = ["scoobybejesus <scoobybejesus@users.noreply.github.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
description = "Command-line utility for processing cryptocurrency transactions into 'lots' and 'movements'."
|
description = "Command-line utility for processing cryptocurrency transactions into 'lots' and 'movements'."
|
||||||
|
|
|
@ -61,11 +61,11 @@ The rules for successfully preparing and maintaining the input file can generall
|
||||||
|
|
||||||
1. The first account must be given number `1`, and each additional account must count up sequentially.
|
1. The first account must be given number `1`, and each additional account must count up sequentially.
|
||||||
2. Margin quote account `ticker`s must be followed by an underscore and the base account ticker (i.e., `BTC_xmr`).
|
2. Margin quote account `ticker`s must be followed by an underscore and the base account ticker (i.e., `BTC_xmr`).
|
||||||
3. `Proceeds` is the value of the transaction, whether spent, received, or exchanged.
|
3. `Proceeds` is the value of the transaction (measured in the home currency), whether spent, received, or exchanged.
|
||||||
It is **required** in order to properly calculate income/expense/gain/loss.
|
It is **required** in order to properly calculate income/expense/gain/loss.
|
||||||
4. `Proceeds` must have a period as a decimal separator (`1,000.00` not `1.000,00`) and must not contain the ticker or symbol (USD or $).
|
4. `Proceeds` must have a period as a decimal separator (`1,000.00` not `1.000,00`) and must not contain the ticker or symbol (USD or $).
|
||||||
5. Only home currency accounts can have negative balances. Crypto accounts may not go negative at any time.
|
5. Only home currency accounts can have negative balances. Crypto accounts may not go negative at any time.
|
||||||
(Exception: crypto margin accounts may go negative, of course.)
|
(Exception: crypto margin accounts may go negative.)
|
||||||
|
|
||||||
As you can see, most of the rules can generally be ignored.
|
As you can see, most of the rules can generally be ignored.
|
||||||
In fact, the only tricky field is the `proceeds` column, but even that becomes second nature soon enough.
|
In fact, the only tricky field is the `proceeds` column, but even that becomes second nature soon enough.
|
||||||
|
@ -82,18 +82,18 @@ In order to be successfully imported, the CSV input file **must** be in a prescr
|
||||||
| | | |Bank |Exchange|Wallet |Exchange|Simplewallet|
|
| | | |Bank |Exchange|Wallet |Exchange|Simplewallet|
|
||||||
| | | | USD | BTC | BTC | XMR | XMR |
|
| | | | USD | BTC | BTC | XMR | XMR |
|
||||||
| | | | non | non | non | non | non |
|
| | | | non | non | non | non | non |
|
||||||
|2/1/16 |0 |Bought | -220| 0.25| | | |
|
|2-1-16 |0 |Bought | -220| 0.25| | | |
|
||||||
|3/1/16 |250 |Traded | | -0.25| | 180| |
|
|3-1-16 |250 |Traded | | -0.25| | 180| |
|
||||||
|4/1/16 |0 |Transferred | | | | -90| 90|
|
|4-1-16 |0 |Transferred | | | | -90| 90|
|
||||||
|5/1/16 |0 |Transferred | | | | 90| -90|
|
|5-1-16 |0 |Transferred | | | | 90| -90|
|
||||||
|5/2/16 |160 |Traded | | 0.3| | -90| |
|
|5-2-16 |160 |Traded | | 0.3| | -90| |
|
||||||
|6/1/16 |0 |Transferred | | -0.3| 0.3| | |
|
|6-1-16 |0 |Transferred | | -0.3| 0.3| | |
|
||||||
|7/1/16 |200 |Traded | | 0.7| | -90| |
|
|7-1-16 |200 |Traded | | 0.7| | -90| |
|
||||||
|8/1/16 |0 |Transferred | | 0.3| -0.3| | |
|
|8-1-16 |0 |Transferred | | 0.3| -0.3| | |
|
||||||
|9/1/16 |400 |Traded | | -0.5| | 200| |
|
|9-1-16 |400 |Traded | | -0.5| | 200| |
|
||||||
|10/1/16|900 |Traded | | 1| | -200| |
|
|10-1-16|900 |Traded | | 1| | -200| |
|
||||||
|11/1/16|0 |Transferred | | -1.5| 1.5| | |
|
|11-1-16|0 |Transferred | | -1.5| 1.5| | |
|
||||||
|12/1/16|2000 |Traded* | | | -1.5| | 400|
|
|12-1-16|2000 |Traded* | | | -1.5| | 400|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -187,9 +187,9 @@ Until "spot" funds are spent to pay off the margin loans, it's simply an [unreco
|
||||||
##### Columns
|
##### Columns
|
||||||
|
|
||||||
* **txDate**: As a default, this parser expects a format of `MM-dd-YY` or `MM-dd-YYYY`.
|
* **txDate**: As a default, this parser expects a format of `MM-dd-YY` or `MM-dd-YYYY`.
|
||||||
The ISO 8601 date format (`YYYY-MM-dd` or `YY-MM-dd` both work) may be indicated by passing the `-i` flag.
|
The ISO 8601 date format (`YYYY-MM-dd` or `YY-MM-dd` both work) may be indicated by setting the environment variable `ISO_DATE` to `1` or `true`.
|
||||||
The hyphen, slash, or period delimiters (`-`, `/`, or `.`) may be indicated
|
The hyphen, slash, or period delimiters (`-`, `/`, or `.`) may be indicated
|
||||||
by passing the `-d` option followed by `h`, `s`, or `p`, respectively (hyphen, `-`, is default).
|
by setting `DATE_SEPARATOR` to `h`, `s`, or `p`, respectively (hyphen, `-`, is default).
|
||||||
|
|
||||||
* **proceeds**: This is can be any **positive** number that will parse into a floating point 32-bit number,
|
* **proceeds**: This is can be any **positive** number that will parse into a floating point 32-bit number,
|
||||||
as long as the **decimal separator** is a **period**.
|
as long as the **decimal separator** is a **period**.
|
||||||
|
@ -201,7 +201,7 @@ but be sure not to include the ticker or symbol of the currency
|
||||||
* **memo**: This can be a string of characters of any length, though fewer than 20-30 characters is advised.
|
* **memo**: This can be a string of characters of any length, though fewer than 20-30 characters is advised.
|
||||||
Currently, **commas** in the memo field are **not** supported.
|
Currently, **commas** in the memo field are **not** supported.
|
||||||
|
|
||||||
* *value*: This is similar to **proceeds**, in that the **decimal separator** must be a **period**,
|
* *quantity*: This is similar to **proceeds**, in that the **decimal separator** must be a **period**,
|
||||||
and you *cannot* include the ticker or symbol of the currency in that field.
|
and you *cannot* include the ticker or symbol of the currency in that field.
|
||||||
It is different from **proceeds** in that this will be parsed into a 128-bit precision decimal floating point number,
|
It is different from **proceeds** in that this will be parsed into a 128-bit precision decimal floating point number,
|
||||||
and a negative value can be indicated via a preceding `-`.
|
and a negative value can be indicated via a preceding `-`.
|
||||||
|
@ -226,5 +226,5 @@ Anything aside from those six choices will fail to parse.
|
||||||
|
|
||||||
* *Transactions*: After the four header rows describing the accounts, the transaction rows follow.
|
* *Transactions*: After the four header rows describing the accounts, the transaction rows follow.
|
||||||
Each row is a separate transaction.
|
Each row is a separate transaction.
|
||||||
For each transaction, input the **date**, **proceeds**, **memo**, and **values** by which the account balances change.
|
For each transaction, input the **date**, **proceeds**, **memo**, and **quantity** by which the account balances change.
|
||||||
As mentioned elsewhere, a minimum of one and a maximum of two Accounts can be associated with a single transaction.
|
As mentioned elsewhere, a minimum of one and a maximum of two **Accounts** can be associated with a single transaction.
|
27
README.md
27
README.md
|
@ -4,8 +4,8 @@
|
||||||
|
|
||||||
###### (The package produces a binary and accompanying library)
|
###### (The package produces a binary and accompanying library)
|
||||||
|
|
||||||
This is a command-line tool that calculates income, expenses, realized gains, and realized losses
|
This is a command-line tool that calculates income, expenses, realized gains, realized losses,
|
||||||
(and holding period) from cryptocurrency activity and denominates the results in the user's home currency.
|
and holding period from cryptocurrency activity and denominates the results in the user's home currency.
|
||||||
The default home currency is USD, but any currency can be substituted.
|
The default home currency is USD, but any currency can be substituted.
|
||||||
This tool is probably most useful for filling out a tax return or making tax planning decisions.
|
This tool is probably most useful for filling out a tax return or making tax planning decisions.
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ containing the user's entire cryptocurrency transaction history, the software wi
|
||||||
|
|
||||||
* Two methods each of LIFO or FIFO (compatible w/ the concept of "specific identification")
|
* Two methods each of LIFO or FIFO (compatible w/ the concept of "specific identification")
|
||||||
|
|
||||||
* Ability to perform like-kind exchange treatment
|
* Ability to perform like-kind exchange treatment through a particular date
|
||||||
|
|
||||||
* Compatible with any (single) home currency
|
* Compatible with any (single) home currency
|
||||||
|
|
||||||
|
@ -63,16 +63,27 @@ This will build `./target/debug/cryptools` (or `./target/release/cryptools` for
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Run `./target/debug/cryptools` with no arguments (or with `--help`, or `-h`) to see usage.
|
Run `./target/debug/cryptools` with no arguments (or with `--help`, or `-h`) to see usage.
|
||||||
Alternatively, run `cargo run`, in which case command-line arguments for `cryptools` may be entered following `--`, e.g., `cargo run -- -h`.
|
Alternatively, run `cargo run`, in which case command-line options for `cryptools` may be entered following `--`, e.g., `cargo run -- -h`.
|
||||||
|
|
||||||
|
Running with no options/arguments will lead the user through a wizard.
|
||||||
|
To skip the wizard, there are three requirements:
|
||||||
|
* The [CSV input file](https://github.com/scoobybejesus/cryptools/blob/master/InputFile_CSV.md) is a required command line argument.
|
||||||
|
* The `-a` flag must be passed.
|
||||||
|
* The configuration settings you require are the same as default, or you set the appropriate environment variables, or you have a `.env` file.
|
||||||
|
|
||||||
Running with no arguments will lead the user through a wizard; or all required arguments can be passed as command-line flags/options/args.
|
|
||||||
See `/examples/` directory for further guidance,
|
See `/examples/` directory for further guidance,
|
||||||
or jump directly to the [examples.md](https://github.com/scoobybejesus/cryptools/blob/master/examples/examples.md) file.
|
or jump directly to the [examples.md](https://github.com/scoobybejesus/cryptools/blob/master/examples/examples.md) file.
|
||||||
|
|
||||||
|
###### Note: The import of your [CSV input file](https://github.com/scoobybejesus/cryptools/blob/master/InputFile_CSV.md) may fail or behave undesirably with the default configuration settings.
|
||||||
|
See [.env.example](https://github.com/scoobybejesus/cryptools/blob/master/examples/.env.example) for those defaults.
|
||||||
|
If you wish to skip the wizard but require changes to default settings, copy `.env.example` to `.env` and make your changes.
|
||||||
|
The `.env` file must be placed in the directory from which `cryptools` is run or a parent directory.
|
||||||
|
Alternatively, the respective environment variables may be set manually.
|
||||||
|
|
||||||
## Development state
|
## Development state
|
||||||
|
|
||||||
As of summer 2019, the code does not require additional features in order for it to serve the project's founder.
|
As of fall 2020, the code does not require additional features in order for it to serve the project's founder.
|
||||||
At the same time, there are plenty of bells and whistles, creature comforts, etc. that are desired and may be added.
|
At the same time, there are still bells and whistles, creature comforts, etc. that are desired and may be added.
|
||||||
Additionally, the code could use factoring or general re-working in several areas.
|
Additionally, the code could use factoring or general re-working in several areas.
|
||||||
|
|
||||||
The software has been tested on Mac, Linux, and FreeBSD.
|
The software has been tested on Mac, Linux, and FreeBSD.
|
||||||
|
@ -101,7 +112,7 @@ My first real progress was with Python, but I still didn't manage to fully devel
|
||||||
Luckily, I managed to stumble across a mentor who helped me write 80% of an MVP in strongly-typed Swift.
|
Luckily, I managed to stumble across a mentor who helped me write 80% of an MVP in strongly-typed Swift.
|
||||||
We coded our way into a corner, but I had learned enough to take the code apart and put it back together correctly and complete it.
|
We coded our way into a corner, but I had learned enough to take the code apart and put it back together correctly and complete it.
|
||||||
I really enjoyed Swift, but I wanted something even more performant (and cross-platform), and Rust seemed to fit the bill.
|
I really enjoyed Swift, but I wanted something even more performant (and cross-platform), and Rust seemed to fit the bill.
|
||||||
I rewrote the code in Rust (also with a bit of help from my mentor), and it has turned out to be a great choice.
|
I rewrote the code in Rust (also with a bit of help), and it has turned out to be a great choice.
|
||||||
|
|
||||||
## Legal
|
## Legal
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,8 @@ The sample input files and the resulting reports are in the `/examples/resources
|
||||||
|
|
||||||
(Note: new reports have been added since the write-up below was written.
|
(Note: new reports have been added since the write-up below was written.
|
||||||
Nevertheless, evaluating the reports should mostly be self-explanatory.
|
Nevertheless, evaluating the reports should mostly be self-explanatory.
|
||||||
Pass a -p flag from the command line to see the full list of available
|
Pass a -p flag from the command line to be presented a full list of available
|
||||||
reports - and select from them - once the import has taken place.)
|
reports to select from once the import has taken place.)
|
||||||
|
|
||||||
## 1. Using the wizard
|
## 1. Using the wizard
|
||||||
|
|
||||||
|
@ -16,14 +16,14 @@ reports - and select from them - once the import has taken place.)
|
||||||
##### We're going to pass in that file as a command-line argument (no flags are required).
|
##### We're going to pass in that file as a command-line argument (no flags are required).
|
||||||
Enter the following:
|
Enter the following:
|
||||||
|
|
||||||
##### `cargo run -- ./examples/resources/faker1__sample_input.csv`
|
##### `cargo run -- examples/resources/faker1__sample_input.csv`
|
||||||
|
|
||||||
(Substitute a Windows-style file path, if necessary.)
|
(Substitute a Windows-style file path, if necessary.)
|
||||||
|
|
||||||
Running the command above takes you through the wizard.
|
Running the command above takes you through the wizard.
|
||||||
|
|
||||||
(Note: You can simply run **`cargo run`** instead,
|
(Note: You can simply run **`cargo run`** instead,
|
||||||
in which case after answering yes to "Shall we proceed," you will have to enter the path of the input file.)
|
in which case after answering 'yes' to "Shall we proceed," you will have to enter the path of the input file.)
|
||||||
|
|
||||||
##### Type `<Enter>` to accept default responses to the first three prompts, which are:
|
##### Type `<Enter>` to accept default responses to the first three prompts, which are:
|
||||||
|
|
||||||
|
@ -33,44 +33,51 @@ in which case after answering yes to "Shall we proceed," you will have to enter
|
||||||
|
|
||||||
##### The final question asks if and where you'd like to save the reports.
|
##### The final question asks if and where you'd like to save the reports.
|
||||||
|
|
||||||
The default is the current directory, which is probably undesirable.
|
The default is the current directory, which may be undesirable.
|
||||||
Type `c` and `<Enter>` to change the directory.
|
Type `c` and `<Enter>` to change the directory.
|
||||||
Then tab-complete your way through `/Users/<your-username>/Documents`*, for example, and then `<Enter>`.
|
Then tab-complete your way through `/Users/<your-username>/Documents`, for example, and then `<Enter>`.
|
||||||
|
|
||||||
\* This would be different for Windows, of course.
|
\* This would be different for Windows, of course.
|
||||||
|
|
||||||
##### Now the program has ended, and you should have reports in the directory you provided.
|
##### Now the program has ended, and you should have reports in the directory you provided.
|
||||||
|
|
||||||
The reports should generally match those in the `examples/resources` directory.
|
The reports should generally match those in the `examples/resources` directory,
|
||||||
(Additional reports are created too, but you can generally match the existing reports by title.)
|
but additional (newer) reports will be generated too.
|
||||||
|
|
||||||
|
|
||||||
## 2. Skipping the wizard
|
## 2. Skipping the wizard
|
||||||
|
|
||||||
Let's run the program again.
|
Enter the following:
|
||||||
This time around, we'll pass command-line parameters to skip the wizard.
|
|
||||||
|
|
||||||
##### Again, preview the input file `faker2__sample_input.csv`.
|
##### `cargo run -- -a examples/resources/faker1__sample_input.csv`
|
||||||
|
|
||||||
You'll see it's similar to the README example, except that there is a wider variety of transactions,
|
(Substitute a Windows-style file path, if necessary.)
|
||||||
|
|
||||||
|
This will have quickly and automatically exported all the reports into the current directory.
|
||||||
|
Go delete them before you forget (or feel free to take a look at them first).
|
||||||
|
|
||||||
|
## 3. Using an input file with a slash (`/`) as the date separator
|
||||||
|
|
||||||
|
##### Preview the input file `faker2__sample_input.csv`.
|
||||||
|
|
||||||
|
You'll see it's similar to the first example, though with a wider variety of transactions,
|
||||||
plus the memos are more descriptive.
|
plus the memos are more descriptive.
|
||||||
|
More importantly, the date column uses a different format `/` instead of `-`.
|
||||||
|
|
||||||
##### Run **`cargo run -- --help`** to see descriptions for the parameters we can use, or just enter:
|
Run:
|
||||||
|
|
||||||
##### `cargo run -- -ds -a -o ~/Documents ./examples/resources/faker2__sample_input.csv`
|
##### `DATE_SEPARATOR=s cargo run -- -a -o ~/Documents ./examples/resources/faker2__sample_input.csv`
|
||||||
|
|
||||||
\* Substitute `~/Documents` with your desired output directory.
|
\* Substitute `~/Documents` with your desired output directory.
|
||||||
Substitute a Windows-style file path, if necessary.
|
Substitute a Windows-style file path, if necessary.
|
||||||
|
|
||||||
##### Again, the program runs, and you should have reports in the location you provided.
|
It worked correctly, right?
|
||||||
|
Note that we set an enviroment variable so the program knew how to parse the date column correctly.
|
||||||
|
An easier way to do this would be to create a `.env` file and set it there.
|
||||||
|
This is described in the README (though there isn't much to it).
|
||||||
|
|
||||||
###### Try once more. This time, after `-a`, type `-p`, to be presented a "print menu" for choosing individual reports.
|
###### Try once more. This time, after `-a`, type `-p`, to be presented a "print menu" for choosing individual reports.
|
||||||
|
|
||||||
We were able to bypass the wizard because:
|
## To recap:
|
||||||
|
|
||||||
1. The required parameters were passed in.
|
|
||||||
2. Default values were used for parameters not passed in.
|
|
||||||
3. The `-a` flag was set which accepts all parameters without asking twice (i.e., skips the wizard).
|
|
||||||
|
|
||||||
The only "required" parameter is the input file.
|
The only "required" parameter is the input file.
|
||||||
All other parameters have default values.
|
All other parameters have default values.
|
||||||
|
@ -78,8 +85,8 @@ The default values may not be desirable for your use case, however.
|
||||||
For example, you may want FIFO instead of LIFO,
|
For example, you may want FIFO instead of LIFO,
|
||||||
or you may set your home currency to EUR instead of USD.
|
or you may set your home currency to EUR instead of USD.
|
||||||
Or maybe you may want to apply like-kind exchange treatment through a particular date.
|
Or maybe you may want to apply like-kind exchange treatment through a particular date.
|
||||||
These parameters can all be set via command line options.
|
These parameters can all be set via environment variables (or in a `.env` file).
|
||||||
See the `--help` screen for all the options.
|
See the `--help` screen for command line options and .env.example for information on environment variables.
|
||||||
|
|
||||||
As mentioned above, pass the -p flag to be presented with a list of available reports.
|
As mentioned above, pass the -p flag to be presented with a list of available reports.
|
||||||
|
|
||||||
|
|
|
@ -2,15 +2,15 @@ txDate,proceeds,memo,1,2,3,4,5
|
||||||
,,,Bank,Exchange,Wallet,Exchange,Simplewallet
|
,,,Bank,Exchange,Wallet,Exchange,Simplewallet
|
||||||
,,,USD,BTC,BTC,XMR,XMR
|
,,,USD,BTC,BTC,XMR,XMR
|
||||||
,,,non,non,non,non,non
|
,,,non,non,non,non,non
|
||||||
2/1/16,0,FIRST,-220,0.25,,,
|
2-1-16,0,FIRST,-220,0.25,,,
|
||||||
3/1/16,250,SECOND,,-0.25,,180,
|
3-1-16,250,SECOND,,-0.25,,180,
|
||||||
4/1/16,0,THIRD,,,,-90,90
|
4-1-16,0,THIRD,,,,-90,90
|
||||||
5/1/16,0,FOURTH,,,,90,-90
|
5-1-16,0,FOURTH,,,,90,-90
|
||||||
5/2/16,160,FIFTH,,0.3,,-90,
|
5-2-16,160,FIFTH,,0.3,,-90,
|
||||||
6/1/16,0,SIXTH,,-0.3,0.3,,
|
6-1-16,0,SIXTH,,-0.3,0.3,,
|
||||||
7/1/16,200,SEVENTH,,0.7,,-90,
|
7-1-16,200,SEVENTH,,0.7,,-90,
|
||||||
8/1/16,0,EIGHTH,,0.3,-0.3,,
|
8-1-16,0,EIGHTH,,0.3,-0.3,,
|
||||||
9/1/16,400,NINTH,,-0.5,,200,
|
9-1-16,400,NINTH,,-0.5,,200,
|
||||||
10/1/16,900,TENTH,,1,,-200,
|
10-1-16,900,TENTH,,1,,-200,
|
||||||
11/1/16,0,ELEVENTH,,-1.5,1.5,,
|
11-1-16,0,ELEVENTH,,-1.5,1.5,,
|
||||||
12/1/16,2000,TWELFTH,,,-1.5,,400
|
12-1-16,2000,TWELFTH,,,-1.5,,400
|
|
|
@ -16,7 +16,7 @@ use crate::crptls_lib::create_lots_mvmts;
|
||||||
use crate::crptls_lib::costing_method::InventoryCostingMethod;
|
use crate::crptls_lib::costing_method::InventoryCostingMethod;
|
||||||
|
|
||||||
|
|
||||||
/// `ImportProcessParameters` are determined from command-line args and/or wizard input from the user.
|
/// `ImportProcessParameters` are determined from command-line args, environment variables, and/or wizard input from the user.
|
||||||
/// They are the settings that allow the software to carry out the importing-from-csv of
|
/// They are the settings that allow the software to carry out the importing-from-csv of
|
||||||
/// `Account`s and `Transaction`s, creation of `Lot`s and `Movement`s, addition of cost basis and proceeds
|
/// `Account`s and `Transaction`s, creation of `Lot`s and `Movement`s, addition of cost basis and proceeds
|
||||||
/// to `Movement`s, and application of like-kind treatment, in a specific and automated fashion.
|
/// to `Movement`s, and application of like-kind treatment, in a specific and automated fashion.
|
||||||
|
@ -26,7 +26,7 @@ pub struct ImportProcessParameters {
|
||||||
pub home_currency: String,
|
pub home_currency: String,
|
||||||
pub costing_method: InventoryCostingMethod,
|
pub costing_method: InventoryCostingMethod,
|
||||||
pub lk_treatment_enabled: bool,
|
pub lk_treatment_enabled: bool,
|
||||||
/// NaiveDate either from "1-1-1" (default and not to be used) or the actual date chosen (or passed in via Cli option)
|
/// NaiveDate either from "1-1-1" (default and not to be used) or the actual date chosen (or passed in via env var)
|
||||||
pub lk_cutoff_date: NaiveDate,
|
pub lk_cutoff_date: NaiveDate,
|
||||||
pub lk_basis_date_preserved: bool,
|
pub lk_basis_date_preserved: bool,
|
||||||
pub should_export: bool,
|
pub should_export: bool,
|
||||||
|
@ -61,6 +61,7 @@ pub fn import_and_process_final(
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
println!(" Successfully imported csv file.");
|
println!(" Successfully imported csv file.");
|
||||||
|
println!("Processing the data...");
|
||||||
|
|
||||||
transactions_map = create_lots_mvmts::create_lots_and_movements(
|
transactions_map = create_lots_mvmts::create_lots_and_movements(
|
||||||
&settings,
|
&settings,
|
||||||
|
@ -71,7 +72,7 @@ pub fn import_and_process_final(
|
||||||
// &mut lot_map,
|
// &mut lot_map,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
println!(" Successfully created lots and movements.");
|
println!(" Created lots and movements.");
|
||||||
|
|
||||||
import_cost_proceeds_etc::add_cost_basis_to_movements(
|
import_cost_proceeds_etc::add_cost_basis_to_movements(
|
||||||
&settings,
|
&settings,
|
||||||
|
@ -81,7 +82,7 @@ pub fn import_and_process_final(
|
||||||
&transactions_map
|
&transactions_map
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
println!(" Successfully added cost basis to movements.");
|
println!(" Added cost basis to movements.");
|
||||||
|
|
||||||
import_cost_proceeds_etc::add_proceeds_to_movements(
|
import_cost_proceeds_etc::add_proceeds_to_movements(
|
||||||
&raw_account_map,
|
&raw_account_map,
|
||||||
|
@ -90,8 +91,7 @@ pub fn import_and_process_final(
|
||||||
&transactions_map
|
&transactions_map
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
println!(" Successfully added proceeds to movements.");
|
println!(" Added proceeds to movements.");
|
||||||
|
|
||||||
|
|
||||||
if settings.lk_treatment_enabled {
|
if settings.lk_treatment_enabled {
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ pub(crate) fn import_from_csv(
|
||||||
transactions_map: &mut HashMap<u32, Transaction>,
|
transactions_map: &mut HashMap<u32, Transaction>,
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
|
|
||||||
let file = File::open(import_file_path)?; println!("CSV ledger file opened successfully.\n");
|
let file = File::open(import_file_path)?; println!("\nCSV ledger file opened successfully.\n");
|
||||||
|
|
||||||
let mut rdr = csv::ReaderBuilder::new()
|
let mut rdr = csv::ReaderBuilder::new()
|
||||||
.has_headers(true)
|
.has_headers(true)
|
||||||
|
@ -240,7 +240,8 @@ fn import_transactions(
|
||||||
let tx_date = NaiveDate::parse_from_str(this_tx_date, &format_yy)
|
let tx_date = NaiveDate::parse_from_str(this_tx_date, &format_yy)
|
||||||
.unwrap_or_else(|_| NaiveDate::parse_from_str(this_tx_date, &format_yyyy)
|
.unwrap_or_else(|_| NaiveDate::parse_from_str(this_tx_date, &format_yyyy)
|
||||||
.expect("
|
.expect("
|
||||||
Failed to parse date in input file. Check date separator character (which is a hyphen unless modified via Cli option -d).\n")
|
Failed to parse date in input file. Check date the separator character, which is expected to be a hyphen \
|
||||||
|
unless otherwise set via environment variable or .env file. See `.env.example.`\n")
|
||||||
);
|
);
|
||||||
|
|
||||||
let transaction = Transaction {
|
let transaction = Transaction {
|
||||||
|
|
|
@ -95,11 +95,9 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
|
||||||
let args = Cli::from_args();
|
let args = Cli::from_args();
|
||||||
|
|
||||||
let cfg = setup::get_env()?;
|
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
"
|
"\
|
||||||
Hello,
|
Hello!
|
||||||
|
|
||||||
This software will import your csv file's ledger of cryptocurrency transactions.
|
This software will import your csv file's ledger of cryptocurrency transactions.
|
||||||
It will then process it by creating 'lots' and posting 'movements' to those lots.
|
It will then process it by creating 'lots' and posting 'movements' to those lots.
|
||||||
|
@ -111,6 +109,8 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||||
Note: The software is designed to import a full history. Gains and losses may be incorrect otherwise.
|
Note: The software is designed to import a full history. Gains and losses may be incorrect otherwise.
|
||||||
");
|
");
|
||||||
|
|
||||||
|
let cfg = setup::get_env()?;
|
||||||
|
|
||||||
let (input_file_path, settings) = setup::run_setup(args, cfg)?;
|
let (input_file_path, settings) = setup::run_setup(args, cfg)?;
|
||||||
|
|
||||||
let (
|
let (
|
||||||
|
|
40
src/setup.rs
40
src/setup.rs
|
@ -1,7 +1,6 @@
|
||||||
// Copyright (c) 2017-2019, scoobybejesus
|
// Copyright (c) 2017-2019, scoobybejesus
|
||||||
// Redistributions must include the license: https://github.com/scoobybejesus/cryptools/blob/master/LEGAL.txt
|
// Redistributions must include the license: https://github.com/scoobybejesus/cryptools/blob/master/LEGAL.txt
|
||||||
|
|
||||||
// use std::ffi::OsString;
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::process;
|
use std::process;
|
||||||
|
@ -20,13 +19,14 @@ use crate::wizard;
|
||||||
|
|
||||||
pub fn get_env() -> Result<super::Cfg, Box<dyn Error>> {
|
pub fn get_env() -> Result<super::Cfg, Box<dyn Error>> {
|
||||||
|
|
||||||
dotenv::dotenv().expect("Failed to read .env file");
|
match dotenv::dotenv() {
|
||||||
|
Ok(_path) => {println!("Setting environment variables from .env file.")},
|
||||||
|
Err(_e) => println!("Did not find .env file.")
|
||||||
|
}
|
||||||
|
|
||||||
let iso_date: bool = match env::var("ISO_DATE") {
|
let iso_date: bool = match env::var("ISO_DATE") {
|
||||||
Ok(val) => {
|
Ok(val) => {
|
||||||
let var_lower = val.to_lowercase();
|
if val == "1" || val.to_lowercase() == "true" {
|
||||||
let val_str = var_lower.as_str();
|
|
||||||
if val_str == "1" || val == "true" {
|
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
@ -36,23 +36,37 @@ pub fn get_env() -> Result<super::Cfg, Box<dyn Error>> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let date_separator: String = match env::var("DATE_SEPARATOR") {
|
let date_separator: String = match env::var("DATE_SEPARATOR") {
|
||||||
Ok(val) => val.to_lowercase(),
|
Ok(val) => {
|
||||||
Err(_e) => "h".to_string(),
|
println!(" Found DATE_SEPARATOR env var: {}", val);
|
||||||
|
val.to_lowercase()},
|
||||||
|
Err(_e) => {
|
||||||
|
println!(" Using default date separator (hyphen).");
|
||||||
|
"h".to_string()},
|
||||||
};
|
};
|
||||||
|
|
||||||
let home_currency = match env::var("HOME_CURRENCY") {
|
let home_currency = match env::var("HOME_CURRENCY") {
|
||||||
Ok(val) => val.to_uppercase(),
|
Ok(val) => {
|
||||||
Err(_e) => "USD".to_string(),
|
println!(" Found HOME_CURRENCY env var: {}", val);
|
||||||
|
val.to_uppercase()},
|
||||||
|
Err(_e) => {
|
||||||
|
println!(" Using default home currency (USD).");
|
||||||
|
"USD".to_string()},
|
||||||
};
|
};
|
||||||
|
|
||||||
let lk_cutoff_date = match env::var("LK_CUTOFF_DATE") {
|
let lk_cutoff_date = match env::var("LK_CUTOFF_DATE") {
|
||||||
Ok(val) => Some(val),
|
Ok(val) => {
|
||||||
|
println!(" Found LK_CUTOFF_DATE env var: {}", val);
|
||||||
|
Some(val)},
|
||||||
Err(_e) => None,
|
Err(_e) => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let inv_costing_method = match env::var("INV_COSTING_METHOD") {
|
let inv_costing_method = match env::var("INV_COSTING_METHOD") {
|
||||||
Ok(val) => val,
|
Ok(val) => {
|
||||||
Err(_e) => "1".to_string(),
|
println!(" Found INV_COSTING_METHOD env var: {}", val);
|
||||||
|
val},
|
||||||
|
Err(_e) => {
|
||||||
|
println!(" Using default inventory costing method (LIFO by lot creation date).");
|
||||||
|
"1".to_string()},
|
||||||
};
|
};
|
||||||
|
|
||||||
let cfg = super::Cfg {
|
let cfg = super::Cfg {
|
||||||
|
@ -106,7 +120,7 @@ pub (crate) fn run_setup(cmd_args: super::Cli, cfg: super::Cfg) -> Result<(PathB
|
||||||
let like_kind_cutoff_date = if like_kind_election {
|
let like_kind_cutoff_date = if like_kind_election {
|
||||||
NaiveDate::parse_from_str(&like_kind_cutoff_date_string, "%y-%m-%d")
|
NaiveDate::parse_from_str(&like_kind_cutoff_date_string, "%y-%m-%d")
|
||||||
.unwrap_or_else(|_| NaiveDate::parse_from_str(&like_kind_cutoff_date_string, "%Y-%m-%d")
|
.unwrap_or_else(|_| NaiveDate::parse_from_str(&like_kind_cutoff_date_string, "%Y-%m-%d")
|
||||||
.expect("Command line date (like-kind cutoff option) has an incorrect format. Program must abort."))
|
.expect("Environment variable for LK_CUTOFF_DATE has an incorrect format. Program must abort. See .env.example."))
|
||||||
} else { NaiveDate::parse_from_str(&"1-1-1", "%y-%m-%d").unwrap() };
|
} else { NaiveDate::parse_from_str(&"1-1-1", "%y-%m-%d").unwrap() };
|
||||||
|
|
||||||
let settings = ImportProcessParameters {
|
let settings = ImportProcessParameters {
|
||||||
|
|
Loading…
Reference in New Issue