Skip to content

Commit cf437e1

Browse files
committed
Merge pull request #93 from recurly/use_invoice_settings_fields
Read and Write custom invoice notes from API
2 parents 7a2ea00 + 0d6ef01 commit cf437e1

7 files changed

Lines changed: 82 additions & 5 deletions

File tree

CHANGELOG

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
## Unreleased
22

3+
- Added ability to read and write invoice notes
4+
35
## Version 2.2.6 October 31, 2014
46

57
- Bug fix: `subscription.invoice` now returns the invoice for subscription

recurly/__init__.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,11 +174,16 @@ def charge(self, charge):
174174
url = urljoin(self._url, '%s/adjustments' % self.account_code)
175175
return charge.post(url)
176176

177-
def invoice(self):
177+
def invoice(self, **kwargs):
178178
"""Create an invoice for any outstanding adjustments this account has."""
179179
url = urljoin(self._url, '%s/invoices' % self.account_code)
180180

181-
response = self.http_request(url, 'POST')
181+
if kwargs:
182+
response = self.http_request(url, 'POST', Invoice(**kwargs), {'Content-Type':
183+
'application/xml; charset=utf-8'})
184+
else:
185+
response = self.http_request(url, 'POST')
186+
182187
if response.status != 201:
183188
self.raise_http_error(response)
184189

@@ -439,8 +444,18 @@ class Invoice(Resource):
439444
'created_at',
440445
'line_items',
441446
'transactions',
447+
'terms_and_conditions',
448+
'customer_notes',
442449
)
443450

451+
blacklist_attributes = (
452+
'currency',
453+
)
454+
455+
def serializable_attributes(self):
456+
return [attr for attr in self.attributes if attr not in
457+
self.blacklist_attributes]
458+
444459
@classmethod
445460
def all_open(cls, **kwargs):
446461
"""Return a `Page` of open invoices.
@@ -531,7 +546,9 @@ class Subscription(Resource):
531546
'collection_method',
532547
'po_number',
533548
'first_renewal_date',
534-
'bulk'
549+
'bulk',
550+
'terms_and_conditions',
551+
'customer_notes',
535552
)
536553
sensitive_attributes = ('number', 'verification_value', 'bulk')
537554

recurly/resource.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,13 @@ class Resource(object):
227227
even though this `Resource` class has no ``currency`` attribute of
228228
its own."""
229229

230+
def serializable_attributes(self):
231+
""" Attributes to be serialized in a ``POST`` or ``PUT`` request.
232+
Returns all attributes by default. Can be overriden on the child class.
233+
"""
234+
235+
return self.attributes
236+
230237
def __init__(self, **kwargs):
231238
try:
232239
self.attributes.index('currency') # Test for currency attribute,
@@ -673,7 +680,7 @@ def raise_http_error(cls, response):
673680
def to_element(self):
674681
"""Serialize this `Resource` instance to an XML element."""
675682
elem = ElementTree.Element(self.nodename)
676-
for attrname in self.attributes:
683+
for attrname in self.serializable_attributes():
677684
# Only use values that have been loaded into the internal
678685
# __dict__. For retrieved objects we look into the XML response at
679686
# access time, so the internal __dict__ contains only the elements
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
POST https://api.recurly.com/v2/accounts/invoicemock/invoices HTTP/1.1
2+
Accept: application/xml
3+
Authorization: Basic YXBpa2V5Og==
4+
User-Agent: recurly-python/{version}
5+
Content-Type: application/xml; charset=utf-8
6+
7+
<?xml version="1.0" encoding="UTF-8"?>
8+
<invoice>
9+
<terms_and_conditions>Some Terms and Conditions</terms_and_conditions>
10+
<customer_notes>Some Customer Notes</customer_notes>
11+
</invoice>
12+

13+
HTTP/1.1 201 Created
14+
Content-Type: application/xml; charset=utf-8
15+
Location: https://api.recurly.com/v2/invoices/4ba1531325014b4f969cd13676f514d8
16+
17+
<?xml version="1.0" encoding="UTF-8"?>
18+
<invoice href="https://api.recurly.com/v2/invoices/4ba1531325014b4f969cd13676f514d8">
19+
<uuid>4ba1531325014b4f969cd13676f514d8</uuid>
20+
<account_code>invoicemock</account_code>
21+
<amount_in_cents>
22+
<USD type="integer">1000</USD>
23+
</amount_in_cents>
24+
<terms_and_conditions>Some Terms and Conditions</terms_and_conditions>
25+
<customer_notes>Some Customer Notes</customer_notes>
26+
<start_date type="datetime">2009-11-03T23:27:46-08:00</start_date>
27+
<end_date type="datetime"></end_date>
28+
<description>test charge</description>
29+
<created_at type="datetime">2009-11-03T23:27:46-08:00</created_at>
30+
</invoice>

tests/fixtures/subscription/error-no-billing-info.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ Content-Type: application/xml; charset=utf-8
1010
<unit_amount_in_cents type="integer">1000</unit_amount_in_cents>
1111
<currency>USD</currency>
1212
<bulk type="boolean">true</bulk>
13+
<terms_and_conditions>Some Terms and Conditions</terms_and_conditions>
14+
<customer_notes>Some Customer Notes</customer_notes>
1315
</subscription>
1416

1517
HTTP/1.1 400 Bad Request

tests/fixtures/subscription/subscribed.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ Content-Type: application/xml; charset=utf-8
1010
<unit_amount_in_cents type="integer">1000</unit_amount_in_cents>
1111
<currency>USD</currency>
1212
<bulk type="boolean">true</bulk>
13+
<terms_and_conditions>Some Terms and Conditions</terms_and_conditions>
14+
<customer_notes>Some Customer Notes</customer_notes>
1315
</subscription>
1416

1517
HTTP/1.1 201 Created
@@ -36,6 +38,8 @@ Location: https://api.recurly.com/v2/subscriptions/12345678901234567890123456789
3638
<current_period_ends_at type="datetime">2010-07-27T07:00:00Z</current_period_ends_at>
3739
<trial_started_at nil="nil"></trial_started_at>
3840
<trial_ends_at nil="nil"></trial_ends_at>
41+
<terms_and_conditions>Some Terms and Conditions</terms_and_conditions>
42+
<customer_notes>Some Customer Notes</customer_notes>
3943
<subscription_add_ons type="array">
4044
</subscription_add_ons>
4145
<a name="cancel" href="https://api.recurly.com/v2/subscriptions/123456789012345678901234567890ab/cancel" method="put"/>

tests/test_resources.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,19 @@ def test_invoice(self):
541541
invoice = account.invoices()[0]
542542
self.assertEqual(invoice.tax_type, 'usst')
543543

544+
def test_invoice_with_optionals(self):
545+
account = Account(account_code='invoice%s' % self.test_id)
546+
with self.mock_request('invoice/account-created.xml'):
547+
account.save()
548+
549+
with self.mock_request('invoice/invoiced-with-optionals.xml'):
550+
invoice = account.invoice(terms_and_conditions='Some Terms and Conditions',
551+
customer_notes='Some Customer Notes')
552+
553+
self.assertEqual(type(invoice), recurly.Invoice)
554+
self.assertEqual(invoice.terms_and_conditions, 'Some Terms and Conditions')
555+
self.assertEqual(invoice.customer_notes, 'Some Customer Notes')
556+
544557
def test_build_invoice(self):
545558
account = Account(account_code='invoice%s' % self.test_id)
546559
with self.mock_request('invoice/account-created.xml'):
@@ -675,7 +688,9 @@ def test_subscribe(self):
675688
plan_code='basicplan',
676689
currency='USD',
677690
unit_amount_in_cents=1000,
678-
bulk=True
691+
bulk=True,
692+
terms_and_conditions='Some Terms and Conditions',
693+
customer_notes='Some Customer Notes'
679694
)
680695

681696
with self.mock_request('subscription/error-no-billing-info.xml'):

0 commit comments

Comments
 (0)