save the product
This commit is contained in:
parent
e2f1f0f523
commit
496f2b9706
|
@ -30,6 +30,36 @@ module DiscoursePatrons
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
begin
|
||||||
|
product = ::Stripe::Product.retrieve(params[:id])
|
||||||
|
|
||||||
|
render_json_dump product
|
||||||
|
|
||||||
|
rescue ::Stripe::InvalidRequestError => e
|
||||||
|
return render_json_error e.message
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
begin
|
||||||
|
product = ::Stripe::Product.update(
|
||||||
|
params[:id], {
|
||||||
|
name: params[:name],
|
||||||
|
active: params[:active],
|
||||||
|
metadata: {
|
||||||
|
group_name: params[:group_name]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
render_json_dump product
|
||||||
|
|
||||||
|
rescue ::Stripe::InvalidRequestError => e
|
||||||
|
return render_json_error e.message
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
begin
|
begin
|
||||||
product = ::Stripe::Product.delete(params[:id])
|
product = ::Stripe::Product.delete(params[:id])
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||||
export default Ember.Controller.extend({
|
export default Ember.Controller.extend({
|
||||||
actions: {
|
actions: {
|
||||||
createPlan() {
|
createPlan() {
|
||||||
this.get("model")
|
this.get("model.plan")
|
||||||
.save()
|
.save()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.transitionToRoute("adminPlugins.discourse-patrons.plans");
|
this.transitionToRoute("adminPlugins.discourse-patrons.plans");
|
||||||
|
|
|
@ -17,6 +17,15 @@ export default Ember.Controller.extend({
|
||||||
this.transitionToRoute("adminPlugins.discourse-patrons.products");
|
this.transitionToRoute("adminPlugins.discourse-patrons.products");
|
||||||
})
|
})
|
||||||
.catch(popupAjaxError);
|
.catch(popupAjaxError);
|
||||||
|
},
|
||||||
|
|
||||||
|
updateProduct() {
|
||||||
|
this.get("model.product")
|
||||||
|
.update()
|
||||||
|
.then(() => {
|
||||||
|
this.transitionToRoute("adminPlugins.discourse-patrons.products");
|
||||||
|
})
|
||||||
|
.catch(popupAjaxError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,7 +5,7 @@ export default {
|
||||||
this.route("discourse-patrons", function() {
|
this.route("discourse-patrons", function() {
|
||||||
this.route("dashboard");
|
this.route("dashboard");
|
||||||
this.route("products", function() {
|
this.route("products", function() {
|
||||||
this.route("show", { path: "/:plan-id" });
|
this.route("show", { path: "/:product-id" });
|
||||||
});
|
});
|
||||||
this.route("plans", function() {
|
this.route("plans", function() {
|
||||||
this.route("show", { path: "/:plan-id" });
|
this.route("show", { path: "/:plan-id" });
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import { ajax } from "discourse/lib/ajax";
|
import { ajax } from "discourse/lib/ajax";
|
||||||
|
|
||||||
const AdminProduct = Discourse.Model.extend({
|
const AdminProduct = Discourse.Model.extend({
|
||||||
|
isNew: false,
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
return ajax(`/patrons/admin/products/${this.id}`, { method: "delete" });
|
return ajax(`/patrons/admin/products/${this.id}`, { method: "delete" });
|
||||||
},
|
},
|
||||||
|
@ -13,6 +15,16 @@ const AdminProduct = Discourse.Model.extend({
|
||||||
};
|
};
|
||||||
|
|
||||||
return ajax("/patrons/admin/products", { method: "post", data });
|
return ajax("/patrons/admin/products", { method: "post", data });
|
||||||
|
},
|
||||||
|
|
||||||
|
update() {
|
||||||
|
const data = {
|
||||||
|
name: this.name,
|
||||||
|
groupName: this.groupName,
|
||||||
|
active: this.active
|
||||||
|
};
|
||||||
|
|
||||||
|
return ajax(`/patrons/admin/products/${this.id}`, { method: "patch", data });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -21,7 +33,13 @@ AdminProduct.reopenClass({
|
||||||
return ajax("/patrons/admin/products", { method: "get" }).then(result =>
|
return ajax("/patrons/admin/products", { method: "get" }).then(result =>
|
||||||
result.map(product => AdminProduct.create(product))
|
result.map(product => AdminProduct.create(product))
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
|
|
||||||
|
find(id) {
|
||||||
|
return ajax(`/patrons/admin/products/${id}`, { method: "get" }).then(product =>
|
||||||
|
AdminProduct.create(product)
|
||||||
|
);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default AdminProduct;
|
export default AdminProduct;
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
import AdminPlan from "discourse/plugins/discourse-patrons/discourse/models/admin-plan";
|
import AdminPlan from "discourse/plugins/discourse-patrons/discourse/models/admin-plan";
|
||||||
|
import AdminProduct from "discourse/plugins/discourse-patrons/discourse/models/admin-product";
|
||||||
|
|
||||||
export default Discourse.Route.extend({
|
export default Discourse.Route.extend({
|
||||||
model() {
|
model() {
|
||||||
return AdminPlan.create();
|
const plan = AdminPlan.create();
|
||||||
|
const products = AdminProduct.findAll();
|
||||||
|
|
||||||
|
return Ember.RSVP.hash({ plan, products });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,8 +2,17 @@ import AdminProduct from "discourse/plugins/discourse-patrons/discourse/models/a
|
||||||
import Group from "discourse/models/group";
|
import Group from "discourse/models/group";
|
||||||
|
|
||||||
export default Discourse.Route.extend({
|
export default Discourse.Route.extend({
|
||||||
model(param) {
|
model(params) {
|
||||||
const product = AdminProduct.create();
|
const id = params['product-id'];
|
||||||
|
let product;
|
||||||
|
|
||||||
|
if(id === 'new') {
|
||||||
|
product = AdminProduct.create({ active: true, isNew: true });
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
product = AdminProduct.find(id);
|
||||||
|
}
|
||||||
|
|
||||||
const groups = Group.findAll({ ignore_automatic: true });
|
const groups = Group.findAll({ ignore_automatic: true });
|
||||||
|
|
||||||
return Ember.RSVP.hash({ product, groups });
|
return Ember.RSVP.hash({ product, groups });
|
||||||
|
|
|
@ -2,18 +2,22 @@
|
||||||
<h4>{{i18n 'discourse_patrons.admin.plans.title'}}</h4>
|
<h4>{{i18n 'discourse_patrons.admin.plans.title'}}</h4>
|
||||||
|
|
||||||
<form class="form-horizontal">
|
<form class="form-horizontal">
|
||||||
<div>
|
<p>
|
||||||
<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.plan.name}}
|
||||||
</div>
|
</p>
|
||||||
<div>
|
<p>
|
||||||
<label for="amount">{{i18n 'discourse_patrons.admin.plans.show.amount'}}</label>
|
<label for="amount">{{i18n 'discourse_patrons.admin.plans.show.amount'}}</label>
|
||||||
{{input type="text" name="name" value=model.amount}}
|
{{input type="text" name="name" value=model.plan.amount}}
|
||||||
</div>
|
</p>
|
||||||
<div>
|
<p>
|
||||||
|
<label for="product">{{i18n 'discourse_patrons.admin.plans.show.product'}}</label>
|
||||||
|
{{combo-box valueAttribute="value" content=model.products value=defaultProduct}}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
<label for="interval">{{i18n 'discourse_patrons.admin.plans.show.interval'}}</label>
|
<label for="interval">{{i18n 'discourse_patrons.admin.plans.show.interval'}}</label>
|
||||||
{{combo-box valueAttribute="value" content=model.intervals value=model.interval}}
|
{{combo-box valueAttribute="value" content=model.plan.intervals value=model.plan.interval}}
|
||||||
</div>
|
</p>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
|
|
|
@ -2,20 +2,24 @@
|
||||||
<h4>{{i18n 'discourse_patrons.admin.products.title'}}</h4>
|
<h4>{{i18n 'discourse_patrons.admin.products.title'}}</h4>
|
||||||
|
|
||||||
<form class="form-horizontal">
|
<form class="form-horizontal">
|
||||||
<div>
|
<p>
|
||||||
<label for="name">{{i18n 'discourse_patrons.admin.plans.show.name'}}</label>
|
<label for="name">{{i18n 'discourse_patrons.admin.products.product.name'}}</label>
|
||||||
{{input type="text" name="name" value=model.product.name}}
|
{{input type="text" name="name" value=model.product.name}}
|
||||||
</div>
|
</p>
|
||||||
<div>
|
<p>
|
||||||
<label for="interval">{{i18n 'discourse_patrons.admin.products.show.group'}}</label>
|
<label for="interval">{{i18n 'discourse_patrons.admin.products.product.group'}}</label>
|
||||||
{{combo-box valueAttribute="value" content=model.groups value=model.product.groupName}}
|
{{combo-box valueAttribute="value" content=model.groups value=model.product.groupName}}
|
||||||
</div>
|
</p>
|
||||||
<div>
|
<p>
|
||||||
<label for="interval">{{i18n 'discourse_patrons.admin.products.show.active'}}</label>
|
<label for="interval">{{i18n 'discourse_patrons.admin.products.product.active'}}</label>
|
||||||
{{input type="checkbox" checked=model.product.active}}
|
{{input type="checkbox" checked=model.product.active}}
|
||||||
</div>
|
</p>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
{{d-button label="discourse_patrons.admin.products.show.create" action="createProduct" icon="plus"}}
|
{{#if model.product.isNew}}
|
||||||
|
{{d-button label="discourse_patrons.admin.products.operations.create" action="createProduct" icon="plus"}}
|
||||||
|
{{else}}
|
||||||
|
{{d-button label="discourse_patrons.admin.products.operations.update" action="updateProduct" icon="fa-save"}}
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<p class="btn-right">
|
<p class="btn-right">
|
||||||
{{#link-to 'adminPlugins.discourse-patrons.products.show' 'new' class="btn btn-primary"}}
|
{{#link-to 'adminPlugins.discourse-patrons.products.show' 'new' class="btn btn-primary"}}
|
||||||
{{d-icon "plus"}}
|
{{d-icon "plus"}}
|
||||||
<span>{{i18n 'discourse_patrons.admin.products.new'}}</span>
|
<span>{{i18n 'discourse_patrons.admin.products.operations.new'}}</span>
|
||||||
{{/link-to}}
|
{{/link-to}}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
|
@ -61,18 +61,17 @@ en:
|
||||||
amount: Amount
|
amount: Amount
|
||||||
products:
|
products:
|
||||||
title: Products
|
title: Products
|
||||||
new: New Product
|
|
||||||
show:
|
|
||||||
group: User Group
|
|
||||||
create: Create Product
|
|
||||||
active: Active
|
|
||||||
product:
|
|
||||||
product_id: Product ID
|
|
||||||
group: User Group
|
|
||||||
active: Active
|
|
||||||
operations:
|
operations:
|
||||||
|
create: Create New Product
|
||||||
|
update: Update Product
|
||||||
|
new: New Product
|
||||||
destroy:
|
destroy:
|
||||||
confirm: Are you sure you want to destroy this product?
|
confirm: Are you sure you want to destroy this product?
|
||||||
|
product:
|
||||||
|
product_id: Product ID
|
||||||
|
name: Product Name
|
||||||
|
group: User Group
|
||||||
|
active: Active
|
||||||
plans:
|
plans:
|
||||||
title: Plans
|
title: Plans
|
||||||
new: New Plan
|
new: New Plan
|
||||||
|
|
|
@ -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, :create, :destroy]
|
resources :products
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :customers, only: [:create]
|
resources :customers, only: [:create]
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
enabled_site_setting :discourse_patrons_enabled
|
enabled_site_setting :discourse_patrons_enabled
|
||||||
|
|
||||||
gem 'stripe', '5.7.0'
|
gem 'stripe', '5.7.1'
|
||||||
|
|
||||||
register_asset "stylesheets/common/discourse-patrons.scss"
|
register_asset "stylesheets/common/discourse-patrons.scss"
|
||||||
register_asset "stylesheets/mobile/discourse-patrons.scss"
|
register_asset "stylesheets/mobile/discourse-patrons.scss"
|
||||||
|
|
|
@ -16,13 +16,25 @@ module DiscoursePatrons
|
||||||
expect(response.status).to eq(403)
|
expect(response.status).to eq(403)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not create the products" do
|
it "does not create the product" do
|
||||||
::Stripe::Product.expects(:create).never
|
::Stripe::Product.expects(:create).never
|
||||||
post "/patrons/admin/products.json"
|
post "/patrons/admin/products.json"
|
||||||
expect(response.status).to eq(403)
|
expect(response.status).to eq(403)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not delete the products" do
|
it "does not show the product" do
|
||||||
|
::Stripe::Product.expects(:retrieve).never
|
||||||
|
get "/patrons/admin/products/prod_qwerty123.json"
|
||||||
|
expect(response.status).to eq(403)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not update the product" do
|
||||||
|
::Stripe::Product.expects(:update).never
|
||||||
|
put "/patrons/admin/products/prod_qwerty123.json"
|
||||||
|
expect(response.status).to eq(403)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not delete the product" do
|
||||||
::Stripe::Product.expects(:delete).never
|
::Stripe::Product.expects(:delete).never
|
||||||
delete "/patrons/admin/products/u2.json"
|
delete "/patrons/admin/products/u2.json"
|
||||||
expect(response.status).to eq(403)
|
expect(response.status).to eq(403)
|
||||||
|
@ -63,6 +75,20 @@ module DiscoursePatrons
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'show' do
|
||||||
|
it 'retrieves the product' do
|
||||||
|
::Stripe::Product.expects(:retrieve).with('prod_walterwhite')
|
||||||
|
get "/patrons/admin/products/prod_walterwhite.json"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'update' do
|
||||||
|
it 'updates the product' do
|
||||||
|
::Stripe::Product.expects(:update)
|
||||||
|
patch "/patrons/admin/products/prod_walterwhite.json", params: {}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe 'delete' do
|
describe 'delete' do
|
||||||
it 'deletes the product' do
|
it 'deletes the product' do
|
||||||
::Stripe::Product.expects(:delete).with('prod_walterwhite')
|
::Stripe::Product.expects(:delete).with('prod_walterwhite')
|
||||||
|
|
Loading…
Reference in New Issue