From 7156529ceb23356abe77da248cb6d8d7189d81fa Mon Sep 17 00:00:00 2001 From: Brett Smith Date: Tue, 15 Oct 2019 15:41:47 -0400 Subject: [PATCH] nbpy2017: Report item rate names and final unit prices. This keeps more of the RBI calculation in the templates, where it belongs. Template logic has become more capable since this importer was first written, which makes this change practical. --- import2ledger/importers/nbpy2017.py | 41 +++++++++++++++++++---------- setup.py | 2 +- tests/data/imports.yml | 36 ++++++++++++++++--------- 3 files changed, 52 insertions(+), 27 deletions(-) diff --git a/import2ledger/importers/nbpy2017.py b/import2ledger/importers/nbpy2017.py index f861d2f..75ec212 100644 --- a/import2ledger/importers/nbpy2017.py +++ b/import2ledger/importers/nbpy2017.py @@ -1,6 +1,7 @@ import collections import decimal import functools +import re import bs4 from .. import strparse @@ -10,11 +11,8 @@ STATUS_PAID = 'Payment' STATUS_REFUNDED = 'Refund' class Invoice2017: - STANDARD_TICKET_RBI = decimal.Decimal('42.50') - DISCOUNT_TICKET_RBI = STANDARD_TICKET_RBI / 2 - STANDARD_SHIRT_RBI = decimal.Decimal('25.50') - DISCOUNT_SHIRT_RBI = STANDARD_SHIRT_RBI CURRENCY = 'USD' + ITEM_RE = re.compile(r'(?:^|\()(Ticket|T-Shirt) - ') @classmethod def _elem_stripped_string(cls, elem): @@ -54,8 +52,10 @@ class Invoice2017: 'invoice_date': self.invoice_date, 'invoice_id': self.invoice_id, 'payee': self.payee, + 'shirt_price': self.shirt_price, 'shirt_rate': self.shirt_rate, 'shirts_sold': self.shirts_sold, + 'ticket_price': self.ticket_price, 'ticket_rate': self.ticket_rate, 'tickets_sold': self.tickets_sold, } @@ -78,23 +78,36 @@ class Invoice2017: def _read_invoice_items(self, table, first_row_text, rows_text): self.amount = decimal.Decimal(0) self.tickets_sold = decimal.Decimal(0) - self.ticket_rate = self.STANDARD_TICKET_RBI + self.ticket_price = decimal.Decimal(0) + self.ticket_rate = '' self.shirts_sold = decimal.Decimal(0) - self.shirt_rate = self.STANDARD_SHIRT_RBI + self.shirt_price = decimal.Decimal(0) + self.shirt_rate = '' for description, qty, unit_price, total in rows_text: if qty is None: continue total = strparse.currency_decimal(total) self.amount += total - if description.startswith('Ticket - '): + match = self.ITEM_RE.search(description) + try: + item_type = match.group(1) + except AttributeError: + continue + qty = int(qty) + unit_price = strparse.currency_decimal(unit_price) + if item_type == 'Ticket': if total > 0: - self.tickets_sold += int(qty) - elif description.startswith('Early Bird ('): - self.ticket_rate = self.DISCOUNT_TICKET_RBI - elif description.startswith('T-Shirt - '): - self.shirts_sold += int(qty) - elif description.startswith('T-shirts complimentary '): - self.shirts_sold -= int(qty) + self.tickets_sold += qty + self.ticket_price += unit_price + self.ticket_rate = description + elif item_type == 'T-Shirt': + if description.startswith('T-shirts complimentary '): + self.shirts_sold -= qty + else: + if total > 0: + self.shirts_sold += qty + self.shirt_price += unit_price + self.shirt_rate = description def _read_invoice_activity(self, table, first_row_text, rows_text): self.actions = [{ diff --git a/setup.py b/setup.py index 11a6e18..9dce543 100755 --- a/setup.py +++ b/setup.py @@ -30,7 +30,7 @@ REQUIREMENTS['tests_require'] = [ setup( name='import2ledger', description="Import different sources of financial data to Ledger", - version='0.9.3', + version='0.10.0', author='Brett Smith', author_email='brettcsmith@brettcsmith.org', license='GNU AGPLv3+', diff --git a/tests/data/imports.yml b/tests/data/imports.yml index 2ec351e..1301b8c 100644 --- a/tests/data/imports.yml +++ b/tests/data/imports.yml @@ -180,9 +180,11 @@ date: !!python/object/apply:datetime.date [2017, 10, 19] amount: !!python/object/apply:decimal.Decimal ["80.00"] tickets_sold: !!python/object/apply:decimal.Decimal ["1"] - ticket_rate: !!python/object/apply:decimal.Decimal ["21.25"] + ticket_price: !!python/object/apply:decimal.Decimal ["80.00"] + ticket_rate: Early Bird (Ticket - Individual Supporter) shirts_sold: !!python/object/apply:decimal.Decimal ["1"] - shirt_rate: !!python/object/apply:decimal.Decimal ["25.50"] + shirt_price: !!python/object/apply:decimal.Decimal ["0"] + shirt_rate: "Complimentary for ticket holder (Supporter-level and above) (T-Shirt - Men's/Straight Cut Size L)" currency: USD status: Invoice invoice_id: "83" @@ -192,9 +194,11 @@ date: !!python/object/apply:datetime.date [2017, 10, 19] amount: !!python/object/apply:decimal.Decimal ["80.00"] tickets_sold: !!python/object/apply:decimal.Decimal ["1"] - ticket_rate: !!python/object/apply:decimal.Decimal ["21.25"] + ticket_price: !!python/object/apply:decimal.Decimal ["80.00"] + ticket_rate: Early Bird (Ticket - Individual Supporter) shirts_sold: !!python/object/apply:decimal.Decimal ["1"] - shirt_rate: !!python/object/apply:decimal.Decimal ["25.50"] + shirt_price: !!python/object/apply:decimal.Decimal ["0"] + shirt_rate: "Complimentary for ticket holder (Supporter-level and above) (T-Shirt - Men's/Straight Cut Size L)" currency: USD status: Payment invoice_id: "83" @@ -210,9 +214,11 @@ date: !!python/object/apply:datetime.date [2017, 12, 3] amount: !!python/object/apply:decimal.Decimal ["50.00"] tickets_sold: !!python/object/apply:decimal.Decimal ["1"] - ticket_rate: !!python/object/apply:decimal.Decimal ["42.50"] + ticket_price: !!python/object/apply:decimal.Decimal ["50.00"] + ticket_rate: Ticket - Unaffiliated Individual shirts_sold: !!python/object/apply:decimal.Decimal ["0"] - shirt_rate: !!python/object/apply:decimal.Decimal ["25.50"] + shirt_price: !!python/object/apply:decimal.Decimal ["0"] + shirt_rate: "" status: Invoice currency: USD invoice_date: !!python/object/apply:datetime.date [2017, 12, 3] @@ -222,9 +228,11 @@ date: !!python/object/apply:datetime.date [2017, 12, 3] amount: !!python/object/apply:decimal.Decimal ["50.00"] tickets_sold: !!python/object/apply:decimal.Decimal ["1"] - ticket_rate: !!python/object/apply:decimal.Decimal ["42.50"] + ticket_price: !!python/object/apply:decimal.Decimal ["50.00"] + ticket_rate: Ticket - Unaffiliated Individual shirts_sold: !!python/object/apply:decimal.Decimal ["0"] - shirt_rate: !!python/object/apply:decimal.Decimal ["25.50"] + shirt_price: !!python/object/apply:decimal.Decimal ["0"] + shirt_rate: "" status: Payment currency: USD invoice_date: !!python/object/apply:datetime.date [2017, 12, 3] @@ -240,9 +248,11 @@ date: !!python/object/apply:datetime.date [2017, 9, 5] amount: !!python/object/apply:decimal.Decimal ["60.00"] tickets_sold: !!python/object/apply:decimal.Decimal ["0"] - ticket_rate: !!python/object/apply:decimal.Decimal ["42.50"] + ticket_price: !!python/object/apply:decimal.Decimal ["0"] + ticket_rate: Ticket - Talk Proposer shirts_sold: !!python/object/apply:decimal.Decimal ["2"] - shirt_rate: !!python/object/apply:decimal.Decimal ["25.50"] + shirt_price: !!python/object/apply:decimal.Decimal ["30.00"] + shirt_rate: "T-Shirt - Men's/Straight Cut Size M" status: Invoice currency: USD invoice_date: !!python/object/apply:datetime.date [2017, 9, 5] @@ -252,9 +262,11 @@ date: !!python/object/apply:datetime.date [2017, 9, 5] amount: !!python/object/apply:decimal.Decimal ["60.00"] tickets_sold: !!python/object/apply:decimal.Decimal ["0"] - ticket_rate: !!python/object/apply:decimal.Decimal ["42.50"] + ticket_price: !!python/object/apply:decimal.Decimal ["0"] + ticket_rate: Ticket - Talk Proposer shirts_sold: !!python/object/apply:decimal.Decimal ["2"] - shirt_rate: !!python/object/apply:decimal.Decimal ["25.50"] + shirt_price: !!python/object/apply:decimal.Decimal ["30.00"] + shirt_rate: "T-Shirt - Men's/Straight Cut Size M" status: Payment currency: USD invoice_date: !!python/object/apply:datetime.date [2017, 9, 5]