Merge remote-tracking branch 'remotes/origin/dev' into add-device
# Conflicts: # api/account/account_api/api.py # api/account/tests/features/steps/update_membership.py # shared/selene/api/endpoints/account.py # shared/selene/data/account/repository/sql/get_active_membership_by_account_id.sqlpull/79/head
commit
c851624256
|
@ -64,7 +64,8 @@ def _add_account(context, db):
|
|||
type='Monthly Membership',
|
||||
start_date=date.today(),
|
||||
payment_method='Stripe',
|
||||
payment_account_id='foo'
|
||||
payment_account_id='foo',
|
||||
payment_id='bar'
|
||||
),
|
||||
agreements=[
|
||||
AccountAgreement(type=PRIVACY_POLICY, accept_date=date.today())
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import json
|
||||
from datetime import date
|
||||
|
||||
from behave import given, when, then
|
||||
from hamcrest import assert_that, equal_to, starts_with, none
|
||||
|
||||
from selene.api.testing import generate_access_token, generate_refresh_token
|
||||
from selene.data.account import AccountRepository
|
||||
from selene.data.account import AccountRepository, Account, AccountAgreement, PRIVACY_POLICY
|
||||
from selene.util.db import get_db_connection
|
||||
|
||||
new_account_request = dict(
|
||||
|
@ -14,11 +15,13 @@ new_account_request = dict(
|
|||
login=dict(
|
||||
federatedEmail=None,
|
||||
userEnteredEmail='test@mycroft.ai',
|
||||
password='test'
|
||||
password='12345678'
|
||||
),
|
||||
support=dict(
|
||||
openDataset=True,
|
||||
membership=None
|
||||
membership='Maybe Later',
|
||||
paymentMethod=None,
|
||||
paymentAccountId=None
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -40,15 +43,20 @@ yearly_membership = {
|
|||
|
||||
|
||||
@given('a user with a free account')
|
||||
def create_account_free_account(context):
|
||||
context.client.post(
|
||||
'/api/account',
|
||||
data=json.dumps(new_account_request),
|
||||
content_type='application_json'
|
||||
def create_account(context):
|
||||
context.account = Account(
|
||||
email_address='test@mycroft.ai',
|
||||
username='test',
|
||||
refresh_tokens=[],
|
||||
membership=None,
|
||||
agreements=[
|
||||
AccountAgreement(type=PRIVACY_POLICY, accept_date=date.today())
|
||||
]
|
||||
)
|
||||
with get_db_connection(context.client_config['DB_CONNECTION_POOL']) as db:
|
||||
account = AccountRepository(db).get_account_by_email(new_account_request['login']['userEnteredEmail'])
|
||||
context.account = account
|
||||
acct_repository = AccountRepository(db)
|
||||
account_id = acct_repository.add(context.account, 'foo')
|
||||
context.account.id = account_id
|
||||
generate_access_token(context)
|
||||
generate_refresh_token(context)
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ CREATE TABLE account.account_membership (
|
|||
membership_ts_range tsrange NOT NULL,
|
||||
payment_method payment_method_enum NOT NULL,
|
||||
payment_account_id text NOT NULL,
|
||||
payment_id text NOT NULL,
|
||||
insert_ts TIMESTAMP NOT NULL
|
||||
DEFAULT CURRENT_TIMESTAMP,
|
||||
EXCLUDE USING gist (account_id WITH =, membership_ts_range with &&),
|
||||
|
|
|
@ -207,12 +207,19 @@ class AccountEndpoint(SeleneEndpoint):
|
|||
payment_token = self.request_data['support']['paymentToken']
|
||||
email = self.request_data['login']['userEnteredEmail']
|
||||
plan = self._get_plan(membership_type).stripe_plan
|
||||
payment_account_id, start = self._create_stripe_subscription(None, payment_token, email, plan)
|
||||
payment_account_id, start, subscription_id = self._create_stripe_subscription(
|
||||
None,
|
||||
payment_token,
|
||||
email,
|
||||
plan
|
||||
)
|
||||
|
||||
membership = AccountMembership(
|
||||
type=membership_type,
|
||||
start_date=date.today(),
|
||||
payment_method=self.request_data['support']['paymentMethod'],
|
||||
payment_account_id=payment_account_id
|
||||
payment_account_id=payment_account_id,
|
||||
payment_id=subscription_id
|
||||
)
|
||||
account = Account(
|
||||
email_address=email_address,
|
||||
|
@ -236,10 +243,9 @@ class AccountEndpoint(SeleneEndpoint):
|
|||
customer_id = customer.id
|
||||
subscription = stripe.Subscription.create(customer=customer_id, items=[{'plan': plan}])
|
||||
|
||||
# TODO: store subscription.id
|
||||
start = subscription.current_period_start
|
||||
start = date.fromtimestamp(start)
|
||||
return customer_id, start
|
||||
return customer_id, start, subscription.id
|
||||
|
||||
def _get_plan(self, plan):
|
||||
with get_db_connection(self.config['DB_CONNECTION_POOL']) as db:
|
||||
|
@ -250,38 +256,52 @@ class AccountEndpoint(SeleneEndpoint):
|
|||
membership_repository = MembershipRepository(db)
|
||||
active_membership = membership_repository.get_active_membership_by_account_id(self.account.id)
|
||||
if active_membership:
|
||||
active_membership.end_date = datetime.utcnow()
|
||||
# TODO: use the subscription id to delete the membership on stripe
|
||||
membership_repository.finish_membership(active_membership)
|
||||
add_membership = UpdateMembership(self.request_data.get('support'))
|
||||
add_membership.validate()
|
||||
support = self.request_data['support']
|
||||
membership_type = support['membership']
|
||||
membership = self._get_plan(membership_type)
|
||||
stripe_id, start_date = self._create_stripe_subscription(
|
||||
active_membership.payment_account_id,
|
||||
None,
|
||||
self.account.email_address,
|
||||
membership.stripe_plan
|
||||
)
|
||||
self.cancel_membership(active_membership, membership_repository)
|
||||
membership_type, start_date, stripe_id, subscription_stripe_id = self.update_membership(
|
||||
active_membership)
|
||||
else:
|
||||
add_membership = AddMembership(self.request_data.get('support'))
|
||||
add_membership.validate()
|
||||
support = self.request_data['support']
|
||||
membership_type = support['membership']
|
||||
token = support['paymentToken']
|
||||
membership = self._get_plan(membership_type)
|
||||
stripe_id, start_date = self._create_stripe_subscription(
|
||||
None,
|
||||
token,
|
||||
self.account.email_address,
|
||||
membership.stripe_plan
|
||||
)
|
||||
membership_type, start_date, stripe_id, subscription_stripe_id = self.create_membership()
|
||||
|
||||
new_membership = AccountMembership(
|
||||
start_date=start_date,
|
||||
payment_method=STRIPE_PAYMENT,
|
||||
payment_account_id=stripe_id,
|
||||
payment_id=subscription_stripe_id,
|
||||
type=membership_type
|
||||
)
|
||||
AccountRepository(db).add_membership(self.account.id, new_membership)
|
||||
|
||||
def create_membership(self):
|
||||
add_membership = AddMembership(self.request_data.get('support'))
|
||||
add_membership.validate()
|
||||
support = self.request_data['support']
|
||||
membership_type = support['membership']
|
||||
token = support['paymentToken']
|
||||
membership = self._get_plan(membership_type)
|
||||
stripe_id, start_date, subscription_stripe_id = self._create_stripe_subscription(
|
||||
None,
|
||||
token,
|
||||
self.account.email_address,
|
||||
membership.stripe_plan
|
||||
)
|
||||
return membership_type, start_date, stripe_id, subscription_stripe_id
|
||||
|
||||
def update_membership(self, active_membership):
|
||||
add_membership = UpdateMembership(self.request_data.get('support'))
|
||||
add_membership.validate()
|
||||
support = self.request_data['support']
|
||||
membership_type = support['membership']
|
||||
membership = self._get_plan(membership_type)
|
||||
stripe_id, start_date, subscription_stripe_id = self._create_stripe_subscription(
|
||||
active_membership.payment_account_id,
|
||||
None,
|
||||
self.account.email_address,
|
||||
membership.stripe_plan
|
||||
)
|
||||
return membership_type, start_date, stripe_id, subscription_stripe_id
|
||||
|
||||
def cancel_membership(self, active_membership, membership_repository):
|
||||
active_membership.end_date = datetime.utcnow()
|
||||
active_stripe_subscription = stripe.Subscription.retrieve(active_membership.payment_id)
|
||||
active_stripe_subscription.delete()
|
||||
membership_repository.finish_membership(active_membership)
|
||||
|
|
|
@ -18,6 +18,7 @@ class AccountMembership(object):
|
|||
start_date: date
|
||||
payment_method: str
|
||||
payment_account_id: str
|
||||
payment_id: str
|
||||
id: str = None
|
||||
end_date: date = None
|
||||
|
||||
|
|
|
@ -83,7 +83,8 @@ class AccountRepository(object):
|
|||
account_id=acct_id,
|
||||
membership_type=membership.type,
|
||||
payment_method=membership.payment_method,
|
||||
payment_account_id=membership.payment_account_id
|
||||
payment_account_id=membership.payment_account_id,
|
||||
payment_id=membership.payment_id
|
||||
)
|
||||
)
|
||||
self.cursor.insert(request)
|
||||
|
|
|
@ -4,7 +4,8 @@ INSERT INTO
|
|||
membership_id,
|
||||
membership_ts_range,
|
||||
payment_method,
|
||||
payment_account_id
|
||||
payment_account_id,
|
||||
payment_id
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
|
@ -19,5 +20,6 @@ VALUES
|
|||
),
|
||||
'[now,]',
|
||||
%(payment_method)s,
|
||||
%(payment_account_id)s
|
||||
%(payment_account_id)s,
|
||||
%(payment_id)s
|
||||
)
|
||||
|
|
|
@ -29,7 +29,8 @@ WITH
|
|||
'type', m.type,
|
||||
'start_date', lower(am.membership_ts_range)::DATE,
|
||||
'payment_method', am.payment_method,
|
||||
'payment_account_id', am.payment_account_id
|
||||
'payment_account_id', am.payment_account_id,
|
||||
'payment_id', am.payment_id
|
||||
)
|
||||
FROM
|
||||
account.account_membership am
|
||||
|
|
|
@ -3,10 +3,11 @@ SELECT
|
|||
mem.type,
|
||||
LOWER(acc_mem.membership_ts_range) start_date,
|
||||
acc_mem.payment_method,
|
||||
payment_account_id
|
||||
payment_account_id,
|
||||
payment_id
|
||||
FROM
|
||||
account.account_membership acc_mem
|
||||
INNER JOIN
|
||||
account.membership mem ON acc_mem.membership_id = mem.id
|
||||
WHERE
|
||||
account_id = %(account_id)s AND UPPER(acc_mem.membership_ts_range) IS NULL
|
||||
account_id = %(account_id)s AND UPPER(acc_mem.membership_ts_range) IS NULL
|
||||
|
|
Loading…
Reference in New Issue