list subscriptions

This commit is contained in:
Rimian Perkins 2019-10-29 11:43:32 +11:00
parent 5a7097b774
commit 7edb0fe39b
13 changed files with 125 additions and 17 deletions

View File

@ -3,10 +3,8 @@
module DiscoursePatrons module DiscoursePatrons
class InvoicesController < ::ApplicationController class InvoicesController < ::ApplicationController
include DiscoursePatrons::Stripe include DiscoursePatrons::Stripe
requires_login
before_action :set_api_key before_action :set_api_key
requires_login
def index def index
begin begin

View File

@ -3,8 +3,25 @@
module DiscoursePatrons module DiscoursePatrons
class SubscriptionsController < ::ApplicationController class SubscriptionsController < ::ApplicationController
include DiscoursePatrons::Stripe include DiscoursePatrons::Stripe
before_action :set_api_key before_action :set_api_key
requires_login
def index
begin
customer = DiscoursePatrons::Customer.find_user(current_user)
if customer.present?
subscriptions = ::Stripe::Subscription.list(customer: customer.customer_id)
else
subscriptions = []
end
render_json_dump subscriptions
rescue ::Stripe::InvalidRequestError => e
return render_json_error e.message
end
end
def create def create
begin begin

View File

@ -1,6 +1,12 @@
import computed from "ember-addons/ember-computed-decorators";
import { ajax } from "discourse/lib/ajax"; import { ajax } from "discourse/lib/ajax";
const Subscription = Discourse.Model.extend({ const Subscription = Discourse.Model.extend({
@computed("created")
createdFormatted(created) {
return moment.unix(created).format();
},
save() { save() {
const data = { const data = {
customer: this.customer, customer: this.customer,
@ -11,4 +17,12 @@ const Subscription = Discourse.Model.extend({
} }
}); });
Subscription.reopenClass({
findAll() {
return ajax("/patrons/subscriptions", { method: "get" }).then(result =>
result.map(subscription => Subscription.create(subscription))
);
}
});
export default Subscription; export default Subscription;

View File

@ -0,0 +1,15 @@
import Subscription from "discourse/plugins/discourse-patrons/discourse/models/subscription";
export default Discourse.Route.extend({
model() {
return Subscription.findAll();
},
setupController(controller, model) {
if (this.currentUser.id !== this.modelFor("user").id) {
this.replaceWith("userActivity");
} else {
controller.setProperties({ model });
}
}
});

View File

@ -1,3 +0,0 @@
{{#if (user-viewing-self model)}}
{{#link-to 'user.billing'}}{{d-icon "credit-card"}}{{I18n 'discourse_patrons.navigation.billing'}}{{/link-to}}
{{/if}}

View File

@ -0,0 +1,3 @@
{{#if (user-viewing-self model)}}
{{#link-to 'user.subscriptions'}}{{d-icon "credit-card"}}{{I18n 'discourse_patrons.navigation.subscriptions'}}{{/link-to}}
{{/if}}

View File

@ -2,13 +2,6 @@
<h3>{{i18n 'discourse_patrons.user.billing.title'}}</h3> <h3>{{i18n 'discourse_patrons.user.billing.title'}}</h3>
{{#if model}} {{#if model}}
<p class="btn-right">
{{#link-to 'user.subscriptions' class="btn btn-primary"}}
{{d-icon "credit-card"}}
<span>{{i18n 'discourse_patrons.user.subscriptions.title'}}</span>
{{/link-to}}
</p>
<table class="topic-list"> <table class="topic-list">
<thead> <thead>
<th>{{i18n 'discourse_patrons.user.billing.invoices.amount'}}</th> <th>{{i18n 'discourse_patrons.user.billing.invoices.amount'}}</th>

View File

@ -0,0 +1,27 @@
<h3>{{i18n 'discourse_patrons.user.billing.title'}}</h3>
{{#if model}}
<table class="topic-list">
<thead>
<th>{{i18n 'discourse_patrons.user.billing.invoices.amount'}}</th>
<th>{{i18n 'discourse_patrons.user.billing.invoices.number'}}</th>
<th>{{i18n 'discourse_patrons.user.billing.invoices.created_at'}}</th>
<th></th>
</thead>
{{#each model as |invoice|}}
<tr>
<td>{{invoice.amount_paid}}</td>
<td>{{invoice.number}}</td>
<td>{{format-date invoice.createdFormatted}}</td>
<td class="td-right">
<a href="{{invoice.invoice_pdf}}" class="btn btn-icon">
{{d-icon "download"}}
</a>
</td>
</tr>
{{/each}}
</table>
{{else}}
<p>{{i18n 'discourse_patrons.user.billing_help'}}</p>
{{/if}}

View File

@ -1,2 +1,21 @@
{{#d-section class="user-secondary-navigation" pageClass="user-subscriptions"}}
<h3>{{i18n 'discourse_patrons.user.subscriptions.title'}}</h3> <h3>{{i18n 'discourse_patrons.user.subscriptions.title'}}</h3>
{{#if model}}
<table class="topic-list">
<thead>
<th>{{i18n 'discourse_patrons.user.billing.subscriptions.created_at'}}</th>
<th></th>
</thead>
{{#each model as |subscription|}}
<tr>
<td>{{format-date subscription.createdFormatted}}</td>
</tr>
{{/each}}
</table>
{{else}}
<p>{{i18n 'discourse_patrons.user.subscriptions_help'}}</p>
{{/if}}
{{/d-section}}

View File

@ -18,11 +18,14 @@ en:
title: Discourse Patrons title: Discourse Patrons
optional: Optional optional: Optional
navigation: navigation:
subscriptions: Subscriptions
subscribe: Subscribe subscribe: Subscribe
billing: Billing billing: Billing
user: user:
subscriptions_help: You have no subscriptions.
subscriptions: subscriptions:
title: Subscriptions title: Subscriptions
created_at: Created
billing_help: We couldn't find a customer identifier in our system. billing_help: We couldn't find a customer identifier in our system.
billing: billing:
title: Billing title: Billing
@ -30,7 +33,6 @@ en:
amount: Amount amount: Amount
number: Invoice Number number: Invoice Number
created_at: Created created_at: Created
subscribe:
title: Subscribe title: Subscribe
card: card:
title: Payment title: Payment

View File

@ -17,7 +17,7 @@ DiscoursePatrons::Engine.routes.draw do
resources :patrons, only: [:index, :create] resources :patrons, only: [:index, :create]
resources :plans, only: [:index] resources :plans, only: [:index]
resources :products, only: [:index] resources :products, only: [:index]
resources :subscriptions, only: [:create] resources :subscriptions, only: [:index, :create]
get '/' => 'patrons#index' get '/' => 'patrons#index'
end end

View File

@ -36,6 +36,7 @@ Discourse::Application.routes.append do
get '/admin/plugins/discourse-patrons/plans' => 'admin/plugins#index' get '/admin/plugins/discourse-patrons/plans' => 'admin/plugins#index'
get '/admin/plugins/discourse-patrons/plans/:plan_id' => 'admin/plugins#index' get '/admin/plugins/discourse-patrons/plans/:plan_id' => 'admin/plugins#index'
get 'u/:username/billing' => 'users#show', constraints: { username: USERNAME_ROUTE_FORMAT } get 'u/:username/billing' => 'users#show', constraints: { username: USERNAME_ROUTE_FORMAT }
get 'u/:username/subscriptions' => 'users#show', constraints: { username: USERNAME_ROUTE_FORMAT }
end end
after_initialize do after_initialize do

View File

@ -4,6 +4,14 @@ require 'rails_helper'
module DiscoursePatrons module DiscoursePatrons
RSpec.describe SubscriptionsController do RSpec.describe SubscriptionsController do
context "not authenticated" do
it "does not create a subscription" do
::Stripe::Plan.expects(:retrieve).never
::Stripe::Subscription.expects(:create).never
post "/patrons/subscriptions.json", params: { plan: 'plan_1234', customer: 'cus_1234' }
end
end
context "authenticated" do context "authenticated" do
let(:user) { Fabricate(:user, email: 'hello.2@example.com') } let(:user) { Fabricate(:user, email: 'hello.2@example.com') }
@ -11,6 +19,20 @@ module DiscoursePatrons
sign_in(user) sign_in(user)
end end
describe "index" do
it "does not get subscriptions if there is no customer" do
::Stripe::Subscription.expects(:create).never
get "/patrons/subscriptions.json"
expect(response.body).to eq "[]"
end
it "gets subscriptions" do
DiscoursePatrons::Customer.create(user_id: user.id, customer_id: 'cus_id5678')
::Stripe::Subscription.expects(:list).with(customer: 'cus_id5678')
get "/patrons/subscriptions.json"
end
end
describe "create" do describe "create" do
it "creates a subscription" do it "creates a subscription" do
::Stripe::Plan.expects(:retrieve).returns(metadata: { group_name: 'awesome' }) ::Stripe::Plan.expects(:retrieve).returns(metadata: { group_name: 'awesome' })