forked from EvergreenCrypto/docker-finance
container: lib_taxes: add support for IRS Rev. Proc. 2024-28
- Creates per-wallet / per-account compliance for IRS Rev. Proc. 2024-28
* Obfuscated keymap now creates a unique indentifier per-wallet /
per-account where all trades, spends and income are now clearly
tied to their respective wallets / accounts.
- Removes support for anonymized ("universal pool") reports.
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
# docker-finance | modern accounting for the power-user
|
||||
#
|
||||
# Copyright (C) 2021-2024 Aaron Fiore (Founder, Evergreen Crypto LLC)
|
||||
# Copyright (C) 2021-2025 Aaron Fiore (Founder, Evergreen Crypto LLC)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -1067,24 +1067,12 @@ function lib_taxes::__taxes_write()
|
||||
lib_taxes::__reports_obfs
|
||||
lib_utils::catch $?
|
||||
|
||||
#
|
||||
# Anonymized
|
||||
#
|
||||
|
||||
lib_utils::print_custom " \e[32m├─\e[34m\e[1;3m ${_arg_tag} (anonymized)\e[0m\n"
|
||||
|
||||
local _ext_anon="report_anon.csv"
|
||||
local _out_file="${_base_path}-${_ext_anon}"
|
||||
|
||||
lib_taxes::__reports_anon
|
||||
lib_utils::catch $?
|
||||
|
||||
#
|
||||
# Verify reports
|
||||
#
|
||||
|
||||
lib_utils::print_custom " \e[32m│\e[0m\n"
|
||||
lib_utils::print_custom " \e[32m│\e[0m\t\e[37;2m ... Verifying $_arg_tag (full/obfuscated/anonymized) ...\e[0m\n"
|
||||
lib_utils::print_custom " \e[32m│\e[0m\t\e[37;2m ... Verifying $_arg_tag (full/obfuscated) ...\e[0m\n"
|
||||
lib_utils::print_custom " \e[32m│\e[0m\n"
|
||||
|
||||
local _full
|
||||
@@ -1093,12 +1081,9 @@ function lib_taxes::__taxes_write()
|
||||
local _obfs
|
||||
_obfs="$(wc -l ${_base_path}-${_ext_obfs})"
|
||||
|
||||
local _anon
|
||||
_anon="$(wc -l ${_base_path}-${_ext_anon})"
|
||||
|
||||
# TODO: more involved verification
|
||||
|
||||
if [[ "${_full% *}" != "${_obfs% *}" && "${_obfs% *}" != "${_anon% *}" ]]; then
|
||||
if [[ "${_full% *}" != "${_obfs% *}" ]]; then
|
||||
lib_utils::die_fatal "Report verification: line count mistmatch"
|
||||
fi
|
||||
fi
|
||||
@@ -1187,6 +1172,8 @@ function lib_taxes::__reports_patch()
|
||||
#
|
||||
# - Coinbase Pro was sunsetted in late 2022
|
||||
|
||||
# TODO: for 2025+, subaccount will be included before comma
|
||||
# (must add appropriate regex if patch must ever be applied to 2025+)
|
||||
local _coinbase_string="(coinbase,|coinbase-pro,)"
|
||||
grep -E "$_coinbase_string" "$_spends" &>/dev/null
|
||||
|
||||
@@ -1282,11 +1269,25 @@ function lib_taxes::__reports_obfs_gen()
|
||||
local _count
|
||||
_count=$(echo "$_raw_column" | wc -l)
|
||||
|
||||
local _sha="sha256sum"
|
||||
lib_utils::deps_check "$_sha"
|
||||
|
||||
local _obfs_column
|
||||
_obfs_column="$(shuf --random-source='/dev/urandom' -i 1-"${_count}" \
|
||||
| while read _line; do
|
||||
[ "$_line" -lt 10 ] && _num="0${_line}" || _num="${_line}"
|
||||
echo "$_num"
|
||||
_obfs_column="$(echo "$_raw_column" \
|
||||
| while read _account; do
|
||||
#
|
||||
# OBFS column key is a truncated SHA digest of complete profile along with complete account.
|
||||
#
|
||||
# NOTE:
|
||||
#
|
||||
# - static delimiter is used to avoid potential inconsistencies
|
||||
# (if ever given a custom delimiter)
|
||||
#
|
||||
# - complete profile is included as a means to provide a 'reasonable' salt
|
||||
# (since default account names and memos can be used across profiles or subprofiles)
|
||||
#
|
||||
echo -n "${global_parent_profile}/${global_child_profile}/${_account}" | "$_sha" | head -c${2:-10}
|
||||
echo
|
||||
done)"
|
||||
|
||||
readarray -t _raw <<<"$_raw_column"
|
||||
@@ -1309,18 +1310,14 @@ function lib_taxes::__reports_obfs_gen()
|
||||
|
||||
for(i = 1; i <= count; i++)
|
||||
{
|
||||
# HACK: makes the data (most likely the Memo) sed friendly,
|
||||
# if it has delimiter in string.
|
||||
sub(/:/, "_", r[i])
|
||||
|
||||
print tax_year "_" args_tag "-" column "_" o[i] OFS r[i]
|
||||
print o[i] OFS r[i]
|
||||
}
|
||||
}' FS=, OFS=, \
|
||||
| (
|
||||
sed -u 1q
|
||||
sort
|
||||
) \
|
||||
| sed 's:, :,:g' >"$_keymap_file"
|
||||
| sed 's|, |,|g' >"$_keymap_file"
|
||||
|
||||
# Generate a temp file of the given raw column
|
||||
local _tmp_file="${_tmp_dir}/${_styled_column}"
|
||||
@@ -1329,7 +1326,7 @@ function lib_taxes::__reports_obfs_gen()
|
||||
# Obfuscate given raw column with keymap data
|
||||
tail -n +2 "$_keymap_file" \
|
||||
| while read _line; do
|
||||
sed -i "s:${_line#*,}:${_line%,*}:g" "$_tmp_file"
|
||||
sed -i "s|${_line#*,}|${_line%,*}|g" "$_tmp_file"
|
||||
done
|
||||
done
|
||||
|
||||
@@ -1339,25 +1336,4 @@ function lib_taxes::__reports_obfs_gen()
|
||||
| xsv select "$_all_columns" -o "$_out_file"
|
||||
}
|
||||
|
||||
#
|
||||
# Reports (anonymized)
|
||||
#
|
||||
|
||||
function lib_taxes::__reports_anon()
|
||||
{
|
||||
case "$_arg_tag" in
|
||||
trade | trades)
|
||||
xsv select "Date,Action,Symbol,Volume,Currency,Total,FeeCurrency,Fee" \
|
||||
"$_in_file" -o "$_out_file"
|
||||
;;
|
||||
income | spend | spends)
|
||||
xsv select "Date,Action,Symbol,Volume,Currency,Total" \
|
||||
"$_in_file" -o "$_out_file"
|
||||
;;
|
||||
*)
|
||||
lib_utils::die_fatal "Unsupported type"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# vim: sw=2 sts=2 si ai et
|
||||
|
||||
Reference in New Issue
Block a user