Skip to content
This repository has been archived by the owner on Feb 8, 2018. It is now read-only.

Commit

Permalink
get rid of BalancedThing
Browse files Browse the repository at this point in the history
closes #1681 and #2446
  • Loading branch information
Changaco committed Mar 24, 2015
1 parent 718c8fc commit b6d7f65
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 157 deletions.
110 changes: 0 additions & 110 deletions gratipay/billing/__init__.py
Original file line number Diff line number Diff line change
@@ -1,110 +0,0 @@
"""This module encapsulates billing logic and db access.
"""
from __future__ import unicode_literals

import balanced


class BalancedThing(object):
"""Represent either a credit card or a bank account.
"""

thing_type = None # either 'card' or 'bank_account'
keys_to_attr_paths = None # set to a mapping in subclasses

_customer = None # underlying balanced.Customer object
_thing = None # underlying balanced.{BankAccount,Card} object

def __getitem__(self, key):
"""Given a name, return a unicode.
Allow subclasses to provide a flat set of keys, which, under the hood,
might be nested attributes and/or keys. The traversal path is relative
to _thing (not self!).
"""
attr_path = self.keys_to_attr_paths.get(key, key)

out = None
if self._customer is not None and self._thing is not None:
out = self._thing
for val in attr_path.split('.'):
if type(out) is dict:
# this lets us reach into the meta dict
out = out.get(val)
else:
try:
out = getattr(out, val)
except AttributeError:
raise KeyError("{} not found".format(val))
if out is None:
break

if out is None:
# Default to ''; see https://github.com/gratipay/gratipay.com/issues/2161.
out = ''

return out

def __init__(self, balanced_customer_href):
"""Given a Balanced account_uri, load data from Balanced.
"""
if balanced_customer_href is None:
return

# XXX Indexing is borken. See:
# https://github.com/balanced/balanced-python/issues/10

self._customer = balanced.Customer.fetch(balanced_customer_href)

things = getattr(self._customer, self.thing_type+'s')\
.filter(is_valid=True).all()
nvalid = len(things)

if nvalid == 0:
self._thing = None
elif nvalid == 1:
self._thing = things[0]
else:
msg = "%s has %d valid %ss"
msg %= (balanced_customer_href, len(things), self.thing_type)
raise RuntimeError(msg)

@property
def is_setup(self):
return self._thing is not None


class BalancedCard(BalancedThing):
"""This is a dict-like wrapper around a Balanced credit card.
"""

thing_type = 'card'

keys_to_attr_paths = {
'id': 'customer.href',
'address_1': 'address.line1',
'address_2': 'meta.address_2',
'country': 'meta.country',
'city_town': 'meta.city_town',
'zip': 'address.postal_code',
# gratipay is saving the state in the meta field
# for compatibility with legacy customers
'state': 'meta.region',
'last4': 'number',
'last_four': 'number',
'card_type': 'brand',
'expiration_month': 'expiration_month',
'expiration_year': 'expiration_year',
}


class BalancedBankAccount(BalancedThing):
"""This is a dict-like wrapper around a Balanced bank account.
"""

thing_type = 'bank_account'

keys_to_attr_paths = {
'customer_href': 'customer.href',
}
38 changes: 22 additions & 16 deletions www/%username/receipts/%exchange_id.int.html.spt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import balanced

from aspen import Response
from gratipay.models.exchange_route import ExchangeRoute
from gratipay.utils import get_participant
from gratipay.billing import BalancedCard

[-------------------]

Expand All @@ -16,7 +18,11 @@ exchange = website.db.one("""
if exchange is None:
raise Response(404)

card = BalancedCard(participant.balanced_customer_href)
route = ExchangeRoute.from_id(exchange.route)
if route and route.network == 'balanced-cc':
card = balanced.Card.fetch(route.address)
else:
card = balanced.Card(address={}, meta={})

[-------------------]
<style>
Expand Down Expand Up @@ -87,42 +93,42 @@ card = BalancedCard(participant.balanced_customer_href)
<h1>Receipt</h1>

<div id="their-info">
{{ card['name'] }}
{{ card.name }}
({{ participant.username }})<br />
{{ card['last4'] }} ({{ card['card_type'] }})<br />
{{ card['address_1'] }}<br />
{% if card['address_2'] %}
{{ card['address_2'] }}<br />
{{ card.number }} ({{ card.brand }})<br />
{{ card.address.line1 }}<br />
{% if card.address.line2 %}
{{ card.address.line2 }}<br />
{% endif %}
{{ card['city_town'] }}{% if card['city_town'] %},{% endif %}
{{ card['state'] }}
{{ card['zip'] }}<br />
{{ locale.countries.get(card['country'], '') }}
{{ card.address.city }}{% if card.address.city %},{% endif %}
{{ card.address.state }}
{{ card.address.postal_code }}<br />
{{ locale.countries.get(card.address.country_code, '') }}
</div>

<table>
<tr>
<th>Amount:</th>
<td>$</td>
<td>{{ exchange['amount'] }}</td>
<td>{{ exchange.amount }}</td>
</tr>
<tr>
<th>Fee:</th>
<td>$</td>
<td>{{ exchange['fee'] }}</td>
<td>{{ exchange.fee }}</td>
</tr>
<tr class="total">
<th>Total:</th>
<td>$</td>
<td>{{ exchange['fee'] + exchange['amount'] }}</td>
<td>{{ exchange.fee + exchange.amount }}</td>
</tr>
</table>

<table id="txnid">
<tr>
<td class="date">{{ exchange['timestamp'].strftime("%B %d, %Y").replace(' 0', ' ') }}</td>
<td class="date">{{ exchange.timestamp.strftime("%B %d, %Y").replace(' 0', ' ') }}</td>
<td class="mdash">&mdash;</td>
<td class="txnid">Transaction ID: {{ exchange['id'] }}</td>
<td class="txnid">Transaction ID: {{ exchange.id }}</td>
</tr>
</table>

Expand Down
18 changes: 10 additions & 8 deletions www/%username/routes/bank-account.html.spt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from gratipay import billing
import balanced

from gratipay.billing.exchanges import MINIMUM_CREDIT
from gratipay.models.exchange_route import ExchangeRoute
from gratipay.utils import get_participant

[-----------------------------------------------------------------------------]
Expand All @@ -9,17 +11,16 @@ status = ". . ."

if not user.ANON:
participant = get_participant(state, restrict=True)
balanced_customer_href = participant.balanced_customer_href
last_ach_result = participant.last_ach_result

status = _("Your bank account is {0}not connected{1}")
if balanced_customer_href:
route = ExchangeRoute.from_network(participant, 'balanced-ba')
if route:
account = participant.get_balanced_account()
bank_account = balanced.BankAccount.fetch(route.address)
last_ach_result = route.error
if last_ach_result == "":
status = _("Your bank account is {0}connected{1}")

account = participant.get_balanced_account()
bank_account = billing.BalancedBankAccount(balanced_customer_href)

title = _("Bank Account")
[-----------------------------------------------------------------------------]
{% extends "templates/base.html" %}
Expand Down Expand Up @@ -83,7 +84,8 @@ title = _("Bank Account")

</form>

{% if bank_account and bank_account.is_setup %}

{% if bank_account %}
<form id="delete" data-thing="credit card"
data-confirm="{{ _('Are you sure you want to disconnect your bank account?') }}">
<button>{{ _("Disconnect My Bank Account") }}</button>
Expand Down
47 changes: 24 additions & 23 deletions www/%username/routes/credit-card.html.spt
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
from gratipay import billing
import balanced

from gratipay.models.exchange_route import ExchangeRoute
from gratipay.utils import get_participant

[-----------------------------------------------------------------------------]

status = status_msg = ". . ."
balanced_customer_href = None

if not user.ANON:
participant = get_participant(state, restrict=True)
balanced_customer_href = participant.balanced_customer_href
last_bill_result = participant.last_bill_result

status = "missing"
status_msg = _("Your credit card is {0}missing{1}")
if balanced_customer_href:
if last_bill_result is not None:
if last_bill_result == "":
status = "working"
status_msg = _("Your credit card is {0}working{1}")
else:
status = "failing"
status_msg = _("Your credit card is {0}failing{1}")

card = billing.BalancedCard(balanced_customer_href)
# the id on the card might not match unless the db
# is updated to use the new style of urls

route = ExchangeRoute.from_network(participant, 'balanced-cc')
if route:
card = balanced.Card.fetch(route.address)
last_bill_result = route.error
if last_bill_result == "":
status = "working"
status_msg = _("Your credit card is {0}working{1}")
else:
status = "failing"
status_msg = _("Your credit card is {0}failing{1}")
else:
card = balanced.Card(address={}, meta={})

title = _("Credit Card")

Expand Down Expand Up @@ -102,40 +102,41 @@ title = _("Credit Card")

<label>
<span>{{ _("Full Name on Card") }}</span>
<input id="name" value="{{ card['name'] }}" />
<input id="name" value="{{ card.name }}" />
</label>

<label>
<span>{{ _("Address 1") }}</span>
<input id="address_1" value="{{ card['address_1'] }}" />
<input id="address_1" value="{{ card.address.line1 }}" />
</label>

<label>
<span>{{ _("Address 2") }}</span>
<input id="address_2" value="{{ card['address_2'] }}" />
<input id="address_2" value="{{ card.address.line2 or card.meta.address_2 }}" />
</label>

<label>
<span>{{ _("City or Town") }}</span>
<input id="city_town" value="{{ card['city_town'] }}" />
<input id="city_town" value="{{ card.address.city or card.meta.city_town }}" />
</label>

<label class="half">
<span>{{ _("State or Province") }}</span>
<input id="state" value="{{ card['state'] }}" />
<input id="state" value="{{ card.address.state or card.meta.region }}" />
</label>

<label class="half right">
<span>{{ _("ZIP or Postal Code") }}</span>
<input id="zip" value="{{ card['zip'] }}" />
<input id="zip" value="{{ card.address.postal_code }}" />
</label>

<label>
<span>{{ _("Country") }}</span>
<select id="country" data-placeholder="{{ _('Select your country...') }}">
<option value=""></option>
{% set country = card.address.country_code or card.meta.country %}
{% for each in locale.countries.items() %}
<option value="{{ each[0] }}" {{ 'selected' if each[0] == card['country'] else '' }}>{{ each[1] }}</option>
<option value="{{ each[0] }}" {{ 'selected' if each[0] == country else '' }}>{{ each[1] }}</option>
{% endfor %}
</select>
</label>
Expand Down

0 comments on commit b6d7f65

Please sign in to comment.