From b00c1a427d4ae68ec1113e4352cee0fba9229fb3 Mon Sep 17 00:00:00 2001
From: Angus McLeod
Date: Thu, 4 Jan 2024 14:45:51 +0100
Subject: [PATCH 1/5] Add x-discourse-subscriptions into
discourse-subscription-server
---
.../user_authorizations_controller.rb | 11 ++
.../components/create-coupon-form.hbs | 47 +++++
.../modal/subscription-invoices.hbs | 22 +++
.../components/modal/subscription-invoices.js | 6 +
.../discourse/components/payment-plan.hbs | 12 ++
.../discourse/components/product-item.hbs | 37 ++++
.../components/subscription-data.gjs | 21 +++
.../components/subscription-domain.gjs | 31 ++++
.../components/subscription-domains.gjs | 40 ++++
.../components/subscription-invoices-btn.gjs | 23 +++
.../components/subscriptions-banner.hbs | 1 +
.../components/subscriptions-banner.js | 16 ++
.../subscriptions-banner-container.hbs | 1 +
.../subscription-server-initializer.js | 106 +++++++++++
assets/javascripts/discourse/lib/products.js | 34 ++++
.../discourse/routes/subscribe-alias.js | 7 +
.../routes/user-billing-authorizations.js | 9 +
.../discourse/subscriptions-route-map.js | 3 +
...-discourse-subscriptions-products-show.hbs | 175 ++++++++++++++++++
.../discourse/templates/user/billing.hbs | 29 +++
.../templates/user/billing/authorizations.hbs | 13 ++
.../discourse/user-subscriptions-route-map.js | 13 ++
assets/stylesheets/common/common.scss | 73 ++++++++
config/locales/client.en.yml | 31 +++-
config/routes.rb | 2 +
config/settings.yml | 15 ++
coverage/.last_run.json | 5 -
...scriptions_coupons_controller_extension.rb | 29 +++
...criptions_products_controller_extension.rb | 31 ++++
...iptions_subscriber_controller_extension.rb | 22 +++
plugin.rb | 42 +++++
.../subscription_server/user_spec.rb | 9 +
.../user_authorizations_controller_spec.rb | 41 ++++
33 files changed, 951 insertions(+), 6 deletions(-)
create mode 100644 app/controllers/subscription_server/user_authorizations_controller.rb
create mode 100644 assets/javascripts/discourse/components/create-coupon-form.hbs
create mode 100644 assets/javascripts/discourse/components/modal/subscription-invoices.hbs
create mode 100644 assets/javascripts/discourse/components/modal/subscription-invoices.js
create mode 100644 assets/javascripts/discourse/components/payment-plan.hbs
create mode 100644 assets/javascripts/discourse/components/product-item.hbs
create mode 100644 assets/javascripts/discourse/components/subscription-data.gjs
create mode 100644 assets/javascripts/discourse/components/subscription-domain.gjs
create mode 100644 assets/javascripts/discourse/components/subscription-domains.gjs
create mode 100644 assets/javascripts/discourse/components/subscription-invoices-btn.gjs
create mode 100644 assets/javascripts/discourse/components/subscriptions-banner.hbs
create mode 100644 assets/javascripts/discourse/components/subscriptions-banner.js
create mode 100644 assets/javascripts/discourse/connectors/top-notices/subscriptions-banner-container.hbs
create mode 100644 assets/javascripts/discourse/initializers/subscription-server-initializer.js
create mode 100644 assets/javascripts/discourse/lib/products.js
create mode 100644 assets/javascripts/discourse/routes/subscribe-alias.js
create mode 100644 assets/javascripts/discourse/routes/user-billing-authorizations.js
create mode 100644 assets/javascripts/discourse/subscriptions-route-map.js
create mode 100644 assets/javascripts/discourse/templates/admin/plugins-discourse-subscriptions-products-show.hbs
create mode 100644 assets/javascripts/discourse/templates/user/billing.hbs
create mode 100644 assets/javascripts/discourse/templates/user/billing/authorizations.hbs
create mode 100644 assets/javascripts/discourse/user-subscriptions-route-map.js
create mode 100644 assets/stylesheets/common/common.scss
delete mode 100644 coverage/.last_run.json
create mode 100644 extensions/discourse_subscriptions_coupons_controller_extension.rb
create mode 100644 extensions/discourse_subscriptions_products_controller_extension.rb
create mode 100644 extensions/discourse_subscriptions_subscriber_controller_extension.rb
create mode 100644 spec/requests/subscription_server/user_authorizations_controller_spec.rb
diff --git a/app/controllers/subscription_server/user_authorizations_controller.rb b/app/controllers/subscription_server/user_authorizations_controller.rb
new file mode 100644
index 0000000..0baed79
--- /dev/null
+++ b/app/controllers/subscription_server/user_authorizations_controller.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class SubscriptionServer::UserAuthorizationsController < ApplicationController
+ before_action :ensure_logged_in
+
+ def destroy
+ params.require(:domain)
+ current_user.remove_subscription_domain(params[:domain])
+ render json: success_json
+ end
+end
diff --git a/assets/javascripts/discourse/components/create-coupon-form.hbs b/assets/javascripts/discourse/components/create-coupon-form.hbs
new file mode 100644
index 0000000..741bca3
--- /dev/null
+++ b/assets/javascripts/discourse/components/create-coupon-form.hbs
@@ -0,0 +1,47 @@
+
diff --git a/assets/javascripts/discourse/components/modal/subscription-invoices.hbs b/assets/javascripts/discourse/components/modal/subscription-invoices.hbs
new file mode 100644
index 0000000..bae5c6a
--- /dev/null
+++ b/assets/javascripts/discourse/components/modal/subscription-invoices.hbs
@@ -0,0 +1,22 @@
+
+ <:body>
+ {{i18n "discourse_subscriptions.user.invoices.modal.description" email=this.currentUser.email}}
+
+ <:footer>
+
+ {{d-icon "external-link-alt"}}
+
+ {{i18n "discourse_subscriptions.user.invoices.modal.btn"}}
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/javascripts/discourse/components/modal/subscription-invoices.js b/assets/javascripts/discourse/components/modal/subscription-invoices.js
new file mode 100644
index 0000000..108c548
--- /dev/null
+++ b/assets/javascripts/discourse/components/modal/subscription-invoices.js
@@ -0,0 +1,6 @@
+import Component from "@glimmer/component";
+import { inject as service } from "@ember/service";
+
+export default class SubscriptionInvoices extends Component {
+ @service currentUser;
+}
diff --git a/assets/javascripts/discourse/components/payment-plan.hbs b/assets/javascripts/discourse/components/payment-plan.hbs
new file mode 100644
index 0000000..873fa73
--- /dev/null
+++ b/assets/javascripts/discourse/components/payment-plan.hbs
@@ -0,0 +1,12 @@
+
+
+ {{#if recurringPlan}}
+ {{i18n (concat "discourse_subscriptions.plans.interval.adverb." plan.recurring.interval)}}
+ {{else}}
+ {{i18n "discourse_subscriptions.one_time_payment"}}
+ {{/if}}
+
+
+
+ {{format-currency plan.currency plan.amountDollars}}
+
\ No newline at end of file
diff --git a/assets/javascripts/discourse/components/product-item.hbs b/assets/javascripts/discourse/components/product-item.hbs
new file mode 100644
index 0000000..33fba67
--- /dev/null
+++ b/assets/javascripts/discourse/components/product-item.hbs
@@ -0,0 +1,37 @@
+{{product.name}}
+
+
+ {{html-safe product.description}}
+
+
+{{#if isLoggedIn}}
+
+ {{#if product.custom}}
+
+ {{product.btnLabel}}
+
+ {{else}}
+ {{#if product.repurchaseable}}
+ {{#link-to "subscribe.show" product.id class="btn btn-primary"}}
+ {{i18n "discourse_subscriptions.subscribe.title"}}
+ {{/link-to}}
+ {{#if product.subscribed}}
+ {{#link-to "user.billing.subscriptions" currentUser.username class="billing-link"}}
+ {{i18n "discourse_subscriptions.subscribe.view_past"}}
+ {{/link-to}}
+ {{/if}}
+ {{else}}
+ {{#if product.subscribed}}
+
✓ {{i18n "discourse_subscriptions.subscribe.purchased"}}
+ {{#link-to "user.billing.subscriptions" currentUser.username class="billing-link"}}
+ {{i18n "discourse_subscriptions.subscribe.go_to_billing"}}
+ {{/link-to}}
+ {{else}}
+ {{#link-to "subscribe.show" product.id disabled=product.subscribed class="btn btn-primary"}}
+ {{i18n "discourse_subscriptions.subscribe.title"}}
+ {{/link-to}}
+ {{/if}}
+ {{/if}}
+ {{/if}}
+
+{{/if}}
diff --git a/assets/javascripts/discourse/components/subscription-data.gjs b/assets/javascripts/discourse/components/subscription-data.gjs
new file mode 100644
index 0000000..261f07d
--- /dev/null
+++ b/assets/javascripts/discourse/components/subscription-data.gjs
@@ -0,0 +1,21 @@
+import Component from "@glimmer/component";
+import SubscriptionDomains from "./subscription-domains";
+
+export default class SubscriptionDomain extends Component {
+
+
+ {{@data.resource}} |
+
+
+ {{#each @data.products as |product|}}
+ - {{product}}
+ {{/each}}
+
+ |
+
+
+ |
+ {{@data.domain_limit}} |
+
+
+}
diff --git a/assets/javascripts/discourse/components/subscription-domain.gjs b/assets/javascripts/discourse/components/subscription-domain.gjs
new file mode 100644
index 0000000..2f6392e
--- /dev/null
+++ b/assets/javascripts/discourse/components/subscription-domain.gjs
@@ -0,0 +1,31 @@
+import Component from "@glimmer/component";
+import { action } from "@ember/object";
+import DButton from "discourse/components/d-button";
+import { tracked } from "@glimmer/tracking";
+
+export default class SubscriptionDomain extends Component {
+ @tracked removing;
+
+ @action
+ removeDomain() {
+ this.removing = true;
+ this.args.remove(this.args.domain)
+ .finally(() => {
+ if (this.isDestroying || this.isDestroyed) {
+ return;
+ }
+ this.removing = false;
+ })
+ }
+
+
+ {{@domain}}
+
+
+}
\ No newline at end of file
diff --git a/assets/javascripts/discourse/components/subscription-domains.gjs b/assets/javascripts/discourse/components/subscription-domains.gjs
new file mode 100644
index 0000000..27c5038
--- /dev/null
+++ b/assets/javascripts/discourse/components/subscription-domains.gjs
@@ -0,0 +1,40 @@
+import Component from "@glimmer/component";
+import { action } from "@ember/object";
+import DButton from "discourse/components/d-button";
+import { tracked } from "@glimmer/tracking";
+import { popupAjaxError } from "discourse/lib/ajax-error";
+import { ajax } from "discourse/lib/ajax";
+import SubscriptionDomain from "./subscription-domain";
+
+export default class SubscriptionDomains extends Component {
+ @tracked domains;
+
+ constructor() {
+ super(...arguments);
+ this.domains = this.args.domains;
+ }
+
+ @action
+ removeDomain(domain) {
+ return ajax('/subscription-server/user-authorizations', {
+ type: 'DELETE',
+ data: {
+ domain
+ }
+ })
+ .catch(popupAjaxError)
+ .then(() => {
+ this.domains = this.domains.filter((d) => (d !== domain));
+ });
+ }
+
+
+
+ {{#each this.domains as |domain|}}
+ -
+
+
+ {{/each}}
+
+
+}
\ No newline at end of file
diff --git a/assets/javascripts/discourse/components/subscription-invoices-btn.gjs b/assets/javascripts/discourse/components/subscription-invoices-btn.gjs
new file mode 100644
index 0000000..b32fba7
--- /dev/null
+++ b/assets/javascripts/discourse/components/subscription-invoices-btn.gjs
@@ -0,0 +1,23 @@
+import Component from "@glimmer/component";
+import { action } from "@ember/object";
+import { inject as service } from "@ember/service";
+import DButton from "discourse/components/d-button";
+import SubscriptionInvoicesModal from "./modal/subscription-invoices";
+
+export default class SubscriptionInvoicesBtn extends Component {
+ @service modal;
+
+ @action
+ showModal() {
+ this.modal.show(SubscriptionInvoicesModal, { model: this.args });
+ }
+
+
+
+
+}
diff --git a/assets/javascripts/discourse/components/subscriptions-banner.hbs b/assets/javascripts/discourse/components/subscriptions-banner.hbs
new file mode 100644
index 0000000..8d15644
--- /dev/null
+++ b/assets/javascripts/discourse/components/subscriptions-banner.hbs
@@ -0,0 +1 @@
+{{text}}
diff --git a/assets/javascripts/discourse/components/subscriptions-banner.js b/assets/javascripts/discourse/components/subscriptions-banner.js
new file mode 100644
index 0000000..a6eaeb5
--- /dev/null
+++ b/assets/javascripts/discourse/components/subscriptions-banner.js
@@ -0,0 +1,16 @@
+import Component from "@ember/component";
+import discourseComputed from "discourse-common/utils/decorators";
+
+export default Component.extend({
+ classNameBindings: [":subscriptions-banner", "showBanner:visible"],
+
+ @discourseComputed("currentPath", "text")
+ showBanner(currentPath, text) {
+ return currentPath.includes('subscribe') && text && text.length > 2;
+ },
+
+ @discourseComputed()
+ text() {
+ return this.siteSettings.custom_wizard_subscription_banner;
+ }
+});
diff --git a/assets/javascripts/discourse/connectors/top-notices/subscriptions-banner-container.hbs b/assets/javascripts/discourse/connectors/top-notices/subscriptions-banner-container.hbs
new file mode 100644
index 0000000..b4f64b0
--- /dev/null
+++ b/assets/javascripts/discourse/connectors/top-notices/subscriptions-banner-container.hbs
@@ -0,0 +1 @@
+{{subscriptions-banner currentPath=currentPath}}
diff --git a/assets/javascripts/discourse/initializers/subscription-server-initializer.js b/assets/javascripts/discourse/initializers/subscription-server-initializer.js
new file mode 100644
index 0000000..61a6746
--- /dev/null
+++ b/assets/javascripts/discourse/initializers/subscription-server-initializer.js
@@ -0,0 +1,106 @@
+import { withPluginApi } from "discourse/lib/plugin-api";
+import discourseComputed from "discourse-common/utils/decorators";
+import { popupAjaxError } from "discourse/lib/ajax-error";
+import { ajax } from "discourse/lib/ajax";
+import { customProducts, productOrder } from '../lib/products';
+
+export default {
+ name: 'subscription-servier-initializer',
+ initialize() {
+ withPluginApi('0.8.30', api => {
+ api.modifyClass('component:payment-plan', {
+ pluginId: 'discourse-subscription-server',
+ classNameBindings: [':btn-pavilion-subscribe', 'selectedClass'],
+ tagName: "div",
+
+ click() {
+ this.clickPlan(this.plan);
+ }
+ });
+
+ api.modifyClass('route:admin-plugins-discourse-subscriptions-coupons', {
+ pluginId: 'discourse-subscription-server',
+
+ afterModel() {
+ const AdminProduct = requirejs("discourse/plugins/discourse-subscriptions/discourse/models/admin-product").default;
+ return AdminProduct.findAll().then(products => {
+ this.set('products', products);
+ });
+ },
+
+ setupController(controller, model) {
+ controller.setProperties({
+ model,
+ products: this.products
+ })
+ }
+ });
+
+ api.modifyClass('controller:admin-plugins-discourse-subscriptions-coupons', {
+ pluginId: 'discourse-subscription-server',
+
+ actions: {
+ createNewCoupon(params) {
+ const data = {
+ promo: params.promo,
+ discount_type: params.discount_type,
+ discount: params.discount,
+ active: params.active,
+ applies_to_products: params.applies_to_products
+ };
+
+ return ajax("/s/admin/coupons", {
+ method: "post",
+ data,
+ })
+ .then(() => {
+ this.send("closeCreateForm");
+ this.send("reloadModel");
+ })
+ .catch(popupAjaxError);
+ }
+ }
+ });
+
+ const couponController = api._lookupContainer('controller:admin-plugins-discourse-subscriptions-coupons');
+ api.modifyClass('component:create-coupon-form', {
+ pluginId: 'discourse-subscription-server',
+
+ @discourseComputed
+ products() {
+ return couponController.get('products');
+ },
+
+ actions: {
+ createNewCoupon() {
+ const createParams = {
+ promo: this.promoCode,
+ discount_type: this.discountType,
+ discount: this.discount,
+ active: this.active,
+ applies_to_products: [this.productId]
+ };
+ this.create(createParams);
+ },
+ },
+ });
+
+ api.modifyClass('route:subscribe-index', {
+ pluginId: 'discourse-subscription-server',
+
+ setupController(controller, model) {
+ const stripeProducts = model;
+ const Product = requirejs("discourse/plugins/discourse-subscriptions/discourse/models/product").default;
+ const nonStripeProducts = customProducts().map((product) => Product.create(product));
+ const products = stripeProducts
+ .concat(nonStripeProducts)
+ .filter(p => (!p.hidden))
+ .sort(function(a,b) {
+ return productOrder.indexOf(a.name) - productOrder.indexOf(b.name);
+ });
+ controller.set('model', products);
+ }
+ });
+ })
+ }
+}
diff --git a/assets/javascripts/discourse/lib/products.js b/assets/javascripts/discourse/lib/products.js
new file mode 100644
index 0000000..090f0e6
--- /dev/null
+++ b/assets/javascripts/discourse/lib/products.js
@@ -0,0 +1,34 @@
+import { helperContext } from "discourse-common/lib/helpers";
+
+const customProducts = () => {
+ const siteSettings = helperContext().siteSettings;
+
+ return [
+ {
+ name: 'Custom Wizard Community',
+ description: `${siteSettings.custom_wizard_community_subscription_description}
`,
+ btnLabel: 'Apply',
+ btnHref: siteSettings.custom_wizard_community_subscription_href,
+ custom: true,
+ },
+ {
+ name: 'Custom Wizard Enterprise',
+ description: `${siteSettings.custom_wizard_enterprise_subscription_description}
`,
+ btnLabel: 'Contact Us',
+ btnHref: siteSettings.custom_wizard_enterprise_subscription_href,
+ custom: true,
+ }
+ ];
+}
+
+const productOrder = [
+ 'Custom Wizard Community',
+ 'Custom Wizard Small Business',
+ 'Custom Wizard Business',
+ 'Custom Wizard Enterprise'
+];
+
+export {
+ customProducts,
+ productOrder
+}
diff --git a/assets/javascripts/discourse/routes/subscribe-alias.js b/assets/javascripts/discourse/routes/subscribe-alias.js
new file mode 100644
index 0000000..8642190
--- /dev/null
+++ b/assets/javascripts/discourse/routes/subscribe-alias.js
@@ -0,0 +1,7 @@
+import Route from "@ember/routing/route";
+
+export default Route.extend({
+ afterModel() {
+ return this.replaceWith("subscribe");
+ }
+});
diff --git a/assets/javascripts/discourse/routes/user-billing-authorizations.js b/assets/javascripts/discourse/routes/user-billing-authorizations.js
new file mode 100644
index 0000000..fefdd59
--- /dev/null
+++ b/assets/javascripts/discourse/routes/user-billing-authorizations.js
@@ -0,0 +1,9 @@
+import Route from "@ember/routing/route";
+
+export default Route.extend({
+ templateName: "user/billing/authorizations",
+
+ model() {
+ return this.modelFor('user');
+ }
+});
diff --git a/assets/javascripts/discourse/subscriptions-route-map.js b/assets/javascripts/discourse/subscriptions-route-map.js
new file mode 100644
index 0000000..0227b0a
--- /dev/null
+++ b/assets/javascripts/discourse/subscriptions-route-map.js
@@ -0,0 +1,3 @@
+export default function () {
+ this.route("subscribeAlias", { path: "/subscribe" });
+}
diff --git a/assets/javascripts/discourse/templates/admin/plugins-discourse-subscriptions-products-show.hbs b/assets/javascripts/discourse/templates/admin/plugins-discourse-subscriptions-products-show.hbs
new file mode 100644
index 0000000..8883530
--- /dev/null
+++ b/assets/javascripts/discourse/templates/admin/plugins-discourse-subscriptions-products-show.hbs
@@ -0,0 +1,175 @@
+{{i18n "discourse_subscriptions.admin.products.title"}}
+
+
+
+
+
+
+ {{input
+ type="text"
+ name="statement_descriptor"
+ value=model.product.statement_descriptor
+ }}
+
+
+ {{i18n
+ "discourse_subscriptions.admin.products.product.statement_descriptor_help"
+ }}
+
+
+
+
+
+
+ {{input
+ type="checkbox"
+ name="repurchaseable"
+ checked=model.product.metadata.repurchaseable
+ }}
+
+
+ {{i18n "discourse_subscriptions.admin.products.product.repurchase_help"}}
+
+
+
+
+
+
+ {{input
+ type="checkbox"
+ name="hidden"
+ checked=model.product.metadata.hidden
+ }}
+
+
+ {{i18n "discourse_subscriptions.admin.products.product.hidden_help"}}
+
+
+
+
+
+
+ {{input type="checkbox" name="active" checked=model.product.active}}
+
+
+ {{i18n "discourse_subscriptions.admin.products.product.active_help"}}
+
+
+
+
+{{#unless model.product.isNew}}
+ {{i18n "discourse_subscriptions.admin.plans.title"}}
+
+
+
+
+ {{i18n "discourse_subscriptions.admin.plans.plan.nickname"}} |
+ {{i18n "discourse_subscriptions.admin.plans.plan.interval"}} |
+ {{i18n "discourse_subscriptions.admin.plans.plan.created_at"}} |
+ {{i18n "discourse_subscriptions.admin.plans.plan.group"}} |
+ {{i18n "discourse_subscriptions.admin.plans.plan.active"}} |
+
+ {{i18n "discourse_subscriptions.admin.plans.plan.amount"}}
+ |
+
+ {{#link-to
+ "adminPlugins.discourse-subscriptions.products.show.plans.show"
+ model.product.id
+ "new"
+ class="btn"
+ }}
+ {{i18n "discourse_subscriptions.admin.plans.operations.add"}}
+ {{/link-to}}
+ |
+
+
+
+ {{#each model.plans as |plan|}}
+
+ {{plan.nickname}} |
+ {{plan.recurring.interval}} |
+ {{format-unix-date plan.created}} |
+ {{plan.metadata.group_name}} |
+ {{plan.active}} |
+
+ {{format-currency plan.currency plan.amountDollars}}
+ |
+
+ {{#link-to
+ "adminPlugins.discourse-subscriptions.products.show.plans.show"
+ model.product.id
+ plan.id
+ class="btn no-text btn-icon"
+ }}
+ {{d-icon "far-edit"}}
+ {{/link-to}}
+ |
+
+ {{else}}
+
+
+
+ {{i18n
+ "discourse_subscriptions.admin.products.product.plan_help"
+ }}
+ |
+
+ {{/each}}
+
+
+
+{{/unless}}
+
+
+ {{d-button label="cancel" action=(action "cancelProduct") icon="times"}}
+
+ {{#if model.product.isNew}}
+ {{d-button
+ label="discourse_subscriptions.admin.products.operations.create"
+ action=(action "createProduct")
+ icon="plus"
+ class="btn btn-primary"
+ }}
+ {{else}}
+ {{d-button
+ label="discourse_subscriptions.admin.products.operations.update"
+ action=(action "updateProduct")
+ icon="check"
+ class="btn btn-primary"
+ }}
+ {{/if}}
+
+
+{{outlet}}
diff --git a/assets/javascripts/discourse/templates/user/billing.hbs b/assets/javascripts/discourse/templates/user/billing.hbs
new file mode 100644
index 0000000..36241a1
--- /dev/null
+++ b/assets/javascripts/discourse/templates/user/billing.hbs
@@ -0,0 +1,29 @@
+{{#d-section
+ pageClass="user-billing"
+ class="user-secondary-navigation"
+ scrollTop="false"
+}}
+
+
+
+
+
+
+
+
+
+
+{{/d-section}}
+
+
diff --git a/assets/javascripts/discourse/templates/user/billing/authorizations.hbs b/assets/javascripts/discourse/templates/user/billing/authorizations.hbs
new file mode 100644
index 0000000..75ad03d
--- /dev/null
+++ b/assets/javascripts/discourse/templates/user/billing/authorizations.hbs
@@ -0,0 +1,13 @@
+
+
+ {{i18n "discourse_subscriptions.user.authorizations.resource"}} |
+ {{i18n "discourse_subscriptions.user.authorizations.products"}} |
+ {{i18n "discourse_subscriptions.user.authorizations.domains"}} |
+ {{i18n "discourse_subscriptions.user.authorizations.domain_limit"}} |
+
+
+ {{#each model.subscription_domains as |data|}}
+
+ {{/each}}
+
+
diff --git a/assets/javascripts/discourse/user-subscriptions-route-map.js b/assets/javascripts/discourse/user-subscriptions-route-map.js
new file mode 100644
index 0000000..47fc38c
--- /dev/null
+++ b/assets/javascripts/discourse/user-subscriptions-route-map.js
@@ -0,0 +1,13 @@
+export default {
+ resource: "user",
+ path: "users/:username",
+ map() {
+ this.route("billing", function () {
+ this.route("payments");
+ this.route("authorizations");
+ this.route("subscriptions", function () {
+ this.route("card", { path: "/card/:stripe-subscription-id" });
+ });
+ });
+ },
+};
diff --git a/assets/stylesheets/common/common.scss b/assets/stylesheets/common/common.scss
new file mode 100644
index 0000000..1ca0a3d
--- /dev/null
+++ b/assets/stylesheets/common/common.scss
@@ -0,0 +1,73 @@
+.btn-pavilion-subscribe {
+ border: 2px solid var(--tertiary);
+ padding: 2em;
+ margin-right: 2em;
+ cursor: pointer;
+ text-align: center;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-direction: column;
+ line-height: unset;
+
+ &.selected {
+ background-color: var(--tertiary);
+ color: var(--secondary);
+ }
+}
+
+.discourse-subscriptions-section-columns {
+ margin: 20px 0;
+ padding: 20px 0;
+}
+
+.product-list {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(48.5%, 1fr));
+ grid-gap: 2em;
+ margin: 2em 0 4em 0;
+
+ .product {
+ margin: 0;
+ width: unset;
+ }
+}
+
+.subscriptions-banner {
+ display: none;
+ padding: 1rem;
+ margin-bottom: 1rem;
+ background-color: rgba(255, 200, 0, 0.25);
+
+ &.visible {
+ display: block;
+ }
+}
+
+.subscription-data {
+ ul {
+ list-style: none;
+ margin: 0;
+ }
+ td {
+ vertical-align: top;
+ }
+}
+
+.subscription-domain {
+ display: flex;
+ gap: 1em;
+ align-items: center;
+
+ .remove-domain {
+ background-color: unset;
+ }
+}
+
+.discourse-subscriptions-invoices-btn {
+ margin-left: auto;
+
+ .d-button-label {
+ color: var(--secondary) !important;
+ }
+}
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 4334ed8..73635f9 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -1,8 +1,37 @@
en:
+ site_settings:
+ custom_wizard_community_subscription_description: Description of the community subscription
+ custom_wizard_enterprise_subscription_description: Description of the enterprise subscription
+ custom_wizard_community_subscription_href: Community subscription href
+ custom_wizard_enterprise_subscription_href: Enterprise subscription href
+ custom_wizard_subscription_banner: Notice to show on subscription routes
js:
discourse_subscriptions:
admin:
products:
product:
plugin_name: Plugin Name
- plugin_name_help: Name of plugin subscription is for. If filled, will generate API Key with subscription.
\ No newline at end of file
+ plugin_name_help: Name of plugin subscription is for. If filled, will generate API Key with subscription.
+ navigation:
+ authorizations: Authorizations
+ user:
+ authorizations:
+ resource: Resource
+ products: Products
+ domains: Domains
+ domain_limit: Domain Limit
+ remove_domain:
+ title: Remove domain
+ invoices:
+ btn:
+ label: "Invoices"
+ title: "Your subscription invoices"
+ modal:
+ title: Your Subscription Invoices
+ description: Click "Customer Portal" to go to Pavilion's Stripe Customer Portal where you can access your invoices. Sign in using %{email}.
+ btn: "Customer Portal"
+ admin:
+ products:
+ product:
+ hidden: Hidden
+ hidden_help: "Don't display the product in the subscriptions index."
\ No newline at end of file
diff --git a/config/routes.rb b/config/routes.rb
index 6700d56..37441fd 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -4,8 +4,10 @@
get '' => 'server#index', defaults: { format: 'json' }
get 'user-subscriptions' => 'user_subscriptions#index', defaults: { format: 'json' }
get 'messages' => 'messages#index', defaults: { format: 'json' }
+ delete 'user-authorizations' => 'user_authorizations#destroy', defaults: { format: 'json' }
end
Discourse::Application.routes.append do
mount ::SubscriptionServer::Engine, at: "/subscription-server"
+ get '/subscribe' => 'discourse_subscriptions/subscribe#index'
end
diff --git a/config/settings.yml b/config/settings.yml
index 2a21e8a..73ef249 100644
--- a/config/settings.yml
+++ b/config/settings.yml
@@ -4,3 +4,18 @@ plugins:
subscription_server_subscriptions:
type: list
default: ''
+ custom_wizard_community_subscription_description:
+ client: true
+ default: 'Custom Wizard Community Subscription Description'
+ custom_wizard_enterprise_subscription_description:
+ client: true
+ default: 'Custom Wizard Enterprise Subscription Description'
+ custom_wizard_community_subscription_href:
+ client: true
+ default: 'https://coop.pavilion.tech/w/community-subscription'
+ custom_wizard_enterprise_subscription_href:
+ client: true
+ default: 'https://calendly.com/book-pavilion/initial-consult'
+ custom_wizard_subscription_banner:
+ client: true
+ default: ''
\ No newline at end of file
diff --git a/coverage/.last_run.json b/coverage/.last_run.json
deleted file mode 100644
index dc24454..0000000
--- a/coverage/.last_run.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "result": {
- "line": 97.75
- }
-}
diff --git a/extensions/discourse_subscriptions_coupons_controller_extension.rb b/extensions/discourse_subscriptions_coupons_controller_extension.rb
new file mode 100644
index 0000000..42c2b8f
--- /dev/null
+++ b/extensions/discourse_subscriptions_coupons_controller_extension.rb
@@ -0,0 +1,29 @@
+module DiscourseSubscriptionsCouponsControllerExtension
+ def create
+ params.require([:promo, :discount_type, :discount, :active, :applies_to_products])
+ begin
+ coupon_params = {
+ duration: 'forever',
+ max_redemptions: params[:max_redemptions] || 1,
+ applies_to: {
+ products: params[:applies_to_products]
+ }
+ }
+
+ case params[:discount_type]
+ when 'amount'
+ coupon_params[:amount_off] = params[:discount].to_i * 100
+ coupon_params[:currency] = SiteSetting.discourse_subscriptions_currency
+ when 'percent'
+ coupon_params[:percent_off] = params[:discount]
+ end
+
+ coupon = ::Stripe::Coupon.create(coupon_params)
+ promo_code = ::Stripe::PromotionCode.create({ coupon: coupon[:id], code: params[:promo] }) if coupon.present?
+
+ render_json_dump promo_code
+ rescue ::Stripe::InvalidRequestError => e
+ render_json_error e.message
+ end
+ end
+end
\ No newline at end of file
diff --git a/extensions/discourse_subscriptions_products_controller_extension.rb b/extensions/discourse_subscriptions_products_controller_extension.rb
new file mode 100644
index 0000000..d56e1c3
--- /dev/null
+++ b/extensions/discourse_subscriptions_products_controller_extension.rb
@@ -0,0 +1,31 @@
+module DiscourseSubscriptionsProductsControllerExtension
+ def show
+ begin
+ product = ::Stripe::Product.retrieve(params[:id])
+
+ if product[:metadata][:hidden].present?
+ product[:metadata][:hidden] = ActiveRecord::Type::Boolean.new.cast(product[:metadata][:hidden])
+ end
+
+ render_json_dump product
+
+ rescue ::Stripe::InvalidRequestError => e
+ render_json_error e.message
+ end
+ end
+
+ private def product_params
+ params.permit!
+
+ {
+ name: params[:name],
+ active: params[:active],
+ statement_descriptor: params[:statement_descriptor],
+ metadata: {
+ description: params.dig(:metadata, :description),
+ repurchaseable: params.dig(:metadata, :repurchaseable),
+ hidden: params.dig(:metadata, :hidden)
+ }
+ }
+ end
+end
\ No newline at end of file
diff --git a/extensions/discourse_subscriptions_subscriber_controller_extension.rb b/extensions/discourse_subscriptions_subscriber_controller_extension.rb
new file mode 100644
index 0000000..e8cdd9e
--- /dev/null
+++ b/extensions/discourse_subscriptions_subscriber_controller_extension.rb
@@ -0,0 +1,22 @@
+module DiscourseSubscriptionsSubscribeControllerExtension
+ private def serialize_product(product)
+ {
+ id: product[:id],
+ name: product[:name],
+ description: PrettyText.cook(product[:metadata][:description]),
+ subscribed: current_user_products.include?(product[:id]),
+ repurchaseable: product[:metadata][:repurchaseable],
+ hidden: ActiveRecord::Type::Boolean.new.cast(product[:metadata][:hidden])
+ }
+ end
+
+ private def serialize_plans(plans)
+ plans[:data].reduce([]) do |result, p|
+ plan = p.to_h
+ if plan[:nickname] != "hidden"
+ result << plan.slice(:id, :unit_amount, :currency, :type, :recurring, :nickname)
+ end
+ result
+ end.sort_by { |plan| plan[:amount] }
+ end
+end
\ No newline at end of file
diff --git a/plugin.rb b/plugin.rb
index 7c94329..a77a944 100644
--- a/plugin.rb
+++ b/plugin.rb
@@ -8,6 +8,7 @@
# contact_emails: development@pavilion.tech
enabled_site_setting :subscription_server_enabled
+register_asset "stylesheets/common/common.scss"
after_initialize do
%w[
@@ -21,10 +22,14 @@
../lib/subscription_server/extensions/user_api_keys_controller.rb
../config/routes.rb
../app/controllers/subscription_server/user_subscriptions_controller.rb
+ ../app/controllers/subscription_server/user_authorizations_controller.rb
../app/controllers/subscription_server/messages_controller.rb
../app/controllers/subscription_server/server_controller.rb
../app/serializers/subscription_server/message_serializer.rb
../app/serializers/subscription_server/subscription_serializer.rb
+ ../extensions/discourse_subscriptions_coupons_controller_extension.rb
+ ../extensions/discourse_subscriptions_products_controller_extension.rb
+ ../extensions/discourse_subscriptions_subscriber_controller_extension.rb
].each do |path|
load File.expand_path(path, __FILE__)
end
@@ -62,6 +67,17 @@
save_custom_fields(true)
end
+ add_to_class(:user, :remove_subscription_domain) do |domain|
+ self._custom_fields.where(
+ "name LIKE '#{SubscriptionServer::UserSubscriptions::DOMAINS_KEY_PREFIX}%'"
+ ).each do |field|
+ value_arr = field.value.split('|')
+ value_arr = value_arr.reject { |d| d === domain }
+ field.value = value_arr.join('|')
+ field.save!
+ end
+ end
+
add_to_class(:user, :subscription_product_domains) do |resource_name, provider_name, product_id|
key = subscription_product_domain_key(resource_name, provider_name, product_id)
product_domains = custom_fields[key]
@@ -94,4 +110,30 @@
result
end
end
+
+ add_to_serializer(:user, :subscription_domains) { user.subscription_domains }
+
+ ## DiscourseSubscription extensions. discourse-subscriptions plugin must be above this plugin in app.yml
+ DiscourseSubscriptions::SubscribeController.prepend DiscourseSubscriptionsSubscribeControllerExtension
+ DiscourseSubscriptions::Admin::CouponsController.prepend DiscourseSubscriptionsCouponsControllerExtension
+ DiscourseSubscriptions::Admin::ProductsController.prepend DiscourseSubscriptionsProductsControllerExtension
+
+ require 'csv'
+ module ::DiscourseSubscriptions
+ def self.class_update_subscriptions_from_csv(path)
+ rows = CSV.read(path)
+ return unless rows.present?
+
+ rows.each do |row|
+ DiscourseSubscriptions::Subscription
+ .joins(:customer)
+ .where("discourse_subscriptions_customers.customer_id = :customer_id AND discourse_subscriptions_subscriptions.external_id = :subscription_id",
+ customer_id: row[0].strip,
+ subscription_id: row[1].strip
+ ).update_all(
+ external_id: row[2].strip
+ )
+ end
+ end
+ end
end
diff --git a/spec/components/subscription_server/user_spec.rb b/spec/components/subscription_server/user_spec.rb
index 6ad6b53..b95eb25 100644
--- a/spec/components/subscription_server/user_spec.rb
+++ b/spec/components/subscription_server/user_spec.rb
@@ -46,4 +46,13 @@
expect(user.subscription_domains.first[:domains]).to eq([domain])
expect(user.subscription_domains.first[:domain_limit]).to eq(1)
end
+
+ it "#remove_subscription_domain" do
+ user.add_subscription_product_domain(domain, resource, provider, product_id)
+ user.add_subscription_product_domain(domain, resource, provider, "prod_12345")
+ user.remove_subscription_domain(domain)
+ user.reload
+ expect(user.custom_fields[user.subscription_product_domain_key(resource, provider, product_id)]).to eq("")
+ expect(user.custom_fields[user.subscription_product_domain_key(resource, provider, "prod_12345")]).to eq("")
+ end
end
diff --git a/spec/requests/subscription_server/user_authorizations_controller_spec.rb b/spec/requests/subscription_server/user_authorizations_controller_spec.rb
new file mode 100644
index 0000000..f9c25d4
--- /dev/null
+++ b/spec/requests/subscription_server/user_authorizations_controller_spec.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+describe SubscriptionServer::UserAuthorizationsController do
+ let(:user) { Fabricate(:user) }
+ let(:provider) { "stripe" }
+ let(:product_id) { "prod_CBTNpi3fqWWkq0" }
+ let(:product_slug) { "business" }
+ let(:resource) { "custom_wizard" }
+ let(:domain) { "demo.pavilion.tech" }
+
+ it "requires a user" do
+ delete "/subscription-server/user-authorizations"
+ expect(response.status).to eq(403)
+ end
+
+ context "with a user" do
+ before do
+ sign_in(user)
+ end
+
+ describe "#destroy" do
+
+ it "requires a domain" do
+ delete "/subscription-server/user-authorizations"
+ expect(response.status).to eq(400)
+ end
+
+ it "removes the domain from all of the user's products" do
+ user.add_subscription_product_domain(domain, resource, provider, product_id)
+ user.add_subscription_product_domain(domain, resource, provider, "prod_12345")
+
+ delete "/subscription-server/user-authorizations", params: { domain: domain }
+ expect(response.status).to eq(200)
+
+ user.reload
+ expect(user.custom_fields[user.subscription_product_domain_key(resource, provider, product_id)]).to eq("")
+ expect(user.custom_fields[user.subscription_product_domain_key(resource, provider, "prod_12345")]).to eq("")
+ end
+ end
+ end
+end
From a379e33ca5963470af225ccb68fd5c73c0a32cda Mon Sep 17 00:00:00 2001
From: Angus McLeod
Date: Wed, 10 Jan 2024 16:39:09 +0100
Subject: [PATCH 2/5] Move client assets to theme component
---
.../components/create-coupon-form.hbs | 47 -----
.../modal/subscription-invoices.hbs | 22 ---
.../components/modal/subscription-invoices.js | 6 -
.../discourse/components/payment-plan.hbs | 12 --
.../discourse/components/product-item.hbs | 37 ----
.../components/subscription-data.gjs | 21 ---
.../components/subscription-domain.gjs | 31 ----
.../components/subscription-domains.gjs | 40 ----
.../components/subscription-invoices-btn.gjs | 23 ---
.../components/subscriptions-banner.hbs | 1 -
.../components/subscriptions-banner.js | 16 --
.../subscriptions-banner-container.hbs | 1 -
.../subscription-server-initializer.js | 106 -----------
assets/javascripts/discourse/lib/products.js | 34 ----
.../discourse/routes/subscribe-alias.js | 7 -
.../routes/user-billing-authorizations.js | 9 -
.../discourse/subscriptions-route-map.js | 3 -
...-discourse-subscriptions-products-show.hbs | 175 ------------------
.../discourse/templates/user/billing.hbs | 29 ---
.../templates/user/billing/authorizations.hbs | 13 --
.../discourse/user-subscriptions-route-map.js | 13 --
assets/stylesheets/common/common.scss | 73 --------
config/locales/client.en.yml | 37 ----
config/settings.yml | 19 +-
plugin.rb | 7 +-
25 files changed, 9 insertions(+), 773 deletions(-)
delete mode 100644 assets/javascripts/discourse/components/create-coupon-form.hbs
delete mode 100644 assets/javascripts/discourse/components/modal/subscription-invoices.hbs
delete mode 100644 assets/javascripts/discourse/components/modal/subscription-invoices.js
delete mode 100644 assets/javascripts/discourse/components/payment-plan.hbs
delete mode 100644 assets/javascripts/discourse/components/product-item.hbs
delete mode 100644 assets/javascripts/discourse/components/subscription-data.gjs
delete mode 100644 assets/javascripts/discourse/components/subscription-domain.gjs
delete mode 100644 assets/javascripts/discourse/components/subscription-domains.gjs
delete mode 100644 assets/javascripts/discourse/components/subscription-invoices-btn.gjs
delete mode 100644 assets/javascripts/discourse/components/subscriptions-banner.hbs
delete mode 100644 assets/javascripts/discourse/components/subscriptions-banner.js
delete mode 100644 assets/javascripts/discourse/connectors/top-notices/subscriptions-banner-container.hbs
delete mode 100644 assets/javascripts/discourse/initializers/subscription-server-initializer.js
delete mode 100644 assets/javascripts/discourse/lib/products.js
delete mode 100644 assets/javascripts/discourse/routes/subscribe-alias.js
delete mode 100644 assets/javascripts/discourse/routes/user-billing-authorizations.js
delete mode 100644 assets/javascripts/discourse/subscriptions-route-map.js
delete mode 100644 assets/javascripts/discourse/templates/admin/plugins-discourse-subscriptions-products-show.hbs
delete mode 100644 assets/javascripts/discourse/templates/user/billing.hbs
delete mode 100644 assets/javascripts/discourse/templates/user/billing/authorizations.hbs
delete mode 100644 assets/javascripts/discourse/user-subscriptions-route-map.js
delete mode 100644 assets/stylesheets/common/common.scss
delete mode 100644 config/locales/client.en.yml
diff --git a/assets/javascripts/discourse/components/create-coupon-form.hbs b/assets/javascripts/discourse/components/create-coupon-form.hbs
deleted file mode 100644
index 741bca3..0000000
--- a/assets/javascripts/discourse/components/create-coupon-form.hbs
+++ /dev/null
@@ -1,47 +0,0 @@
-
diff --git a/assets/javascripts/discourse/components/modal/subscription-invoices.hbs b/assets/javascripts/discourse/components/modal/subscription-invoices.hbs
deleted file mode 100644
index bae5c6a..0000000
--- a/assets/javascripts/discourse/components/modal/subscription-invoices.hbs
+++ /dev/null
@@ -1,22 +0,0 @@
-
- <:body>
- {{i18n "discourse_subscriptions.user.invoices.modal.description" email=this.currentUser.email}}
-
- <:footer>
-
- {{d-icon "external-link-alt"}}
-
- {{i18n "discourse_subscriptions.user.invoices.modal.btn"}}
-
-
-
-
-
\ No newline at end of file
diff --git a/assets/javascripts/discourse/components/modal/subscription-invoices.js b/assets/javascripts/discourse/components/modal/subscription-invoices.js
deleted file mode 100644
index 108c548..0000000
--- a/assets/javascripts/discourse/components/modal/subscription-invoices.js
+++ /dev/null
@@ -1,6 +0,0 @@
-import Component from "@glimmer/component";
-import { inject as service } from "@ember/service";
-
-export default class SubscriptionInvoices extends Component {
- @service currentUser;
-}
diff --git a/assets/javascripts/discourse/components/payment-plan.hbs b/assets/javascripts/discourse/components/payment-plan.hbs
deleted file mode 100644
index 873fa73..0000000
--- a/assets/javascripts/discourse/components/payment-plan.hbs
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
- {{#if recurringPlan}}
- {{i18n (concat "discourse_subscriptions.plans.interval.adverb." plan.recurring.interval)}}
- {{else}}
- {{i18n "discourse_subscriptions.one_time_payment"}}
- {{/if}}
-
-
-
- {{format-currency plan.currency plan.amountDollars}}
-
\ No newline at end of file
diff --git a/assets/javascripts/discourse/components/product-item.hbs b/assets/javascripts/discourse/components/product-item.hbs
deleted file mode 100644
index 33fba67..0000000
--- a/assets/javascripts/discourse/components/product-item.hbs
+++ /dev/null
@@ -1,37 +0,0 @@
-{{product.name}}
-
-
- {{html-safe product.description}}
-
-
-{{#if isLoggedIn}}
-
- {{#if product.custom}}
-
- {{product.btnLabel}}
-
- {{else}}
- {{#if product.repurchaseable}}
- {{#link-to "subscribe.show" product.id class="btn btn-primary"}}
- {{i18n "discourse_subscriptions.subscribe.title"}}
- {{/link-to}}
- {{#if product.subscribed}}
- {{#link-to "user.billing.subscriptions" currentUser.username class="billing-link"}}
- {{i18n "discourse_subscriptions.subscribe.view_past"}}
- {{/link-to}}
- {{/if}}
- {{else}}
- {{#if product.subscribed}}
-
✓ {{i18n "discourse_subscriptions.subscribe.purchased"}}
- {{#link-to "user.billing.subscriptions" currentUser.username class="billing-link"}}
- {{i18n "discourse_subscriptions.subscribe.go_to_billing"}}
- {{/link-to}}
- {{else}}
- {{#link-to "subscribe.show" product.id disabled=product.subscribed class="btn btn-primary"}}
- {{i18n "discourse_subscriptions.subscribe.title"}}
- {{/link-to}}
- {{/if}}
- {{/if}}
- {{/if}}
-
-{{/if}}
diff --git a/assets/javascripts/discourse/components/subscription-data.gjs b/assets/javascripts/discourse/components/subscription-data.gjs
deleted file mode 100644
index 261f07d..0000000
--- a/assets/javascripts/discourse/components/subscription-data.gjs
+++ /dev/null
@@ -1,21 +0,0 @@
-import Component from "@glimmer/component";
-import SubscriptionDomains from "./subscription-domains";
-
-export default class SubscriptionDomain extends Component {
-
-
- {{@data.resource}} |
-
-
- {{#each @data.products as |product|}}
- - {{product}}
- {{/each}}
-
- |
-
-
- |
- {{@data.domain_limit}} |
-
-
-}
diff --git a/assets/javascripts/discourse/components/subscription-domain.gjs b/assets/javascripts/discourse/components/subscription-domain.gjs
deleted file mode 100644
index 2f6392e..0000000
--- a/assets/javascripts/discourse/components/subscription-domain.gjs
+++ /dev/null
@@ -1,31 +0,0 @@
-import Component from "@glimmer/component";
-import { action } from "@ember/object";
-import DButton from "discourse/components/d-button";
-import { tracked } from "@glimmer/tracking";
-
-export default class SubscriptionDomain extends Component {
- @tracked removing;
-
- @action
- removeDomain() {
- this.removing = true;
- this.args.remove(this.args.domain)
- .finally(() => {
- if (this.isDestroying || this.isDestroyed) {
- return;
- }
- this.removing = false;
- })
- }
-
-
- {{@domain}}
-
-
-}
\ No newline at end of file
diff --git a/assets/javascripts/discourse/components/subscription-domains.gjs b/assets/javascripts/discourse/components/subscription-domains.gjs
deleted file mode 100644
index 27c5038..0000000
--- a/assets/javascripts/discourse/components/subscription-domains.gjs
+++ /dev/null
@@ -1,40 +0,0 @@
-import Component from "@glimmer/component";
-import { action } from "@ember/object";
-import DButton from "discourse/components/d-button";
-import { tracked } from "@glimmer/tracking";
-import { popupAjaxError } from "discourse/lib/ajax-error";
-import { ajax } from "discourse/lib/ajax";
-import SubscriptionDomain from "./subscription-domain";
-
-export default class SubscriptionDomains extends Component {
- @tracked domains;
-
- constructor() {
- super(...arguments);
- this.domains = this.args.domains;
- }
-
- @action
- removeDomain(domain) {
- return ajax('/subscription-server/user-authorizations', {
- type: 'DELETE',
- data: {
- domain
- }
- })
- .catch(popupAjaxError)
- .then(() => {
- this.domains = this.domains.filter((d) => (d !== domain));
- });
- }
-
-
-
- {{#each this.domains as |domain|}}
- -
-
-
- {{/each}}
-
-
-}
\ No newline at end of file
diff --git a/assets/javascripts/discourse/components/subscription-invoices-btn.gjs b/assets/javascripts/discourse/components/subscription-invoices-btn.gjs
deleted file mode 100644
index b32fba7..0000000
--- a/assets/javascripts/discourse/components/subscription-invoices-btn.gjs
+++ /dev/null
@@ -1,23 +0,0 @@
-import Component from "@glimmer/component";
-import { action } from "@ember/object";
-import { inject as service } from "@ember/service";
-import DButton from "discourse/components/d-button";
-import SubscriptionInvoicesModal from "./modal/subscription-invoices";
-
-export default class SubscriptionInvoicesBtn extends Component {
- @service modal;
-
- @action
- showModal() {
- this.modal.show(SubscriptionInvoicesModal, { model: this.args });
- }
-
-
-
-
-}
diff --git a/assets/javascripts/discourse/components/subscriptions-banner.hbs b/assets/javascripts/discourse/components/subscriptions-banner.hbs
deleted file mode 100644
index 8d15644..0000000
--- a/assets/javascripts/discourse/components/subscriptions-banner.hbs
+++ /dev/null
@@ -1 +0,0 @@
-{{text}}
diff --git a/assets/javascripts/discourse/components/subscriptions-banner.js b/assets/javascripts/discourse/components/subscriptions-banner.js
deleted file mode 100644
index a6eaeb5..0000000
--- a/assets/javascripts/discourse/components/subscriptions-banner.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import Component from "@ember/component";
-import discourseComputed from "discourse-common/utils/decorators";
-
-export default Component.extend({
- classNameBindings: [":subscriptions-banner", "showBanner:visible"],
-
- @discourseComputed("currentPath", "text")
- showBanner(currentPath, text) {
- return currentPath.includes('subscribe') && text && text.length > 2;
- },
-
- @discourseComputed()
- text() {
- return this.siteSettings.custom_wizard_subscription_banner;
- }
-});
diff --git a/assets/javascripts/discourse/connectors/top-notices/subscriptions-banner-container.hbs b/assets/javascripts/discourse/connectors/top-notices/subscriptions-banner-container.hbs
deleted file mode 100644
index b4f64b0..0000000
--- a/assets/javascripts/discourse/connectors/top-notices/subscriptions-banner-container.hbs
+++ /dev/null
@@ -1 +0,0 @@
-{{subscriptions-banner currentPath=currentPath}}
diff --git a/assets/javascripts/discourse/initializers/subscription-server-initializer.js b/assets/javascripts/discourse/initializers/subscription-server-initializer.js
deleted file mode 100644
index 61a6746..0000000
--- a/assets/javascripts/discourse/initializers/subscription-server-initializer.js
+++ /dev/null
@@ -1,106 +0,0 @@
-import { withPluginApi } from "discourse/lib/plugin-api";
-import discourseComputed from "discourse-common/utils/decorators";
-import { popupAjaxError } from "discourse/lib/ajax-error";
-import { ajax } from "discourse/lib/ajax";
-import { customProducts, productOrder } from '../lib/products';
-
-export default {
- name: 'subscription-servier-initializer',
- initialize() {
- withPluginApi('0.8.30', api => {
- api.modifyClass('component:payment-plan', {
- pluginId: 'discourse-subscription-server',
- classNameBindings: [':btn-pavilion-subscribe', 'selectedClass'],
- tagName: "div",
-
- click() {
- this.clickPlan(this.plan);
- }
- });
-
- api.modifyClass('route:admin-plugins-discourse-subscriptions-coupons', {
- pluginId: 'discourse-subscription-server',
-
- afterModel() {
- const AdminProduct = requirejs("discourse/plugins/discourse-subscriptions/discourse/models/admin-product").default;
- return AdminProduct.findAll().then(products => {
- this.set('products', products);
- });
- },
-
- setupController(controller, model) {
- controller.setProperties({
- model,
- products: this.products
- })
- }
- });
-
- api.modifyClass('controller:admin-plugins-discourse-subscriptions-coupons', {
- pluginId: 'discourse-subscription-server',
-
- actions: {
- createNewCoupon(params) {
- const data = {
- promo: params.promo,
- discount_type: params.discount_type,
- discount: params.discount,
- active: params.active,
- applies_to_products: params.applies_to_products
- };
-
- return ajax("/s/admin/coupons", {
- method: "post",
- data,
- })
- .then(() => {
- this.send("closeCreateForm");
- this.send("reloadModel");
- })
- .catch(popupAjaxError);
- }
- }
- });
-
- const couponController = api._lookupContainer('controller:admin-plugins-discourse-subscriptions-coupons');
- api.modifyClass('component:create-coupon-form', {
- pluginId: 'discourse-subscription-server',
-
- @discourseComputed
- products() {
- return couponController.get('products');
- },
-
- actions: {
- createNewCoupon() {
- const createParams = {
- promo: this.promoCode,
- discount_type: this.discountType,
- discount: this.discount,
- active: this.active,
- applies_to_products: [this.productId]
- };
- this.create(createParams);
- },
- },
- });
-
- api.modifyClass('route:subscribe-index', {
- pluginId: 'discourse-subscription-server',
-
- setupController(controller, model) {
- const stripeProducts = model;
- const Product = requirejs("discourse/plugins/discourse-subscriptions/discourse/models/product").default;
- const nonStripeProducts = customProducts().map((product) => Product.create(product));
- const products = stripeProducts
- .concat(nonStripeProducts)
- .filter(p => (!p.hidden))
- .sort(function(a,b) {
- return productOrder.indexOf(a.name) - productOrder.indexOf(b.name);
- });
- controller.set('model', products);
- }
- });
- })
- }
-}
diff --git a/assets/javascripts/discourse/lib/products.js b/assets/javascripts/discourse/lib/products.js
deleted file mode 100644
index 090f0e6..0000000
--- a/assets/javascripts/discourse/lib/products.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import { helperContext } from "discourse-common/lib/helpers";
-
-const customProducts = () => {
- const siteSettings = helperContext().siteSettings;
-
- return [
- {
- name: 'Custom Wizard Community',
- description: `${siteSettings.custom_wizard_community_subscription_description}
`,
- btnLabel: 'Apply',
- btnHref: siteSettings.custom_wizard_community_subscription_href,
- custom: true,
- },
- {
- name: 'Custom Wizard Enterprise',
- description: `${siteSettings.custom_wizard_enterprise_subscription_description}
`,
- btnLabel: 'Contact Us',
- btnHref: siteSettings.custom_wizard_enterprise_subscription_href,
- custom: true,
- }
- ];
-}
-
-const productOrder = [
- 'Custom Wizard Community',
- 'Custom Wizard Small Business',
- 'Custom Wizard Business',
- 'Custom Wizard Enterprise'
-];
-
-export {
- customProducts,
- productOrder
-}
diff --git a/assets/javascripts/discourse/routes/subscribe-alias.js b/assets/javascripts/discourse/routes/subscribe-alias.js
deleted file mode 100644
index 8642190..0000000
--- a/assets/javascripts/discourse/routes/subscribe-alias.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import Route from "@ember/routing/route";
-
-export default Route.extend({
- afterModel() {
- return this.replaceWith("subscribe");
- }
-});
diff --git a/assets/javascripts/discourse/routes/user-billing-authorizations.js b/assets/javascripts/discourse/routes/user-billing-authorizations.js
deleted file mode 100644
index fefdd59..0000000
--- a/assets/javascripts/discourse/routes/user-billing-authorizations.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import Route from "@ember/routing/route";
-
-export default Route.extend({
- templateName: "user/billing/authorizations",
-
- model() {
- return this.modelFor('user');
- }
-});
diff --git a/assets/javascripts/discourse/subscriptions-route-map.js b/assets/javascripts/discourse/subscriptions-route-map.js
deleted file mode 100644
index 0227b0a..0000000
--- a/assets/javascripts/discourse/subscriptions-route-map.js
+++ /dev/null
@@ -1,3 +0,0 @@
-export default function () {
- this.route("subscribeAlias", { path: "/subscribe" });
-}
diff --git a/assets/javascripts/discourse/templates/admin/plugins-discourse-subscriptions-products-show.hbs b/assets/javascripts/discourse/templates/admin/plugins-discourse-subscriptions-products-show.hbs
deleted file mode 100644
index 8883530..0000000
--- a/assets/javascripts/discourse/templates/admin/plugins-discourse-subscriptions-products-show.hbs
+++ /dev/null
@@ -1,175 +0,0 @@
-{{i18n "discourse_subscriptions.admin.products.title"}}
-
-
-
-{{#unless model.product.isNew}}
- {{i18n "discourse_subscriptions.admin.plans.title"}}
-
-
-
-
- {{i18n "discourse_subscriptions.admin.plans.plan.nickname"}} |
- {{i18n "discourse_subscriptions.admin.plans.plan.interval"}} |
- {{i18n "discourse_subscriptions.admin.plans.plan.created_at"}} |
- {{i18n "discourse_subscriptions.admin.plans.plan.group"}} |
- {{i18n "discourse_subscriptions.admin.plans.plan.active"}} |
-
- {{i18n "discourse_subscriptions.admin.plans.plan.amount"}}
- |
-
- {{#link-to
- "adminPlugins.discourse-subscriptions.products.show.plans.show"
- model.product.id
- "new"
- class="btn"
- }}
- {{i18n "discourse_subscriptions.admin.plans.operations.add"}}
- {{/link-to}}
- |
-
-
-
- {{#each model.plans as |plan|}}
-
- {{plan.nickname}} |
- {{plan.recurring.interval}} |
- {{format-unix-date plan.created}} |
- {{plan.metadata.group_name}} |
- {{plan.active}} |
-
- {{format-currency plan.currency plan.amountDollars}}
- |
-
- {{#link-to
- "adminPlugins.discourse-subscriptions.products.show.plans.show"
- model.product.id
- plan.id
- class="btn no-text btn-icon"
- }}
- {{d-icon "far-edit"}}
- {{/link-to}}
- |
-
- {{else}}
-
-
-
- {{i18n
- "discourse_subscriptions.admin.products.product.plan_help"
- }}
- |
-
- {{/each}}
-
-
-
-{{/unless}}
-
-
- {{d-button label="cancel" action=(action "cancelProduct") icon="times"}}
-
- {{#if model.product.isNew}}
- {{d-button
- label="discourse_subscriptions.admin.products.operations.create"
- action=(action "createProduct")
- icon="plus"
- class="btn btn-primary"
- }}
- {{else}}
- {{d-button
- label="discourse_subscriptions.admin.products.operations.update"
- action=(action "updateProduct")
- icon="check"
- class="btn btn-primary"
- }}
- {{/if}}
-
-
-{{outlet}}
diff --git a/assets/javascripts/discourse/templates/user/billing.hbs b/assets/javascripts/discourse/templates/user/billing.hbs
deleted file mode 100644
index 36241a1..0000000
--- a/assets/javascripts/discourse/templates/user/billing.hbs
+++ /dev/null
@@ -1,29 +0,0 @@
-{{#d-section
- pageClass="user-billing"
- class="user-secondary-navigation"
- scrollTop="false"
-}}
-
-
-
-
-
-
-
-
-
-
-{{/d-section}}
-
-
diff --git a/assets/javascripts/discourse/templates/user/billing/authorizations.hbs b/assets/javascripts/discourse/templates/user/billing/authorizations.hbs
deleted file mode 100644
index 75ad03d..0000000
--- a/assets/javascripts/discourse/templates/user/billing/authorizations.hbs
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
- {{i18n "discourse_subscriptions.user.authorizations.resource"}} |
- {{i18n "discourse_subscriptions.user.authorizations.products"}} |
- {{i18n "discourse_subscriptions.user.authorizations.domains"}} |
- {{i18n "discourse_subscriptions.user.authorizations.domain_limit"}} |
-
-
- {{#each model.subscription_domains as |data|}}
-
- {{/each}}
-
-
diff --git a/assets/javascripts/discourse/user-subscriptions-route-map.js b/assets/javascripts/discourse/user-subscriptions-route-map.js
deleted file mode 100644
index 47fc38c..0000000
--- a/assets/javascripts/discourse/user-subscriptions-route-map.js
+++ /dev/null
@@ -1,13 +0,0 @@
-export default {
- resource: "user",
- path: "users/:username",
- map() {
- this.route("billing", function () {
- this.route("payments");
- this.route("authorizations");
- this.route("subscriptions", function () {
- this.route("card", { path: "/card/:stripe-subscription-id" });
- });
- });
- },
-};
diff --git a/assets/stylesheets/common/common.scss b/assets/stylesheets/common/common.scss
deleted file mode 100644
index 1ca0a3d..0000000
--- a/assets/stylesheets/common/common.scss
+++ /dev/null
@@ -1,73 +0,0 @@
-.btn-pavilion-subscribe {
- border: 2px solid var(--tertiary);
- padding: 2em;
- margin-right: 2em;
- cursor: pointer;
- text-align: center;
- display: flex;
- align-items: center;
- justify-content: center;
- flex-direction: column;
- line-height: unset;
-
- &.selected {
- background-color: var(--tertiary);
- color: var(--secondary);
- }
-}
-
-.discourse-subscriptions-section-columns {
- margin: 20px 0;
- padding: 20px 0;
-}
-
-.product-list {
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(48.5%, 1fr));
- grid-gap: 2em;
- margin: 2em 0 4em 0;
-
- .product {
- margin: 0;
- width: unset;
- }
-}
-
-.subscriptions-banner {
- display: none;
- padding: 1rem;
- margin-bottom: 1rem;
- background-color: rgba(255, 200, 0, 0.25);
-
- &.visible {
- display: block;
- }
-}
-
-.subscription-data {
- ul {
- list-style: none;
- margin: 0;
- }
- td {
- vertical-align: top;
- }
-}
-
-.subscription-domain {
- display: flex;
- gap: 1em;
- align-items: center;
-
- .remove-domain {
- background-color: unset;
- }
-}
-
-.discourse-subscriptions-invoices-btn {
- margin-left: auto;
-
- .d-button-label {
- color: var(--secondary) !important;
- }
-}
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
deleted file mode 100644
index 73635f9..0000000
--- a/config/locales/client.en.yml
+++ /dev/null
@@ -1,37 +0,0 @@
-en:
- site_settings:
- custom_wizard_community_subscription_description: Description of the community subscription
- custom_wizard_enterprise_subscription_description: Description of the enterprise subscription
- custom_wizard_community_subscription_href: Community subscription href
- custom_wizard_enterprise_subscription_href: Enterprise subscription href
- custom_wizard_subscription_banner: Notice to show on subscription routes
- js:
- discourse_subscriptions:
- admin:
- products:
- product:
- plugin_name: Plugin Name
- plugin_name_help: Name of plugin subscription is for. If filled, will generate API Key with subscription.
- navigation:
- authorizations: Authorizations
- user:
- authorizations:
- resource: Resource
- products: Products
- domains: Domains
- domain_limit: Domain Limit
- remove_domain:
- title: Remove domain
- invoices:
- btn:
- label: "Invoices"
- title: "Your subscription invoices"
- modal:
- title: Your Subscription Invoices
- description: Click "Customer Portal" to go to Pavilion's Stripe Customer Portal where you can access your invoices. Sign in using %{email}.
- btn: "Customer Portal"
- admin:
- products:
- product:
- hidden: Hidden
- hidden_help: "Don't display the product in the subscriptions index."
\ No newline at end of file
diff --git a/config/settings.yml b/config/settings.yml
index 73ef249..d7d9bc5 100644
--- a/config/settings.yml
+++ b/config/settings.yml
@@ -1,21 +1,8 @@
plugins:
- subscription_server_enabled: true
+ subscription_server_enabled:
+ client: true
+ default: true
subscription_server_supplier_name: ''
subscription_server_subscriptions:
type: list
- default: ''
- custom_wizard_community_subscription_description:
- client: true
- default: 'Custom Wizard Community Subscription Description'
- custom_wizard_enterprise_subscription_description:
- client: true
- default: 'Custom Wizard Enterprise Subscription Description'
- custom_wizard_community_subscription_href:
- client: true
- default: 'https://coop.pavilion.tech/w/community-subscription'
- custom_wizard_enterprise_subscription_href:
- client: true
- default: 'https://calendly.com/book-pavilion/initial-consult'
- custom_wizard_subscription_banner:
- client: true
default: ''
\ No newline at end of file
diff --git a/plugin.rb b/plugin.rb
index a77a944..d34edef 100644
--- a/plugin.rb
+++ b/plugin.rb
@@ -8,7 +8,6 @@
# contact_emails: development@pavilion.tech
enabled_site_setting :subscription_server_enabled
-register_asset "stylesheets/common/common.scss"
after_initialize do
%w[
@@ -136,4 +135,10 @@ def self.class_update_subscriptions_from_csv(path)
end
end
end
+
+ on(:after_plugin_activation) do
+ Discourse.plugins.sort_by! do |plugin|
+ plugin.name == 'discourse-subscription-server' ? 1 : 0
+ end
+ end
end
From 10154c91c1a6e7e3905b4085c3db7ba1a6112595 Mon Sep 17 00:00:00 2001
From: Angus McLeod
Date: Wed, 10 Jan 2024 16:41:50 +0100
Subject: [PATCH 3/5] Rubocop
---
Gemfile.lock | 49 +++++++++++++++++++
...scriptions_coupons_controller_extension.rb | 3 +-
...criptions_products_controller_extension.rb | 3 +-
...iptions_subscriber_controller_extension.rb | 3 +-
4 files changed, 55 insertions(+), 3 deletions(-)
create mode 100644 Gemfile.lock
diff --git a/Gemfile.lock b/Gemfile.lock
new file mode 100644
index 0000000..ef27598
--- /dev/null
+++ b/Gemfile.lock
@@ -0,0 +1,49 @@
+GEM
+ remote: https://rubygems.org/
+ specs:
+ ast (2.4.2)
+ json (2.6.3)
+ language_server-protocol (3.17.0.3)
+ parallel (1.23.0)
+ parser (3.2.2.4)
+ ast (~> 2.4.1)
+ racc
+ racc (1.7.3)
+ rainbow (3.1.1)
+ regexp_parser (2.8.2)
+ rexml (3.2.6)
+ rubocop (1.57.2)
+ json (~> 2.3)
+ language_server-protocol (>= 3.17.0)
+ parallel (~> 1.10)
+ parser (>= 3.2.2.4)
+ rainbow (>= 2.2.2, < 4.0)
+ regexp_parser (>= 1.8, < 3.0)
+ rexml (>= 3.2.5, < 4.0)
+ rubocop-ast (>= 1.28.1, < 2.0)
+ ruby-progressbar (~> 1.7)
+ unicode-display_width (>= 2.4.0, < 3.0)
+ rubocop-ast (1.30.0)
+ parser (>= 3.2.1.0)
+ rubocop-capybara (2.19.0)
+ rubocop (~> 1.41)
+ rubocop-discourse (3.4.1)
+ rubocop (>= 1.1.0)
+ rubocop-rspec (>= 2.0.0)
+ rubocop-factory_bot (2.24.0)
+ rubocop (~> 1.33)
+ rubocop-rspec (2.25.0)
+ rubocop (~> 1.40)
+ rubocop-capybara (~> 2.17)
+ rubocop-factory_bot (~> 2.22)
+ ruby-progressbar (1.13.0)
+ unicode-display_width (2.5.0)
+
+PLATFORMS
+ arm64-darwin-22
+
+DEPENDENCIES
+ rubocop-discourse
+
+BUNDLED WITH
+ 2.4.13
diff --git a/extensions/discourse_subscriptions_coupons_controller_extension.rb b/extensions/discourse_subscriptions_coupons_controller_extension.rb
index 42c2b8f..094110e 100644
--- a/extensions/discourse_subscriptions_coupons_controller_extension.rb
+++ b/extensions/discourse_subscriptions_coupons_controller_extension.rb
@@ -1,3 +1,4 @@
+# frozen_string_literal: true
module DiscourseSubscriptionsCouponsControllerExtension
def create
params.require([:promo, :discount_type, :discount, :active, :applies_to_products])
@@ -26,4 +27,4 @@ def create
render_json_error e.message
end
end
-end
\ No newline at end of file
+end
diff --git a/extensions/discourse_subscriptions_products_controller_extension.rb b/extensions/discourse_subscriptions_products_controller_extension.rb
index d56e1c3..9fde5c5 100644
--- a/extensions/discourse_subscriptions_products_controller_extension.rb
+++ b/extensions/discourse_subscriptions_products_controller_extension.rb
@@ -1,3 +1,4 @@
+# frozen_string_literal: true
module DiscourseSubscriptionsProductsControllerExtension
def show
begin
@@ -28,4 +29,4 @@ def show
}
}
end
-end
\ No newline at end of file
+end
diff --git a/extensions/discourse_subscriptions_subscriber_controller_extension.rb b/extensions/discourse_subscriptions_subscriber_controller_extension.rb
index e8cdd9e..614d787 100644
--- a/extensions/discourse_subscriptions_subscriber_controller_extension.rb
+++ b/extensions/discourse_subscriptions_subscriber_controller_extension.rb
@@ -1,3 +1,4 @@
+# frozen_string_literal: true
module DiscourseSubscriptionsSubscribeControllerExtension
private def serialize_product(product)
{
@@ -19,4 +20,4 @@ module DiscourseSubscriptionsSubscribeControllerExtension
result
end.sort_by { |plan| plan[:amount] }
end
-end
\ No newline at end of file
+end
From 74886e7b6101e41044753e3d78b92940cf792115 Mon Sep 17 00:00:00 2001
From: Angus McLeod
Date: Wed, 10 Jan 2024 16:44:38 +0100
Subject: [PATCH 4/5] Update Gemfile.lock
---
Gemfile.lock | 1 +
1 file changed, 1 insertion(+)
diff --git a/Gemfile.lock b/Gemfile.lock
index ef27598..4dc8879 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -41,6 +41,7 @@ GEM
PLATFORMS
arm64-darwin-22
+ x86_64-linux
DEPENDENCIES
rubocop-discourse
From bc762eea4c4c19ec4d4e8f5dd4da087ea3ab7283 Mon Sep 17 00:00:00 2001
From: Angus McLeod
Date: Wed, 10 Jan 2024 17:36:14 +0100
Subject: [PATCH 5/5] Update file loading
---
lib/subscription_server/provider.rb | 2 +-
lib/subscription_server/providers/stripe.rb | 4 ++
plugin.rb | 64 +++++++++++----------
3 files changed, 40 insertions(+), 30 deletions(-)
diff --git a/lib/subscription_server/provider.rb b/lib/subscription_server/provider.rb
index 3936c9a..25ca4d4 100644
--- a/lib/subscription_server/provider.rb
+++ b/lib/subscription_server/provider.rb
@@ -6,7 +6,7 @@
class SubscriptionServer::Provider
attr_reader :user
- def initialize(user)
+ def initialize(user = nil)
@user = user
end
diff --git a/lib/subscription_server/providers/stripe.rb b/lib/subscription_server/providers/stripe.rb
index 5da8e7a..47309c9 100644
--- a/lib/subscription_server/providers/stripe.rb
+++ b/lib/subscription_server/providers/stripe.rb
@@ -45,4 +45,8 @@ def subscriptions(product_ids, resource_name)
result
end
end
+
+ def self.discourse_subscriptions_installed?
+ new.discourse_subscriptions_installed?
+ end
end
diff --git a/plugin.rb b/plugin.rb
index d34edef..9420fe2 100644
--- a/plugin.rb
+++ b/plugin.rb
@@ -9,6 +9,13 @@
enabled_site_setting :subscription_server_enabled
+DiscourseEvent.on(:after_plugin_activation) do
+ sorted_pugins = Discourse.plugins.sort_by do |p|
+ p&.name == 'discourse-subscription-server' ? 1 : 0
+ end
+ Discourse.instance_variable_set(:@plugins, sorted_pugins)
+end
+
after_initialize do
%w[
../lib/subscription_server/engine.rb
@@ -26,9 +33,6 @@
../app/controllers/subscription_server/server_controller.rb
../app/serializers/subscription_server/message_serializer.rb
../app/serializers/subscription_server/subscription_serializer.rb
- ../extensions/discourse_subscriptions_coupons_controller_extension.rb
- ../extensions/discourse_subscriptions_products_controller_extension.rb
- ../extensions/discourse_subscriptions_subscriber_controller_extension.rb
].each do |path|
load File.expand_path(path, __FILE__)
end
@@ -112,33 +116,35 @@
add_to_serializer(:user, :subscription_domains) { user.subscription_domains }
- ## DiscourseSubscription extensions. discourse-subscriptions plugin must be above this plugin in app.yml
- DiscourseSubscriptions::SubscribeController.prepend DiscourseSubscriptionsSubscribeControllerExtension
- DiscourseSubscriptions::Admin::CouponsController.prepend DiscourseSubscriptionsCouponsControllerExtension
- DiscourseSubscriptions::Admin::ProductsController.prepend DiscourseSubscriptionsProductsControllerExtension
-
- require 'csv'
- module ::DiscourseSubscriptions
- def self.class_update_subscriptions_from_csv(path)
- rows = CSV.read(path)
- return unless rows.present?
-
- rows.each do |row|
- DiscourseSubscriptions::Subscription
- .joins(:customer)
- .where("discourse_subscriptions_customers.customer_id = :customer_id AND discourse_subscriptions_subscriptions.external_id = :subscription_id",
- customer_id: row[0].strip,
- subscription_id: row[1].strip
- ).update_all(
- external_id: row[2].strip
- )
- end
+ if SubscriptionServer::Stripe.discourse_subscriptions_installed?
+ %w[
+ ../extensions/discourse_subscriptions_coupons_controller_extension.rb
+ ../extensions/discourse_subscriptions_products_controller_extension.rb
+ ../extensions/discourse_subscriptions_subscriber_controller_extension.rb
+ ].each do |path|
+ load File.expand_path(path, __FILE__)
end
- end
-
- on(:after_plugin_activation) do
- Discourse.plugins.sort_by! do |plugin|
- plugin.name == 'discourse-subscription-server' ? 1 : 0
+ DiscourseSubscriptions::SubscribeController.prepend DiscourseSubscriptionsSubscribeControllerExtension
+ DiscourseSubscriptions::Admin::CouponsController.prepend DiscourseSubscriptionsCouponsControllerExtension
+ DiscourseSubscriptions::Admin::ProductsController.prepend DiscourseSubscriptionsProductsControllerExtension
+
+ require 'csv'
+ module ::DiscourseSubscriptions
+ def self.class_update_subscriptions_from_csv(path)
+ rows = CSV.read(path)
+ return unless rows.present?
+
+ rows.each do |row|
+ DiscourseSubscriptions::Subscription
+ .joins(:customer)
+ .where("discourse_subscriptions_customers.customer_id = :customer_id AND discourse_subscriptions_subscriptions.external_id = :subscription_id",
+ customer_id: row[0].strip,
+ subscription_id: row[1].strip
+ ).update_all(
+ external_id: row[2].strip
+ )
+ end
+ end
end
end
end