Changeset - 668906b944c1
[Not reviewed]
0 2 0
Brett Smith - 6 years ago 2017-12-18 15:47:04
brettcsmith@brettcsmith.org
importers.nbpy2017: Yield entries for the original invoice.

This lets us write up a cleaner separation between the original act of
invoicing and the Stripe payment.
2 files changed with 72 insertions and 9 deletions:
0 comments (0 inline, 0 general)
import2ledger/importers/nbpy2017.py
Show inline comments
...
 
@@ -4,6 +4,10 @@ import functools
 
import bs4
 
from .. import util
 

	
 
STATUS_INVOICED = 'Invoice'
 
STATUS_PAID = 'Payment'
 
STATUS_REFUNDED = 'Refund'
 

	
 
class Invoice2017:
 
    STANDARD_TICKET_RATE = decimal.Decimal('42.50')
 
    DISCOUNT_TICKET_RATE = STANDARD_TICKET_RATE / 2
...
 
@@ -46,6 +50,7 @@ class Invoice2017:
 
        self.base_data = {
 
            'amount': self.amount,
 
            'currency': self.CURRENCY,
 
            'invoice_date': self.invoice_date,
 
            'invoice_id': self.invoice_id,
 
            'payee': self.payee,
 
            'shirt_rate': self.shirt_rate,
...
 
@@ -62,6 +67,9 @@ class Invoice2017:
 

	
 
    def _read_invoice_header(self, table, first_row_text, rows_text):
 
        self.invoice_id = first_row_text[1]
 
        for key, value in rows_text:
 
            if key == 'Issue date':
 
                self.invoice_date = self._strpdate(value)
 
        recipient_h = table.find('th', text='Recipient')
 
        recipient_cell = recipient_h.find_next_sibling('td')
 
        self.payee = next(recipient_cell.stripped_strings)
...
 
@@ -83,13 +91,16 @@ class Invoice2017:
 
                self.amount += decimal.Decimal(total.lstrip('$'))
 

	
 
    def _read_invoice_activity(self, table, first_row_text, rows_text):
 
        self.actions = []
 
        self.actions = [{
 
            'date': self.invoice_date,
 
            'status': STATUS_INVOICED,
 
        }]
 
        for timestamp, description, amount in rows_text:
 
            if description.startswith('Paid '):
 
                last_stripe_id = util.rslice_words(description, 1, limit=1)
 
                action = {
 
                    'multiplier': 1,
 
                    'payment_id': last_stripe_id,
 
                    'status': STATUS_PAID,
 
                }
 
            else:
 
                # Refund handling could go here, if we need it.
...
 
@@ -102,9 +113,6 @@ class Invoice2017:
 
        for action in self.actions:
 
            data = self.base_data.copy()
 
            data.update(action)
 
            multiplier = data.pop('multiplier')
 
            for key in ['amount', 'tickets_sold', 'shirts_sold']:
 
                data[key] *= multiplier
 
            yield data
 

	
 

	
...
 
@@ -129,13 +137,17 @@ class ImporterBase:
 

	
 
    def __iter__(self):
 
        for entry in self.invoice:
 
            if self._should_yield_entry(entry):
 
            if entry['status'] == self.YIELD_STATUS:
 
                yield entry
 

	
 

	
 
class Invoice2017Importer(ImporterBase):
 
    TEMPLATE_KEY = 'template nbpy2017 invoice'
 
    INVOICE_CLASS = Invoice2017
 
    YIELD_STATUS = STATUS_INVOICED
 

	
 

	
 
class Payment2017Importer(ImporterBase):
 
    TEMPLATE_KEY = 'template nbpy2017 payment'
 
    INVOICE_CLASS = Invoice2017
 

	
 
    def _should_yield_entry(self, entry):
 
        return entry['amount'] > 0
 
    YIELD_STATUS = STATUS_PAID
tests/data/imports.yml
Show inline comments
...
 
@@ -82,6 +82,51 @@
 
      payment_id: ch_hHee9ef1aeyee1ruo7ochee9
 
      description: "Payment for invoice #100"
 

	
 
- source: nbpy2017a.html
 
  importer: nbpy2017.Invoice2017Importer
 
  expect:
 
    - payee: Python Person A
 
      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"]
 
      shirts_sold: !!python/object/apply:decimal.Decimal ["1"]
 
      shirt_rate: !!python/object/apply:decimal.Decimal ["25.50"]
 
      currency: USD
 
      status: Invoice
 
      invoice_id: "83"
 
      invoice_date: !!python/object/apply:datetime.date [2017, 10, 19]
 

	
 
- source: nbpy2017b.html
 
  importer: nbpy2017.Invoice2017Importer
 
  expect:
 
    - payee: Python Person B
 
      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"]
 
      shirts_sold: !!python/object/apply:decimal.Decimal ["0"]
 
      shirt_rate: !!python/object/apply:decimal.Decimal ["25.50"]
 
      status: Invoice
 
      currency: USD
 
      invoice_date: !!python/object/apply:datetime.date [2017, 12, 3]
 
      invoice_id: "304"
 

	
 
- source: nbpy2017c.html
 
  importer: nbpy2017.Invoice2017Importer
 
  expect:
 
    - payee: Python Person C
 
      date: !!python/object/apply:datetime.date [2017, 10, 5]
 
      amount: !!python/object/apply:decimal.Decimal ["55.00"]
 
      tickets_sold: !!python/object/apply:decimal.Decimal ["1"]
 
      ticket_rate: !!python/object/apply:decimal.Decimal ["21.25"]
 
      shirts_sold: !!python/object/apply:decimal.Decimal ["1"]
 
      shirt_rate: !!python/object/apply:decimal.Decimal ["25.50"]
 
      status: Invoice
 
      currency: USD
 
      invoice_date: !!python/object/apply:datetime.date [2017, 10, 5]
 
      invoice_id: "11"
 

	
 
- source: nbpy2017a.html
 
  importer: nbpy2017.Payment2017Importer
 
  expect:
...
 
@@ -93,7 +138,9 @@
 
      shirts_sold: !!python/object/apply:decimal.Decimal ["1"]
 
      shirt_rate: !!python/object/apply:decimal.Decimal ["25.50"]
 
      currency: USD
 
      status: Payment
 
      invoice_id: "83"
 
      invoice_date: !!python/object/apply:datetime.date [2017, 10, 19]
 
      payment_id: ch_ahr0ue8lai1ohqu4Gei4Biem
 
      stripe_id: ch_ahr0ue8lai1ohqu4Gei4Biem
 

	
...
 
@@ -107,7 +154,9 @@
 
      ticket_rate: !!python/object/apply:decimal.Decimal ["42.50"]
 
      shirts_sold: !!python/object/apply:decimal.Decimal ["0"]
 
      shirt_rate: !!python/object/apply:decimal.Decimal ["25.50"]
 
      status: Payment
 
      currency: USD
 
      invoice_date: !!python/object/apply:datetime.date [2017, 12, 3]
 
      payment_id: ch_eishei9aiY8aiqu4lieYiu9i
 
      stripe_id: ch_eishei9aiY8aiqu4lieYiu9i
 
      invoice_id: "304"
...
 
@@ -122,7 +171,9 @@
 
      ticket_rate: !!python/object/apply:decimal.Decimal ["21.25"]
 
      shirts_sold: !!python/object/apply:decimal.Decimal ["1"]
 
      shirt_rate: !!python/object/apply:decimal.Decimal ["25.50"]
 
      status: Payment
 
      currency: USD
 
      invoice_date: !!python/object/apply:datetime.date [2017, 10, 5]
 
      payment_id: ch_daer0ahwoh9oDeiqu2eimoD7
 
      stripe_id: ch_daer0ahwoh9oDeiqu2eimoD7
 
      invoice_id: "11"
0 comments (0 inline, 0 general)