Skip to content

Commit f057d39

Browse files
committed
Finish subscriptions (incl. order, orderline, product)
1 parent abd4b50 commit f057d39

File tree

11 files changed

+219
-44
lines changed

11 files changed

+219
-44
lines changed

membersuite_api_client/financial/__init__.py

Whitespace-only changes.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from __future__ import (absolute_import, division, print_function,
2+
unicode_literals)
3+
from future.utils import python_2_unicode_compatible
4+
5+
from ..models import MemberSuiteObject
6+
7+
8+
@python_2_unicode_compatible
9+
class Product(MemberSuiteObject):
10+
11+
def __init__(self, membersuite_object_data, session_id=None):
12+
"""Create an Product object from a the Zeep'ed XML
13+
representation of a Membersuite Product.
14+
15+
"""
16+
super(Product, self).__init__(
17+
membersuite_object_data=membersuite_object_data)
18+
self.name = self.fields['Name']
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from ..exceptions import ExecuteMSQLError
2+
from ..utils import get_new_client
3+
from .models import Product
4+
5+
6+
def get_product(membersuite_id, client=None):
7+
"""Return a Product object by ID.
8+
"""
9+
if not membersuite_id:
10+
return None
11+
12+
client = client or get_new_client(request_session=True)
13+
14+
query = "SELECT Object() FROM PRODUCT WHERE ID = '{}'".format(
15+
membersuite_id)
16+
17+
result = client.runSQL(query)
18+
19+
msql_result = result["body"]["ExecuteMSQLResult"]
20+
21+
if msql_result["Success"]:
22+
membersuite_object_data = (msql_result["ResultValue"]
23+
["SingleObject"])
24+
else:
25+
raise ExecuteMSQLError(result=result)
26+
27+
return Product(membersuite_object_data=membersuite_object_data)

membersuite_api_client/mixins.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,6 @@ class ChunkQueryMixin(object):
2828
2929
Membersuite will often time out on big queries, so this allows us to
3030
break it up into smaller requests.
31-
32-
Design assumptions:
33-
- The service defines an `result_to_models` method to "transform"
34-
the objects returned by the endpoint
3531
"""
3632

3733
def get_long_query(self, base_query, limit_to=100, max_calls=None,
@@ -86,7 +82,6 @@ def get_long_query(self, base_query, limit_to=100, max_calls=None,
8682
else:
8783
search_results = None
8884

89-
9085
if search_results is None:
9186
result_set = []
9287
else:

membersuite_api_client/models.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,18 @@
88
@python_2_unicode_compatible
99
class MemberSuiteObject(object):
1010

11-
def __init__(self, membersuite_object_data):
11+
def __init__(self, membersuite_object_data, membersuite_id=None):
1212
"""Takes the Zeep'ed XML Representation of a MemberSuiteObject as
1313
input.
1414
1515
"""
1616
self.fields = convert_ms_object(
1717
membersuite_object_data["Fields"]["KeyValueOfstringanyType"])
18-
19-
self.membersuite_id = self.fields["ID"]
2018
self.extra_data = membersuite_object_data
19+
self.membersuite_id = (self.fields["ID"]
20+
if membersuite_id is None
21+
else membersuite_id)
2122

2223
def __str__(self):
23-
return ("<MemberSuiteObject: ID: {id}>".format(id=self.id))
24+
return ("<MemberSuiteObject: MemberSuite ID: {id}>".format(
25+
id=self.membersuite_id))

membersuite_api_client/orders/__init__.py

Whitespace-only changes.
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
from __future__ import (absolute_import, division, print_function,
2+
unicode_literals)
3+
from future.utils import python_2_unicode_compatible
4+
5+
from ..models import MemberSuiteObject
6+
from ..utils import get_new_client, value_for_key
7+
from ..financial import services as financial_services
8+
9+
10+
@python_2_unicode_compatible
11+
class OrderLineItem(MemberSuiteObject):
12+
13+
def __init__(self, membersuite_object_data, session_id=None):
14+
"""Create an OrderLineItem object from a the Zeep'ed XML
15+
representation of a Membersuite OrderLineItem.
16+
17+
"""
18+
membersuite_id = value_for_key(
19+
membersuite_object_data=membersuite_object_data,
20+
key="OrderLineItemID")
21+
super(OrderLineItem, self).__init__(
22+
membersuite_object_data=membersuite_object_data,
23+
membersuite_id=membersuite_id)
24+
self.product_id = self.fields["Product"]
25+
self.session_id = session_id
26+
27+
def __str__(self):
28+
return ("<Order: ID: {id}, product: {product} "
29+
" session_id: {session_id}>".format(
30+
id=self.membersuite_id,
31+
product=self.product,
32+
session_id=self.session_id))
33+
34+
def get_product(self, client=None):
35+
"""Return a Product object for this line item.
36+
"""
37+
client = client or get_new_client(request_session=True)
38+
if not client.session_id:
39+
client.request_session()
40+
41+
product = financial_services.get_product(
42+
membersuite_id=self.product_id,
43+
client=client)
44+
45+
return product
46+
47+
48+
@python_2_unicode_compatible
49+
class Order(MemberSuiteObject):
50+
51+
def __init__(self, membersuite_object_data, session_id=None):
52+
"""Create an Order object from a the Zeep'ed XML representation of
53+
a Membersuite Order.
54+
55+
"""
56+
super(Order, self).__init__(
57+
membersuite_object_data=membersuite_object_data)
58+
self.session_id = session_id
59+
60+
def __str__(self):
61+
return ("<Order: ID: {id}, Line Items: {line_items} "
62+
" session_id: {session_id}>".format(
63+
id=self.membersuite_id,
64+
line_items=self.line_items,
65+
session_id=self.session_id))
66+
67+
@property
68+
def first_line_item(self):
69+
"""Returns the first OrderLineItem object for line items in this order.
70+
"""
71+
membersuite_object_data = (
72+
self.fields["LineItems"]["MemberSuiteObject"][0])
73+
line_item = OrderLineItem(
74+
membersuite_object_data=membersuite_object_data)
75+
return line_item
76+
77+
def get_products(self, client=None):
78+
"""A list of Product objects in this Order.
79+
"""
80+
client = client or get_new_client(request_session=True)
81+
if not client.session_id:
82+
client.request_session()
83+
products = []
84+
for line_item in self.line_items:
85+
products.append(line_item.get_product(client=client))
86+
return products
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from ..exceptions import ExecuteMSQLError
2+
from ..utils import get_new_client
3+
from .models import Order
4+
5+
6+
def get_order(membersuite_id, client=None):
7+
"""Get an Order by ID.
8+
"""
9+
if not membersuite_id:
10+
return None
11+
12+
client = client or get_new_client(request_session=True)
13+
if not client.session_id:
14+
client.request_session()
15+
16+
query = "SELECT Object() FROM ORDER WHERE ID = '{}'".format(
17+
membersuite_id)
18+
19+
result = client.runSQL(query)
20+
21+
msql_result = result["body"]["ExecuteMSQLResult"]
22+
23+
if msql_result["Success"]:
24+
membersuite_object_data = (msql_result["ResultValue"]
25+
["SingleObject"])
26+
else:
27+
raise ExecuteMSQLError(result=result)
28+
29+
return Order(membersuite_object_data=membersuite_object_data)
Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,35 @@
1+
# -*- coding: utf-8 -*-
12
"""
23
Models the Subscription object in MemberSuite
34
45
http://api.docs.membersuite.com/#References/Objects/Subscription.htm
56
"""
7+
from __future__ import unicode_literals
68

9+
from ..models import MemberSuiteObject
10+
from ..orders import services as orders_services
711

8-
class Subscription(object):
912

10-
def __init__(self, id, org_id, name, start, end, extra_data={}):
11-
self.id = id
12-
self.org_id = org_id
13-
self.name = name
14-
self.start = start
15-
self.end = end
16-
self.extra_data = extra_data # all other fields, for reference
13+
class Subscription(MemberSuiteObject):
14+
15+
def __init__(self, membersuite_object_data):
16+
super(Subscription, self).__init__(
17+
membersuite_object_data=membersuite_object_data)
18+
self.owner_id = self.fields['Owner']
19+
self.start_date = self.fields['StartDate']
20+
self.expiration_date = self.fields['ExpirationDate']
21+
self.order_id = self.fields['OriginalOrder']
22+
23+
def get_order(self, client=None):
24+
order = orders_services.get_order(membersuite_id=self.order_id,
25+
client=client)
26+
return order
27+
28+
def get_product(self, client=None):
29+
order = self.get_order(client=client)
30+
if order:
31+
first_line_item = order.first_line_item
32+
product = first_line_item.get_product(client=client)
33+
return product
34+
else:
35+
return None

membersuite_api_client/subscriptions/services.py

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,23 @@
88
@todo
99
add date modified param for performance
1010
"""
11-
12-
from .models import Subscription
1311
from ..mixins import ChunkQueryMixin
14-
from ..utils import convert_ms_object
12+
from ..utils import get_new_client
13+
from .models import Subscription
1514

1615
import datetime
1716

1817

1918
class SubscriptionService(ChunkQueryMixin, object):
2019

21-
def __init__(self, client):
20+
def __init__(self, client=None):
2221
"""
2322
Accepts a ConciergeClient to connect with MemberSuite
2423
"""
25-
self.client = client
24+
super(SubscriptionService, self).__init__()
25+
self.client = client or get_new_client()
2626

27-
def get_subscriptions(self, publication_id=None, org_id=None,
27+
def get_subscriptions(self, publication_id=None, owner_id=None,
2828
since_when=None, limit_to=200, max_calls=None,
2929
start_record=0, verbose=False):
3030
"""
@@ -37,8 +37,8 @@ def get_subscriptions(self, publication_id=None, org_id=None,
3737
# (key, operator, value) tuples
3838
where_params = []
3939

40-
if org_id:
41-
where_params.append(('owner', '=', "'%s'" % org_id))
40+
if owner_id:
41+
where_params.append(('owner', '=', "'%s'" % owner_id))
4242
if publication_id:
4343
where_params.append(('publication', '=', "'%s'" % publication_id))
4444
if since_when:
@@ -51,9 +51,6 @@ def get_subscriptions(self, publication_id=None, org_id=None,
5151
query += " AND ".join(
5252
["%s %s %s" % (p[0], p[1], p[2]) for p in where_params])
5353

54-
# note, get_long_query is overkill when just looking at
55-
# one org, but it still only executes once
56-
# `get_long_query` uses `ms_object_to_model` to return Subscriptions
5754
subscription_list = self.get_long_query(
5855
query, limit_to=limit_to, max_calls=max_calls,
5956
start_record=start_record, verbose=verbose)
@@ -62,13 +59,4 @@ def get_subscriptions(self, publication_id=None, org_id=None,
6259

6360
def ms_object_to_model(self, ms_obj):
6461
" Converts an individual result to a Subscription Model "
65-
sane_obj = convert_ms_object(
66-
ms_obj['Fields']['KeyValueOfstringanyType'])
67-
subscription = Subscription(
68-
id=sane_obj['ID'],
69-
org_id=sane_obj['Owner'],
70-
name=sane_obj['Name'],
71-
start=sane_obj['StartDate'],
72-
end=sane_obj['ExpirationDate'],
73-
extra_data=sane_obj)
74-
return subscription
62+
return Subscription(membersuite_object_data=ms_obj)

0 commit comments

Comments
 (0)