From 55cba2df2d64aee94f4e6a2ee71a7e1fc27e2e4c Mon Sep 17 00:00:00 2001 From: Scott Green Date: Mon, 15 Feb 2021 13:00:04 +0000 Subject: [PATCH] Features/transaction notes (#65) Transaction notes feature branch An optional note can now be added per transaction, taken from the last column after the timestamp. This note shoud describe what the transaction is for, for example, for a deposit or withdrawal it could indicate which wallet the transfer is going to/from, to describe what the spend was for, or what the income was from. The transaction note will appear in the logging to help find any issues. The note will also be used as a description field in the income tax report to make tracking income sources easier. The new note field appears in the transaction records output file, this will be an empty field except for the following parsers: Electrum, HandCash, Qt Wallet, Trezor where the original transaction label/note is copied into the transaction record note. --- CHANGELOG.md | 8 ++++++++ bittytax/conv/out_record.py | 3 ++- bittytax/conv/output_csv.py | 5 +++-- bittytax/conv/output_excel.py | 15 +++++++++----- bittytax/conv/parsers/electrum.py | 12 +++++++---- bittytax/conv/parsers/handcash.py | 6 ++++-- bittytax/conv/parsers/qtwallet.py | 15 +++++++++----- bittytax/conv/parsers/trezor.py | 9 ++++++--- bittytax/export_records.py | 2 +- bittytax/import_records.py | 9 +++++++-- bittytax/record.py | 33 ++++++++++++++++++++++--------- bittytax/report.py | 29 ++++++++++++++++----------- bittytax/tax.py | 1 + bittytax/templates/income.html | 28 +++++++++++--------------- bittytax/transactions.py | 18 +++++++++++++++-- 15 files changed, 129 insertions(+), 64 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a45818f..78f5d26c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Change Log ## [Unreleased] +Important:- A new Note field has been added to the end of the transaction record format (column M), this is used to add a description to a transaction. It is recommended that you add the additional Note column to all your existing transaction records. ### Fixed - Accounting tool: "xlrd.biffh.XLRDError: Excel xlsx file; not supported" Exception. ([#36](https://github.com/BittyTax/BittyTax/issues/36)) - Coinbase parser: added support for Convert transactions ([#46](https://github.com/BittyTax/BittyTax/issues/46)) @@ -23,6 +24,9 @@ - Accounting tool: warning given if disposal detected between transfers. - Accounting tool: integrity check (audit balances against section 104 pools). - Accounting tool: skip integrity check (--skipint) option added. +- Accounting tool: new Note field added to transaction record format. +- Accounting tool: note field added to income report. +- Conversion tool: note field added to the Excel and CSV output. ### Changed - Conversion tool: UnknownAddressError exception changed to generic DataFilenameError. - Binance parser: use filename to determine if deposits or withdrawals. @@ -36,6 +40,10 @@ - Accounting tool: same day pooling debug now only shows the pooled transactions. - Accounting tool: section 104 debug also shows matched transactions. - Crypto.com parser: added "campaign_reward" transaction type. ([#64](https://github.com/BittyTax/BittyTax/issues/64)) +- Elecrum parser: Note field is mapped from 'label'. +- HandCash parser: Note field is mapped from 'note'. +- Qt Wallet parser: Note field is mapped from 'Label'. +- Trezor parser: Note field is mapped from 'Address Label'. ### Removed - Accounting tool: skip audit (-s or --skipaudit) option removed. - Accounting tool: updated transactions debug removed. diff --git a/bittytax/conv/out_record.py b/bittytax/conv/out_record.py index d87c985a..495f9d68 100644 --- a/bittytax/conv/out_record.py +++ b/bittytax/conv/out_record.py @@ -24,7 +24,7 @@ def __init__(self, t_type, timestamp, buy_quantity=None, buy_asset='', buy_value=None, sell_quantity=None, sell_asset='', sell_value=None, fee_quantity=None, fee_asset='', fee_value=None, - wallet=''): + wallet='', note=''): self.t_type = t_type self.buy_quantity = Decimal(buy_quantity) if buy_quantity is not None else None @@ -38,6 +38,7 @@ def __init__(self, t_type, timestamp, self.fee_value = Decimal(fee_value) if fee_value is not None else None self.wallet = wallet self.timestamp = timestamp + self.note = note @staticmethod def format_quantity(quantity): diff --git a/bittytax/conv/output_csv.py b/bittytax/conv/output_csv.py index a113b6a2..20ef089d 100644 --- a/bittytax/conv/output_csv.py +++ b/bittytax/conv/output_csv.py @@ -17,7 +17,7 @@ class OutputBase(object): 'Buy Quantity', 'Buy Asset', 'Buy Value', 'Sell Quantity', 'Sell Asset', 'Sell Value', 'Fee Quantity', 'Fee Asset', 'Fee Value', - 'Wallet', 'Timestamp'] + 'Wallet', 'Timestamp', 'Note'] RECAP_OUT_HEADER = ['Type', 'Date', 'InOrBuyAmount', 'InOrBuyCurrency', @@ -172,7 +172,8 @@ def _to_bittytax_csv(tr): '{0:f}'.format(tr.fee_value.normalize()) if tr.fee_value is not None \ else None, tr.wallet, - OutputCsv._format_timestamp(tr.timestamp)] + OutputCsv._format_timestamp(tr.timestamp), + tr.note] @staticmethod def _to_recap_csv(tr): diff --git a/bittytax/conv/output_excel.py b/bittytax/conv/output_excel.py index e59a7770..f13e4059 100644 --- a/bittytax/conv/output_excel.py +++ b/bittytax/conv/output_excel.py @@ -206,6 +206,7 @@ def add_row(self, data_row, row_num): self._xl_value(data_row.t_record.fee_value, row_num, 9) self._xl_wallet(data_row.t_record.wallet, row_num, 10) self._xl_timestamp(data_row.t_record.timestamp, row_num, 11) + self._xl_note(data_row.t_record.note, row_num, 12) if sys.version_info[0] < 3: in_row = [r.decode('utf8') for r in data_row.in_row] @@ -215,13 +216,13 @@ def add_row(self, data_row, row_num): # Add original data for col_num, col_data in enumerate(in_row): if data_row.failure and data_row.failure.col_num == col_num: - self.worksheet.write(row_num, 12 + col_num, col_data, - self.output.format_in_data_err) + self.worksheet.write(row_num, len(self.output.BITTYTAX_OUT_HEADER) + col_num, + col_data, self.output.format_in_data_err) else: - self.worksheet.write(row_num, 12 + col_num, col_data, - self.output.format_in_data) + self.worksheet.write(row_num, len(self.output.BITTYTAX_OUT_HEADER) + col_num, + col_data, self.output.format_in_data) - self._autofit_calc(12 + col_num, len(col_data)) + self._autofit_calc(len(self.output.BITTYTAX_OUT_HEADER) + col_num, len(col_data)) def _xl_type(self, t_type, row_num, col_num): if t_type in self.BUY_LIST: @@ -291,6 +292,10 @@ def _xl_timestamp(self, timestamp, row_num, col_num): self.output.format_timestamp) self._autofit_calc(col_num, len(self.output.DATE_FORMAT)) + def _xl_note(self, note, row_num, col_num): + self.worksheet.write_string(row_num, col_num, note) + self._autofit_calc(col_num, len(note) if note else self.MAX_COL_WIDTH) + def _autofit_calc(self, col_num, width): if width > self.MAX_COL_WIDTH: width = self.MAX_COL_WIDTH diff --git a/bittytax/conv/parsers/electrum.py b/bittytax/conv/parsers/electrum.py index be097953..350b9046 100644 --- a/bittytax/conv/parsers/electrum.py +++ b/bittytax/conv/parsers/electrum.py @@ -22,13 +22,15 @@ def parse_electrum2(data_row, _parser, _filename): data_row.timestamp, buy_quantity=Decimal(in_row[2]), buy_asset=config.args.cryptoasset, - wallet=WALLET) + wallet=WALLET, + note=in_row[1]) else: data_row.t_record = TransactionOutRecord(TransactionOutRecord.TYPE_WITHDRAWAL, data_row.timestamp, sell_quantity=abs(Decimal(in_row[2])), sell_asset=config.args.cryptoasset, - wallet=WALLET) + wallet=WALLET, + note=in_row[1]) def parse_electrum(data_row, _parser, _filename): in_row = data_row.in_row @@ -42,13 +44,15 @@ def parse_electrum(data_row, _parser, _filename): data_row.timestamp, buy_quantity=Decimal(in_row[3]), buy_asset=config.args.cryptoasset, - wallet=WALLET) + wallet=WALLET, + note=in_row[1]) else: data_row.t_record = TransactionOutRecord(TransactionOutRecord.TYPE_WITHDRAWAL, data_row.timestamp, sell_quantity=abs(Decimal(in_row[3])), sell_asset=config.args.cryptoasset, - wallet=WALLET) + wallet=WALLET, + note=in_row[1]) DataParser(DataParser.TYPE_WALLET, "Electrum", diff --git a/bittytax/conv/parsers/handcash.py b/bittytax/conv/parsers/handcash.py index 229e3b31..4088f867 100644 --- a/bittytax/conv/parsers/handcash.py +++ b/bittytax/conv/parsers/handcash.py @@ -25,7 +25,8 @@ def parse_handcash(data_row, parser, _filename): data_row.timestamp, buy_quantity=Decimal(in_row[5]) / 10 ** 8, buy_asset="BSV", - wallet=WALLET) + wallet=WALLET, + note=in_row[3]) elif in_row[0] == "send": if participants[0]["type"] == "user": t_type = TransactionOutRecord.TYPE_GIFT_SENT @@ -38,7 +39,8 @@ def parse_handcash(data_row, parser, _filename): sell_asset="BSV", fee_quantity=Decimal(in_row[4]) / 10 ** 8, fee_asset="BSV", - wallet=WALLET) + wallet=WALLET, + note=in_row[3]) else: raise UnexpectedTypeError(0, parser.in_header[0], in_row[0]) diff --git a/bittytax/conv/parsers/qtwallet.py b/bittytax/conv/parsers/qtwallet.py index 55ab8317..d6e8b9f2 100644 --- a/bittytax/conv/parsers/qtwallet.py +++ b/bittytax/conv/parsers/qtwallet.py @@ -41,19 +41,22 @@ def parse_qt_wallet(data_row, parser, _filename): data_row.timestamp, buy_quantity=amount, buy_asset=symbol, - wallet=WALLET) + wallet=WALLET, + note=in_row[3]) elif in_row[2] == "Sent to": data_row.t_record = TransactionOutRecord(TransactionOutRecord.TYPE_WITHDRAWAL, data_row.timestamp, sell_quantity=amount, sell_asset=symbol, - wallet=WALLET) + wallet=WALLET, + note=in_row[3]) elif in_row[2] == "Mined": data_row.t_record = TransactionOutRecord(TransactionOutRecord.TYPE_MINING, data_row.timestamp, buy_quantity=amount, buy_asset=symbol, - wallet=WALLET) + wallet=WALLET, + note=in_row[3]) elif in_row[2] == "Payment to yourself": data_row.t_record = TransactionOutRecord(TransactionOutRecord.TYPE_WITHDRAWAL, data_row.timestamp, @@ -61,13 +64,15 @@ def parse_qt_wallet(data_row, parser, _filename): sell_asset=symbol, fee_quantity=amount, fee_asset=symbol, - wallet=WALLET) + wallet=WALLET, + note=in_row[3]) elif in_row[2] == "Name operation": data_row.t_record = TransactionOutRecord(TransactionOutRecord.TYPE_SPEND, data_row.timestamp, sell_quantity=amount, sell_asset=symbol, - wallet=WALLET) + wallet=WALLET, + note=in_row[3]) else: raise UnexpectedTypeError(2, parser.in_header[2], in_row[2]) diff --git a/bittytax/conv/parsers/trezor.py b/bittytax/conv/parsers/trezor.py index e63ff2ef..d63ee660 100644 --- a/bittytax/conv/parsers/trezor.py +++ b/bittytax/conv/parsers/trezor.py @@ -32,7 +32,8 @@ def parse_trezor(data_row, parser, filename): buy_asset=symbol, fee_quantity=Decimal(in_row[7])-Decimal(in_row[6]), fee_asset=symbol, - wallet=WALLET) + wallet=WALLET, + note=in_row[4]) elif in_row[5] == "OUT": data_row.t_record = TransactionOutRecord(TransactionOutRecord.TYPE_WITHDRAWAL, data_row.timestamp, @@ -41,7 +42,8 @@ def parse_trezor(data_row, parser, filename): fee_quantity=abs(Decimal(in_row[7])) -Decimal(in_row[6]), fee_asset=symbol, - wallet=WALLET) + wallet=WALLET, + note=in_row[4]) elif in_row[5] == "SELF": data_row.t_record = TransactionOutRecord(TransactionOutRecord.TYPE_WITHDRAWAL, data_row.timestamp, @@ -49,7 +51,8 @@ def parse_trezor(data_row, parser, filename): sell_asset=symbol, fee_quantity=abs(Decimal(in_row[7])), fee_asset=symbol, - wallet=WALLET) + wallet=WALLET, + note=in_row[4]) else: raise UnexpectedTypeError(5, parser.in_header[5], in_row[5]) diff --git a/bittytax/export_records.py b/bittytax/export_records.py index ac2e6dfd..ba754e0d 100644 --- a/bittytax/export_records.py +++ b/bittytax/export_records.py @@ -14,7 +14,7 @@ class ExportRecords: 'Buy Quantity', 'Buy Asset', 'Buy Value', 'Sell Quantity', 'Sell Asset', 'Sell Value', 'Fee Quantity', 'Fee Asset', 'Fee Value', - 'Wallet', 'Timestamp'] + 'Wallet', 'Timestamp', 'Note'] def __init__(self, transaction_records): self.transaction_records = transaction_records diff --git a/bittytax/import_records.py b/bittytax/import_records.py index df21d30b..f82c672d 100644 --- a/bittytax/import_records.py +++ b/bittytax/import_records.py @@ -145,7 +145,7 @@ class TransactionRow(object): 'Buy Quantity', 'Buy Asset', 'Buy Value', 'Sell Quantity', 'Sell Asset', 'Sell Value', 'Fee Quantity', 'Fee Asset', 'Fee Value', - 'Wallet', 'Timestamp'] + 'Wallet', 'Timestamp', 'Note'] BUY_TYPES = (TransactionRecord.TYPE_DEPOSIT, TransactionRecord.TYPE_MINING, @@ -207,8 +207,13 @@ def parse(self): # A fee spend is normally a disposal unless it's part of a transfer fee.disposal = False + if len(self.row) == len(self.HEADER): + note = self.row[12] + else: + note = '' + self.t_record = TransactionRecord(t_type, buy, sell, fee, self.row[10], - self.parse_timestamp(self.row[11])) + self.parse_timestamp(self.row[11]), note) @staticmethod def parse_timestamp(timestamp_str): diff --git a/bittytax/record.py b/bittytax/record.py index 14247288..2b2ce6ce 100644 --- a/bittytax/record.py +++ b/bittytax/record.py @@ -34,7 +34,7 @@ class TransactionRecord(object): cnt = 0 - def __init__(self, t_type, buy, sell, fee, wallet, timestamp): + def __init__(self, t_type, buy, sell, fee, wallet, timestamp, note): self.tid = None self.t_type = t_type self.buy = buy @@ -42,19 +42,23 @@ def __init__(self, t_type, buy, sell, fee, wallet, timestamp): self.fee = fee self.wallet = wallet self.timestamp = timestamp + self.note = note if self.buy: self.buy.t_record = self self.buy.timestamp = self.timestamp.astimezone(config.TZ_LOCAL) self.buy.wallet = self.wallet + self.buy.note = self.note if self.sell: self.sell.t_record = self self.sell.timestamp = self.timestamp.astimezone(config.TZ_LOCAL) self.sell.wallet = self.wallet + self.sell.note = self.note if self.fee: self.fee.t_record = self self.fee.timestamp = self.timestamp.astimezone(config.TZ_LOCAL) self.fee.wallet = self.wallet + self.fee.note = self.note def set_tid(self): if self.tid is None: @@ -87,12 +91,17 @@ def _format_value(value): config.CCY) return '' + @staticmethod + def _format_note(note): + if note: + return "'%s' " % note + return '' + @staticmethod def _format_timestamp(timestamp): if timestamp.microsecond: return timestamp.strftime('%Y-%m-%dT%H:%M:%S.%f %Z') - else: - return timestamp.strftime('%Y-%m-%dT%H:%M:%S %Z') + return timestamp.strftime('%Y-%m-%dT%H:%M:%S %Z') @staticmethod def _format_decimal(decimal): @@ -111,7 +120,7 @@ def __lt__(self, other): def __str__(self): if self.buy and self.sell: - return "%s %s %s%s <- %s %s%s%s '%s' %s [TID:%s]" % ( + return "%s %s %s%s <- %s %s%s%s '%s' %s %s[TID:%s]" % ( self.t_type, self._format_quantity(self.buy.quantity), self.buy.asset, @@ -122,9 +131,10 @@ def __str__(self): self._format_fee(), self.wallet, self._format_timestamp(self.timestamp), + self._format_note(self.note), self.tid[0]) elif self.buy: - return "%s %s %s%s%s '%s' %s [TID:%s]" % ( + return "%s %s %s%s%s '%s' %s %s[TID:%s]" % ( self.t_type, self._format_quantity(self.buy.quantity), self.buy.asset, @@ -132,9 +142,10 @@ def __str__(self): self._format_fee(), self.wallet, self._format_timestamp(self.timestamp), + self._format_note(self.note), self.tid[0]) elif self.sell: - return "%s %s %s%s%s '%s' %s [TID:%s]" % ( + return "%s %s %s%s%s '%s' %s %s[TID:%s]" % ( self.t_type, self._format_quantity(self.sell.quantity), self.sell.asset, @@ -142,6 +153,7 @@ def __str__(self): self._format_fee(), self.wallet, self._format_timestamp(self.timestamp), + self._format_note(self.note), self.tid[0]) return '' @@ -159,7 +171,8 @@ def to_csv(self): self.fee.asset if self.fee else '', self._format_decimal(self.fee.proceeds) if self.fee else '', self.wallet, - self._format_timestamp(self.timestamp)] + self._format_timestamp(self.timestamp), + self.note] elif self.buy: return [self.t_type, self._format_decimal(self.buy.quantity), @@ -172,7 +185,8 @@ def to_csv(self): self.fee.asset if self.fee else '', self._format_decimal(self.fee.proceeds) if self.fee else '', self.wallet, - self._format_timestamp(self.timestamp)] + self._format_timestamp(self.timestamp), + self.note] elif self.sell: return [self.t_type, '', @@ -185,6 +199,7 @@ def to_csv(self): self.fee.asset if self.fee else '', self._format_decimal(self.fee.proceeds) if self.fee else '', self.wallet, - self._format_timestamp(self.timestamp)] + self._format_timestamp(self.timestamp), + self.note] return [] diff --git a/bittytax/report.py b/bittytax/report.py index d3408939..dab952f7 100644 --- a/bittytax/report.py +++ b/bittytax/report.py @@ -270,13 +270,15 @@ def income(self, tax_year): income = self.tax_report[tax_year]['Income'] print("\n%sIncome\n" % Fore.CYAN) - header = "%s %-10s %-28s %-25s %13s %13s" % ('Asset'.ljust(self.MAX_SYMBOL_LEN), - 'Date', - 'Income Type', - 'Quantity', - 'Amount', - 'Fees') + header = "%s %-10s %-10s %-40s %-25s %13s %13s" % ('Asset'.ljust(self.MAX_SYMBOL_LEN), + 'Date', + 'Type', + 'Description', + 'Quantity', + 'Amount', + 'Fees') print("%s%s" % (Fore.YELLOW, header)) + for asset in sorted(income.assets): events = quantity = amount = fees = 0 for te in income.assets[asset]: @@ -284,48 +286,53 @@ def income(self, tax_year): quantity += te.quantity amount += te.amount fees += te.fees - print("%s%s %-10s %-28s %-25s %13s %13s" % ( + print("%s%s %-10s %-10s %-40s %-25s %13s %13s" % ( Fore.WHITE, te.asset.ljust(self.MAX_SYMBOL_LEN), self.format_date(te.date), te.type, + te.note, self.format_quantity(te.quantity), self.format_value(te.amount), self.format_value(te.fees))) if events > 1: - print("%s%s %-10s %-28s %-25s %13s %13s\n" % ( + print("%s%s %-10s %-10s %-40s %-25s %13s %13s\n" % ( Fore.YELLOW, 'Total'.ljust(self.MAX_SYMBOL_LEN), '', '', + '', self.format_quantity(quantity), self.format_value(amount), self.format_value(fees))) - print("%s%s %-28s %-25s %13s %13s" % ( + print("%s%s %-10s %-40s %-25s %13s %13s" % ( Fore.YELLOW, 'Income Type'.ljust(self.MAX_SYMBOL_LEN + 11), '', '', + '', 'Amount', 'Fees')) for i_type in sorted(income.type_totals): - print("%s%s %-28s %-25s %13s %13s" % ( + print("%s%s %-10s %-40s %-25s %13s %13s" % ( Fore.WHITE, i_type.ljust(self.MAX_SYMBOL_LEN + 11), '', '', + '', self.format_value(income.type_totals[i_type]['amount']), self.format_value(income.type_totals[i_type]['fees']))) print("%s%s" % (Fore.YELLOW, '_' * len(header))) - print("%s%s %-28s %-25s %13s %13s%s" % ( + print("%s%s %-10s %-40s %-25s %13s %13s%s" % ( Fore.YELLOW+Style.BRIGHT, 'Total'.ljust(self.MAX_SYMBOL_LEN + 11), '', '', + '', self.format_value(income.totals['amount']), self.format_value(income.totals['fees']), Style.NORMAL)) diff --git a/bittytax/tax.py b/bittytax/tax.py index def968d7..41a33091 100644 --- a/bittytax/tax.py +++ b/bittytax/tax.py @@ -358,6 +358,7 @@ def __init__(self, b): self.type = b.t_type self.quantity = b.quantity self.amount = b.cost.quantize(PRECISION) + self.note = b.note if b.fee_value: self.fees = b.fee_value.quantize(PRECISION) else: diff --git a/bittytax/templates/income.html b/bittytax/templates/income.html index c2f0c9c3..53b6a542 100644 --- a/bittytax/templates/income.html +++ b/bittytax/templates/income.html @@ -6,27 +6,25 @@

Income

Asset Date - Income Type + Type + Description Quantity Amount Fees - - {% for te in income.assets[asset] %} {% set asset_totals.events = asset_totals.events + 1 %} {{te.asset}} {{te.date|datefilter}} - {{te.type}} + {{te.type}} + {{te.note|nowrapfilter}} {{te.quantity|quantityfilter}} {% set asset_totals.quantity = asset_totals.quantity + te.quantity %} {{te.amount|valuefilter}} {% set asset_totals.amount = asset_totals.amount + te.amount %} {{te.fees|valuefilter}} {% set asset_totals.fees = asset_totals.fees + te.fees %} - - {% endfor %} {% if asset_totals.events > 1 %} @@ -34,11 +32,10 @@

Income

Total + {{asset_totals.quantity|quantityfilter}} {{asset_totals.amount|valuefilter}} {{asset_totals.fees|valuefilter}} - - {% endif %} @@ -48,23 +45,21 @@

Income

Income Type - + + Amount Fees - - {% for i_type in income.type_totals|sort %} {{i_type}} - + + {{income.type_totals[i_type]['amount']|valuefilter}} {{income.type_totals[i_type]['fees']|valuefilter}} - - {% endfor %} @@ -72,11 +67,10 @@

Income

Total - + + {{income.totals['amount']|valuefilter}} {{income.totals['fees']|valuefilter}} - - diff --git a/bittytax/transactions.py b/bittytax/transactions.py index 4b70dc77..c3e655d4 100644 --- a/bittytax/transactions.py +++ b/bittytax/transactions.py @@ -167,6 +167,7 @@ def __init__(self, t_type, asset, quantity): self.fee_fixed = True self.wallet = None self.timestamp = None + self.note = None self.matched = False self.pooled = [] @@ -181,6 +182,11 @@ def _format_quantity(self): return '' return '{:0,f}'.format(self.quantity.normalize()) + def _format_note(self): + if self.note: + return "'%s' " % self.note + return '' + def _format_pooled(self, bold=False): if self.pooled: return " %s[%s]%s" % ( @@ -276,6 +282,9 @@ def __iadd__(self, other): if other.fee_fixed != self.fee_fixed: self.fee_fixed = False + if other.note != self.note: + self.note = "" + self.pooled.append(other) return self @@ -308,7 +317,7 @@ def _format_cost(self): return '' def __str__(self, pooled_bold=False, quantity_bold=False): - return "%s%s %s%s %s %s%s%s%s '%s' %s [TID:%s]%s" % ( + return "%s%s %s%s %s %s%s%s%s '%s' %s %s[TID:%s]%s" % ( type(self).__name__.upper(), '*' if not self.acquisition else '', self.t_type, @@ -320,6 +329,7 @@ def __str__(self, pooled_bold=False, quantity_bold=False): self._format_fee(), self.wallet, self._format_timestamp(), + self._format_note(), self._format_tid(), self._format_pooled(pooled_bold)) @@ -371,6 +381,9 @@ def __iadd__(self, other): if other.fee_fixed != self.fee_fixed: self.fee_fixed = False + if other.note != self.note: + self.note = "" + self.pooled.append(other) return self @@ -403,7 +416,7 @@ def _format_proceeds(self): return '' def __str__(self, pooled_bold=False, quantity_bold=False): - return "%s%s %s%s %s %s%s%s%s '%s' %s [TID:%s]%s" % ( + return "%s%s %s%s %s %s%s%s%s '%s' %s %s[TID:%s]%s" % ( type(self).__name__.upper(), '*' if not self.disposal else '', self.t_type, @@ -415,5 +428,6 @@ def __str__(self, pooled_bold=False, quantity_bold=False): self._format_fee(), self.wallet, self._format_timestamp(), + self._format_note(), self._format_tid(), self._format_pooled(pooled_bold))