create the products

This commit is contained in:
Rimian Perkins 2019-10-15 21:50:30 +11:00
parent e51aa5f6f0
commit 23cb6ef93e
11 changed files with 123 additions and 32 deletions

View File

@ -11,6 +11,24 @@ module DiscoursePatrons
products = ::Stripe::Product.list products = ::Stripe::Product.list
render_json_dump products.data render_json_dump products.data
end end
def create
begin
product = ::Stripe::Product.create(
type: 'service',
name: params[:name],
active: params[:active],
metadata: {
group_name: params[:groupName]
}
)
render_json_dump product
rescue ::Stripe::InvalidRequestError => e
return render_json_error e.message
end
end
end end
end end
end end

View File

@ -2,8 +2,13 @@ import { popupAjaxError } from "discourse/lib/ajax-error";
export default Ember.Controller.extend({ export default Ember.Controller.extend({
actions: { actions: {
createPlan() { createProduct() {
this.get("model") // TODO: set default group name beforehand
if(this.get("model.product.groupName") === undefined) {
this.set("model.product.groupName", this.get("model.group.firstObject"));
}
this.get("model.product")
.save() .save()
.then(() => { .then(() => {
this.transitionToRoute("adminPlugins.discourse-patrons.products"); this.transitionToRoute("adminPlugins.discourse-patrons.products");

View File

@ -26,25 +26,33 @@ export default Ember.Controller.extend({
source: result.token.id source: result.token.id
}; };
return ajax("/patrons/customers", { method: "post", data: customerData }).then( return ajax("/patrons/customers", {
customer => { method: "post",
data: customerData
}).then(customer => {
// TODO move default plan into settings // TODO move default plan into settings
if(this.get('model.selectedPlan') === undefined) { if (this.get("model.selectedPlan") === undefined) {
this.set('model.selectedPlan', this.get('model.plans.firstObject')); this.set(
"model.selectedPlan",
this.get("model.plans.firstObject")
);
} }
const subscriptionData = { const subscriptionData = {
customer: customer.id, customer: customer.id,
plan: this.get('model.selectedPlan') plan: this.get("model.selectedPlan")
}; };
return ajax("/patrons/subscriptions", { method: "post", data: subscriptionData }).then( return ajax("/patrons/subscriptions", {
() => { method: "post",
return DiscourseURL.redirectTo(Discourse.SiteSettings.discourse_patrons_subscription_group_landing_page); data: subscriptionData
} }).then(() => {
); return DiscourseURL.redirectTo(
} Discourse.SiteSettings
.discourse_patrons_subscription_group_landing_page
); );
});
});
} }
}); });
} }

View File

@ -1,10 +1,16 @@
import { ajax } from "discourse/lib/ajax"; import { ajax } from "discourse/lib/ajax";
const AdminProduct = Discourse.Model.extend({ const AdminProduct = Discourse.Model.extend({
active: true,
destroy() {}, destroy() {},
save() { save() {
const data = {}; const data = {
name: this.name,
groupName: this.groupName,
active: this.active
};
return ajax("/patrons/admin/products", { method: "post", data }); return ajax("/patrons/admin/products", { method: "post", data });
} }

View File

@ -4,7 +4,8 @@ const AdminSubscription = Discourse.Model.extend({});
AdminSubscription.reopenClass({ AdminSubscription.reopenClass({
find() { find() {
return ajax("/patrons/admin/subscriptions", { method: "get" }).then(result => return ajax("/patrons/admin/subscriptions", { method: "get" }).then(
result =>
result.data.map(subscription => AdminSubscription.create(subscription)) result.data.map(subscription => AdminSubscription.create(subscription))
); );
} }

View File

@ -1,7 +1,11 @@
import AdminProduct from "discourse/plugins/discourse-patrons/discourse/models/admin-plan"; import AdminProduct from "discourse/plugins/discourse-patrons/discourse/models/admin-product";
import Group from "discourse/models/group";
export default Discourse.Route.extend({ export default Discourse.Route.extend({
model() { model(param) {
return AdminProduct.create(); const product = AdminProduct.create();
const groups = Group.findAll({ ignore_automatic: true });
return Ember.RSVP.hash({ product, groups });
} }
}); });

View File

@ -2,11 +2,15 @@
<table class="table discourse-patrons-admin"> <table class="table discourse-patrons-admin">
<thead> <thead>
<th>{{i18n 'discourse_patrons.admin.products.product.product_id'}}</th> <th>{{i18n 'discourse_patrons.admin.products.product.product_id'}}</th>
<th>{{i18n 'discourse_patrons.admin.products.product.group'}}</th>
<th>{{i18n 'discourse_patrons.admin.products.product.active'}}</th>
<th></th> <th></th>
</thead> </thead>
{{#each model as |product|}} {{#each model as |product|}}
<tr> <tr>
<td>{{product.id}}</td> <td>{{product.id}}</td>
<td>{{product.group}}</td>
<td>{{product.active}}</td>
<td class="td-right"> <td class="td-right">
{{d-button {{d-button
action=(action "editProduct" product.id) action=(action "editProduct" product.id)

View File

@ -4,11 +4,15 @@
<form class="form-horizontal"> <form class="form-horizontal">
<div> <div>
<label for="name">{{i18n 'discourse_patrons.admin.plans.show.name'}}</label> <label for="name">{{i18n 'discourse_patrons.admin.plans.show.name'}}</label>
{{input type="text" name="name" value=model.name}} {{input type="text" name="name" value=model.product.name}}
</div> </div>
<div> <div>
<label for="interval">{{i18n 'discourse_patrons.admin.products.show.groups'}}</label> <label for="interval">{{i18n 'discourse_patrons.admin.products.show.group'}}</label>
{{combo-box valueAttribute="value" content=model.intervals value=model.interval}} {{combo-box valueAttribute="value" content=model.groups value=model.product.groupName}}
</div>
<div>
<label for="interval">{{i18n 'discourse_patrons.admin.products.show.active'}}</label>
{{input type="checkbox" checked=model.product.active}}
</div> </div>
</form> </form>

View File

@ -62,6 +62,17 @@ en:
products: products:
title: Products title: Products
new: New Product new: New Product
show:
group: User Group
create: Create Product
active: Active
product:
product_id: Product ID
group: Group
active: Active
operations:
destroy:
confirm: Are you sure you want to destroy this product?
plans: plans:
title: Plans title: Plans
new: New Plan new: New Plan

View File

@ -9,7 +9,7 @@ DiscoursePatrons::Engine.routes.draw do
namespace :admin do namespace :admin do
resources :plans resources :plans
resources :subscriptions, only: [:index] resources :subscriptions, only: [:index]
resources :products, only: [:index] resources :products, only: [:index, :create]
end end
resources :customers, only: [:create] resources :customers, only: [:create]

View File

@ -15,6 +15,12 @@ module DiscoursePatrons
get "/patrons/admin/products.json" get "/patrons/admin/products.json"
expect(response.status).to eq(403) expect(response.status).to eq(403)
end end
it "does nothing" do
::Stripe::Product.expects(:create).never
post "/patrons/admin/products.json"
expect(response.status).to eq(403)
end
end end
context 'authenticated' do context 'authenticated' do
@ -22,11 +28,35 @@ module DiscoursePatrons
before { sign_in(admin) } before { sign_in(admin) }
describe 'index' do
it "gets the empty products" do it "gets the empty products" do
::Stripe::Product.expects(:list) ::Stripe::Product.expects(:list)
get "/patrons/admin/products.json" get "/patrons/admin/products.json"
end end
end end
describe 'create' do
it 'is of product type service' do
::Stripe::Product.expects(:create).with(has_entry(:type, 'service'))
post "/patrons/admin/products.json", params: {}
end
it 'has a name' do
::Stripe::Product.expects(:create).with(has_entry(:name, 'Jesse Pinkman'))
post "/patrons/admin/products.json", params: { name: 'Jesse Pinkman' }
end
it 'has an active attribute' do
::Stripe::Product.expects(:create).with(has_entry(active: false))
post "/patrons/admin/products.json", params: { active: false }
end
it 'has a metadata' do
::Stripe::Product.expects(:create).with(has_entry(:metadata, { group_name: 'discourse-user-group-name' }))
post "/patrons/admin/products.json", params: { group_name: 'discourse-user-group-name' }
end
end
end
end end
end end
end end