From 7156529ceb23356abe77da248cb6d8d7189d81fa 2019-10-15 19:44:53 From: Brett Smith Date: 2019-10-15 19:44:53 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. --- diff --git a/import2ledger/importers/nbpy2017.py b/import2ledger/importers/nbpy2017.py index f861d2f7db20af8a53a6f9ffbcb96a2b37205067..75ec2124be8e638ff54772ce76fc130d700e8c94 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 11a6e18690bd74c65d78a63fc6a9406a02b4346e..9dce543dc23458634fb5594c1029cccdd9eda4ca 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 2ec351e33677f8b63f8f30b59f900a88cedff80e..1301b8c57ee0599672a3ebb7aef77cfa42d48c3f 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]