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.
This commit is contained in:
Brett Smith 2019-10-15 15:41:47 -04:00
parent 1e381664f4
commit 7156529ceb
3 changed files with 52 additions and 27 deletions

View file

@ -1,6 +1,7 @@
import collections import collections
import decimal import decimal
import functools import functools
import re
import bs4 import bs4
from .. import strparse from .. import strparse
@ -10,11 +11,8 @@ STATUS_PAID = 'Payment'
STATUS_REFUNDED = 'Refund' STATUS_REFUNDED = 'Refund'
class Invoice2017: 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' CURRENCY = 'USD'
ITEM_RE = re.compile(r'(?:^|\()(Ticket|T-Shirt) - ')
@classmethod @classmethod
def _elem_stripped_string(cls, elem): def _elem_stripped_string(cls, elem):
@ -54,8 +52,10 @@ class Invoice2017:
'invoice_date': self.invoice_date, 'invoice_date': self.invoice_date,
'invoice_id': self.invoice_id, 'invoice_id': self.invoice_id,
'payee': self.payee, 'payee': self.payee,
'shirt_price': self.shirt_price,
'shirt_rate': self.shirt_rate, 'shirt_rate': self.shirt_rate,
'shirts_sold': self.shirts_sold, 'shirts_sold': self.shirts_sold,
'ticket_price': self.ticket_price,
'ticket_rate': self.ticket_rate, 'ticket_rate': self.ticket_rate,
'tickets_sold': self.tickets_sold, 'tickets_sold': self.tickets_sold,
} }
@ -78,23 +78,36 @@ class Invoice2017:
def _read_invoice_items(self, table, first_row_text, rows_text): def _read_invoice_items(self, table, first_row_text, rows_text):
self.amount = decimal.Decimal(0) self.amount = decimal.Decimal(0)
self.tickets_sold = 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.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: for description, qty, unit_price, total in rows_text:
if qty is None: if qty is None:
continue continue
total = strparse.currency_decimal(total) total = strparse.currency_decimal(total)
self.amount += 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: if total > 0:
self.tickets_sold += int(qty) self.tickets_sold += qty
elif description.startswith('Early Bird ('): self.ticket_price += unit_price
self.ticket_rate = self.DISCOUNT_TICKET_RBI self.ticket_rate = description
elif description.startswith('T-Shirt - '): elif item_type == 'T-Shirt':
self.shirts_sold += int(qty) if description.startswith('T-shirts complimentary '):
elif description.startswith('T-shirts complimentary '): self.shirts_sold -= qty
self.shirts_sold -= int(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): def _read_invoice_activity(self, table, first_row_text, rows_text):
self.actions = [{ self.actions = [{

View file

@ -30,7 +30,7 @@ REQUIREMENTS['tests_require'] = [
setup( setup(
name='import2ledger', name='import2ledger',
description="Import different sources of financial data to Ledger", description="Import different sources of financial data to Ledger",
version='0.9.3', version='0.10.0',
author='Brett Smith', author='Brett Smith',
author_email='brettcsmith@brettcsmith.org', author_email='brettcsmith@brettcsmith.org',
license='GNU AGPLv3+', license='GNU AGPLv3+',

View file

@ -180,9 +180,11 @@
date: !!python/object/apply:datetime.date [2017, 10, 19] date: !!python/object/apply:datetime.date [2017, 10, 19]
amount: !!python/object/apply:decimal.Decimal ["80.00"] amount: !!python/object/apply:decimal.Decimal ["80.00"]
tickets_sold: !!python/object/apply:decimal.Decimal ["1"] 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"] 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 currency: USD
status: Invoice status: Invoice
invoice_id: "83" invoice_id: "83"
@ -192,9 +194,11 @@
date: !!python/object/apply:datetime.date [2017, 10, 19] date: !!python/object/apply:datetime.date [2017, 10, 19]
amount: !!python/object/apply:decimal.Decimal ["80.00"] amount: !!python/object/apply:decimal.Decimal ["80.00"]
tickets_sold: !!python/object/apply:decimal.Decimal ["1"] 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"] 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 currency: USD
status: Payment status: Payment
invoice_id: "83" invoice_id: "83"
@ -210,9 +214,11 @@
date: !!python/object/apply:datetime.date [2017, 12, 3] date: !!python/object/apply:datetime.date [2017, 12, 3]
amount: !!python/object/apply:decimal.Decimal ["50.00"] amount: !!python/object/apply:decimal.Decimal ["50.00"]
tickets_sold: !!python/object/apply:decimal.Decimal ["1"] 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"] 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 status: Invoice
currency: USD currency: USD
invoice_date: !!python/object/apply:datetime.date [2017, 12, 3] invoice_date: !!python/object/apply:datetime.date [2017, 12, 3]
@ -222,9 +228,11 @@
date: !!python/object/apply:datetime.date [2017, 12, 3] date: !!python/object/apply:datetime.date [2017, 12, 3]
amount: !!python/object/apply:decimal.Decimal ["50.00"] amount: !!python/object/apply:decimal.Decimal ["50.00"]
tickets_sold: !!python/object/apply:decimal.Decimal ["1"] 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"] 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 status: Payment
currency: USD currency: USD
invoice_date: !!python/object/apply:datetime.date [2017, 12, 3] invoice_date: !!python/object/apply:datetime.date [2017, 12, 3]
@ -240,9 +248,11 @@
date: !!python/object/apply:datetime.date [2017, 9, 5] date: !!python/object/apply:datetime.date [2017, 9, 5]
amount: !!python/object/apply:decimal.Decimal ["60.00"] amount: !!python/object/apply:decimal.Decimal ["60.00"]
tickets_sold: !!python/object/apply:decimal.Decimal ["0"] 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"] 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 status: Invoice
currency: USD currency: USD
invoice_date: !!python/object/apply:datetime.date [2017, 9, 5] invoice_date: !!python/object/apply:datetime.date [2017, 9, 5]
@ -252,9 +262,11 @@
date: !!python/object/apply:datetime.date [2017, 9, 5] date: !!python/object/apply:datetime.date [2017, 9, 5]
amount: !!python/object/apply:decimal.Decimal ["60.00"] amount: !!python/object/apply:decimal.Decimal ["60.00"]
tickets_sold: !!python/object/apply:decimal.Decimal ["0"] 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"] 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 status: Payment
currency: USD currency: USD
invoice_date: !!python/object/apply:datetime.date [2017, 9, 5] invoice_date: !!python/object/apply:datetime.date [2017, 9, 5]