diff --git a/app/controllers/invoices_controller.rb b/app/controllers/invoices_controller.rb index 57dc385..bb223b8 100644 --- a/app/controllers/invoices_controller.rb +++ b/app/controllers/invoices_controller.rb @@ -3,10 +3,8 @@ module DiscoursePatrons class InvoicesController < ::ApplicationController include DiscoursePatrons::Stripe - - requires_login - before_action :set_api_key + requires_login def index begin diff --git a/app/controllers/subscriptions_controller.rb b/app/controllers/subscriptions_controller.rb index b6d3f07..6a63ff0 100644 --- a/app/controllers/subscriptions_controller.rb +++ b/app/controllers/subscriptions_controller.rb @@ -3,8 +3,25 @@ module DiscoursePatrons class SubscriptionsController < ::ApplicationController include DiscoursePatrons::Stripe - 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 begin diff --git a/assets/javascripts/discourse/models/subscription.js.es6 b/assets/javascripts/discourse/models/subscription.js.es6 index c57d215..abae050 100644 --- a/assets/javascripts/discourse/models/subscription.js.es6 +++ b/assets/javascripts/discourse/models/subscription.js.es6 @@ -1,6 +1,12 @@ +import computed from "ember-addons/ember-computed-decorators"; import { ajax } from "discourse/lib/ajax"; const Subscription = Discourse.Model.extend({ + @computed("created") + createdFormatted(created) { + return moment.unix(created).format(); + }, + save() { const data = { 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; diff --git a/assets/javascripts/discourse/routes/user-subscriptions.js.es6 b/assets/javascripts/discourse/routes/user-subscriptions.js.es6 index e69de29..54fc11d 100644 --- a/assets/javascripts/discourse/routes/user-subscriptions.js.es6 +++ b/assets/javascripts/discourse/routes/user-subscriptions.js.es6 @@ -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 }); + } + } +}); diff --git a/assets/javascripts/discourse/templates/connectors/user-main-nav/billing.hbs b/assets/javascripts/discourse/templates/connectors/user-main-nav/billing.hbs deleted file mode 100644 index b225547..0000000 --- a/assets/javascripts/discourse/templates/connectors/user-main-nav/billing.hbs +++ /dev/null @@ -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}} diff --git a/assets/javascripts/discourse/templates/connectors/user-main-nav/subscriptions.hbs b/assets/javascripts/discourse/templates/connectors/user-main-nav/subscriptions.hbs new file mode 100644 index 0000000..66370fd --- /dev/null +++ b/assets/javascripts/discourse/templates/connectors/user-main-nav/subscriptions.hbs @@ -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}} diff --git a/assets/javascripts/discourse/templates/user/billing.hbs b/assets/javascripts/discourse/templates/user/billing.hbs index e73da42..d1ea854 100644 --- a/assets/javascripts/discourse/templates/user/billing.hbs +++ b/assets/javascripts/discourse/templates/user/billing.hbs @@ -2,13 +2,6 @@

{{i18n 'discourse_patrons.user.billing.title'}}

{{#if model}} -

- {{#link-to 'user.subscriptions' class="btn btn-primary"}} - {{d-icon "credit-card"}} - {{i18n 'discourse_patrons.user.subscriptions.title'}} - {{/link-to}} -

- diff --git a/assets/javascripts/discourse/templates/user/invoices.hbs b/assets/javascripts/discourse/templates/user/invoices.hbs new file mode 100644 index 0000000..d1ea854 --- /dev/null +++ b/assets/javascripts/discourse/templates/user/invoices.hbs @@ -0,0 +1,27 @@ + +

{{i18n 'discourse_patrons.user.billing.title'}}

+ +{{#if model}} +
{{i18n 'discourse_patrons.user.billing.invoices.amount'}}
+ + + + + + + {{#each model as |invoice|}} + + + + + + + {{/each}} +
{{i18n 'discourse_patrons.user.billing.invoices.amount'}}{{i18n 'discourse_patrons.user.billing.invoices.number'}}{{i18n 'discourse_patrons.user.billing.invoices.created_at'}}
{{invoice.amount_paid}}{{invoice.number}}{{format-date invoice.createdFormatted}} + + {{d-icon "download"}} + +
+{{else}} +

{{i18n 'discourse_patrons.user.billing_help'}}

+{{/if}} diff --git a/assets/javascripts/discourse/templates/user/subscriptions.hbs b/assets/javascripts/discourse/templates/user/subscriptions.hbs index 843ddd4..aeb361b 100644 --- a/assets/javascripts/discourse/templates/user/subscriptions.hbs +++ b/assets/javascripts/discourse/templates/user/subscriptions.hbs @@ -1,2 +1,21 @@ +{{#d-section class="user-secondary-navigation" pageClass="user-subscriptions"}} -

{{i18n 'discourse_patrons.user.subscriptions.title'}}

+

{{i18n 'discourse_patrons.user.subscriptions.title'}}

+ + {{#if model}} + + + + + + {{#each model as |subscription|}} + + + + {{/each}} +
{{i18n 'discourse_patrons.user.billing.subscriptions.created_at'}}
{{format-date subscription.createdFormatted}}
+ {{else}} +

{{i18n 'discourse_patrons.user.subscriptions_help'}}

+ {{/if}} + +{{/d-section}} diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 3acaad3..884cb5d 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -18,11 +18,14 @@ en: title: Discourse Patrons optional: Optional navigation: + subscriptions: Subscriptions subscribe: Subscribe billing: Billing user: + subscriptions_help: You have no subscriptions. subscriptions: title: Subscriptions + created_at: Created billing_help: We couldn't find a customer identifier in our system. billing: title: Billing @@ -30,7 +33,6 @@ en: amount: Amount number: Invoice Number created_at: Created - subscribe: title: Subscribe card: title: Payment diff --git a/config/routes.rb b/config/routes.rb index 5d16e81..5ba8fa3 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -17,7 +17,7 @@ DiscoursePatrons::Engine.routes.draw do resources :patrons, only: [:index, :create] resources :plans, only: [:index] resources :products, only: [:index] - resources :subscriptions, only: [:create] + resources :subscriptions, only: [:index, :create] get '/' => 'patrons#index' end diff --git a/plugin.rb b/plugin.rb index 6b48b1d..ea73e8d 100644 --- a/plugin.rb +++ b/plugin.rb @@ -36,6 +36,7 @@ Discourse::Application.routes.append do get '/admin/plugins/discourse-patrons/plans' => '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/subscriptions' => 'users#show', constraints: { username: USERNAME_ROUTE_FORMAT } end after_initialize do diff --git a/spec/requests/subscriptions_controller_spec.rb b/spec/requests/subscriptions_controller_spec.rb index b6e028f..de6c82a 100644 --- a/spec/requests/subscriptions_controller_spec.rb +++ b/spec/requests/subscriptions_controller_spec.rb @@ -4,6 +4,14 @@ require 'rails_helper' module DiscoursePatrons 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 let(:user) { Fabricate(:user, email: 'hello.2@example.com') } @@ -11,6 +19,20 @@ module DiscoursePatrons sign_in(user) 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 it "creates a subscription" do ::Stripe::Plan.expects(:retrieve).returns(metadata: { group_name: 'awesome' })