diff --git a/.gitignore b/.gitignore index 0c45e123..063870dc 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ __pycache__ account_statements/* data/* export/* +withdrawals_deposits/* # Development folder dev/ diff --git a/src/book.py b/src/book.py index 26599aec..45a4778e 100644 --- a/src/book.py +++ b/src/book.py @@ -1107,6 +1107,31 @@ def get_price_from_csv(self) -> None: overwrite=True, ) + def resolve_deposits(self) -> bool: + """ Matches withdrawals and deposits + + Returns: + bool: Return True if everything went as expected. + """ + paths = self.get_file_paths(config.WD_MATCHING_PATH) + + if not paths: + log.warning( + "No matching files for withdrawals/deposits located in %s.", + config.WD_MATCHING_PATH, + ) + return False + + for file_path in paths: + #TODO match withdrawals/deposits + pass + + if not bool(self): + log.warning("Unable to import any data.") + return False + + return True + def read_file(self, file_path: Path) -> None: """Import transactions form an account statement. @@ -1137,20 +1162,20 @@ def read_file(self, file_path: Path) -> None: "Skipping file." ) - def get_account_statement_paths(self, statements_dir: Path) -> list[Path]: - """Return file paths of all account statements in `statements_dir`. + def get_file_paths(self, folder_dir: Path) -> list[Path]: + """Return file paths of all input files in `folder_dir`. + For example, this function can return all account statement file paths. Args: - statements_dir (str): Folder in which account statements - will be searched. + folder_dir (str): Folder in input files will be searched. Returns: - list[Path]: List of account statement file paths. + list[Path]: List of input file paths. """ file_paths: list[Path] = [] - if statements_dir.is_dir(): - for file_path in statements_dir.iterdir(): + if folder_dir.is_dir(): + for file_path in folder_dir.iterdir(): # Ignore .gitkeep and temporary excel files. filename = file_path.stem if filename == ".gitkeep" or filename.startswith("~$"): @@ -1165,7 +1190,7 @@ def read_files(self) -> bool: Returns: bool: Return True if everything went as expected. """ - paths = self.get_account_statement_paths(config.ACCOUNT_STATMENTS_PATH) + paths = self.get_file_paths(config.ACCOUNT_STATMENTS_PATH) if not paths: log.warning( diff --git a/src/config.py b/src/config.py index 5677f0e3..86a42826 100644 --- a/src/config.py +++ b/src/config.py @@ -59,4 +59,5 @@ def IS_LONG_TERM(buy: datetime, sell: datetime) -> bool: ACCOUNT_STATMENTS_PATH = Path(BASE_PATH, "account_statements") DATA_PATH = Path(BASE_PATH, "data") EXPORT_PATH = Path(BASE_PATH, "export") +WD_MATCHING_PATH = Path(BASE_PATH, "withdrawals_deposits") FIAT = FIAT_CLASS.name # Convert to string. diff --git a/src/main.py b/src/main.py index ce655eb1..1efc6afe 100644 --- a/src/main.py +++ b/src/main.py @@ -36,6 +36,12 @@ def main() -> None: log.warning("Stopping CoinTaxman.") return + # TODO Resolve withdrawals and deposits between exchanges (#4) + # 1) Find matching withdrawal and deposit or raise a warning + # 2) Withdraw deposits from one exchange with FIFO/LIFO principle + # to the other exchange + log.debug("Resolve withdrawals and deposits between exchanges...") + book.resolve_deposits() book.get_price_from_csv() taxman.evaluate_taxation() taxman.export_evaluation_as_csv() diff --git a/src/transaction.py b/src/transaction.py index 8e0140f7..ef3e06f9 100644 --- a/src/transaction.py +++ b/src/transaction.py @@ -35,6 +35,7 @@ class Operation: coin: str line: int file_path: Path + buy_platform: typing.Optional[str] = None def __post_init__(self): assert self.validate_types() diff --git a/withdrawals_deposits/.gitkeep b/withdrawals_deposits/.gitkeep new file mode 100644 index 00000000..e69de29b