importers.benevity: Initial version.
This commit is contained in:
parent
f2c869d783
commit
1b1e2d038c
1 changed files with 78 additions and 0 deletions
78
import2ledger/importers/benevity.py
Normal file
78
import2ledger/importers/benevity.py
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
import csv
|
||||||
|
|
||||||
|
from . import _csv
|
||||||
|
from .. import strparse
|
||||||
|
|
||||||
|
class PaymentImporter(_csv.CSVImporterBase):
|
||||||
|
DATE_FIELD = 'Date of Donation'
|
||||||
|
NAME_FIELDS = ['Donor First Name', 'Donor Last Name']
|
||||||
|
DECIMAL_FIELDS = {
|
||||||
|
'Donation Amount': 'donation_amount',
|
||||||
|
'Matched Amount': 'match_amount',
|
||||||
|
'Total': 'amount',
|
||||||
|
}
|
||||||
|
NEEDED_FIELDS = frozenset([
|
||||||
|
DATE_FIELD,
|
||||||
|
*NAME_FIELDS,
|
||||||
|
*DECIMAL_FIELDS,
|
||||||
|
])
|
||||||
|
COPIED_FIELDS = {
|
||||||
|
'Participating Corporation': 'corporation',
|
||||||
|
'Project': 'project',
|
||||||
|
'Comment': 'comment',
|
||||||
|
'Transaction ID': 'transaction_id',
|
||||||
|
'Donation Frequency': 'frequency',
|
||||||
|
}
|
||||||
|
TEMPLATE_KEY = 'template benevity payments'
|
||||||
|
DATE_FMT = '%Y-%m-%d'
|
||||||
|
NOT_SHARED = 'Not shared by donor'
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _read_header(cls, source):
|
||||||
|
needed_keys = cls.NEEDED_FIELDS.union(cls.COPIED_FIELDS)
|
||||||
|
header = {}
|
||||||
|
for row in csv.reader(source):
|
||||||
|
row_len = len(row)
|
||||||
|
if row_len < 2:
|
||||||
|
pass
|
||||||
|
elif row_len == 2:
|
||||||
|
header[row[0]] = row[1]
|
||||||
|
elif needed_keys.issubset(row):
|
||||||
|
return header, csv.DictReader(source, row)
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
raise ValueError("source is not a Benevity CSV")
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def can_import(cls, input_file):
|
||||||
|
try:
|
||||||
|
header, _ = cls._read_header(input_file)
|
||||||
|
except ValueError:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return bool(header)
|
||||||
|
|
||||||
|
def __init__(self, input_file):
|
||||||
|
header, self.in_csv = self._read_header(input_file)
|
||||||
|
self.entry_seed = {
|
||||||
|
'currency': header['Currency'],
|
||||||
|
'disbursement_id': header['Disbursement ID'],
|
||||||
|
'reference': header['Payment Reference'],
|
||||||
|
}
|
||||||
|
|
||||||
|
def _read_row(self, row):
|
||||||
|
try:
|
||||||
|
date = strparse.date(row[self.DATE_FIELD], self.DATE_FMT)
|
||||||
|
except ValueError:
|
||||||
|
return None
|
||||||
|
if all(row[key] == self.NOT_SHARED for key in self.NAME_FIELDS):
|
||||||
|
payee = 'Anonymous'
|
||||||
|
else:
|
||||||
|
payee = ' '.join(row[key] for key in self.NAME_FIELDS)
|
||||||
|
retval = {
|
||||||
|
'date': date,
|
||||||
|
'payee': payee,
|
||||||
|
}
|
||||||
|
retval.update((retkey, strparse.currency_decimal(row[rowkey]))
|
||||||
|
for rowkey, retkey in self.DECIMAL_FIELDS.items())
|
||||||
|
return retval
|
Loading…
Reference in a new issue