1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2024-11-28 09:24:24 +01:00

configure the plans module from the admin UI

This commit is contained in:
Sylvain 2020-05-26 15:39:28 +02:00
parent 6cc6bba7ce
commit 537743a740
29 changed files with 47 additions and 49 deletions

View File

@ -81,8 +81,6 @@ angular.module('application', ['ngCookies', 'ngResource', 'ngSanitize', 'ui.rout
$state.prevParams = fromParams;
});
// Global config: if true, the whole 'Plans & Subscriptions' feature will be disabled in the application
$rootScope.fablabWithoutPlans = Fablab.withoutPlans;
// Global config: if true, all payments will be disabled in the application for the members (only admins will be able to proceed reservations)
$rootScope.fablabWithoutOnlinePayment = Fablab.withoutOnlinePayment;
// Global config: if true, no invoices will be generated

View File

@ -179,7 +179,7 @@ Application.Controllers.controller('StatisticsController', ['$scope', '$state',
*/
$scope.hiddenTab = function (tab) {
if (tab.table) {
if ((tab.es_type_key === 'subscription') && $rootScope.fablabWithoutPlans) {
if ((tab.es_type_key === 'subscription') && !$rootScope.plansModule) {
return true;
} else return (tab.es_type_key === 'space') && !$rootScope.spacesModule;
} else {

View File

@ -58,7 +58,7 @@ Application.Controllers.controller('MainNavController', ['$scope', function ($sc
];
if (!Fablab.withoutPlans) {
if ($scope.plansModule) {
$scope.navLinks.push({
state: 'app.public.plans',
linkText: 'app.public.common.subscriptions',

View File

@ -37,15 +37,17 @@ angular.module('application.router', ['ui.router'])
logoFile: ['CustomAsset', function (CustomAsset) { return CustomAsset.get({ name: 'logo-file' }).$promise; }],
logoBlackFile: ['CustomAsset', function (CustomAsset) { return CustomAsset.get({ name: 'logo-black-file' }).$promise; }],
sharedTranslations: ['Translations', function (Translations) { return Translations.query(['app.shared', 'app.public.common']).$promise; }],
spacesModulePromise: ['Setting', function (Setting) { return Setting.get({ name: 'spaces_module' }).$promise; }]
spacesModulePromise: ['Setting', function (Setting) { return Setting.get({ name: 'spaces_module' }).$promise; }],
plansModulePromise: ['Setting', function (Setting) { return Setting.get({ name: 'plans_module' }).$promise; }]
},
onEnter: ['$rootScope', 'logoFile', 'logoBlackFile', 'spacesModulePromise', 'CSRF', function ($rootScope, logoFile, logoBlackFile, spacesModulePromise, CSRF) {
onEnter: ['$rootScope', 'logoFile', 'logoBlackFile', 'spacesModulePromise', 'plansModulePromise', 'CSRF', function ($rootScope, logoFile, logoBlackFile, spacesModulePromise, plansModulePromise, CSRF) {
// Retrieve Anti-CSRF tokens from cookies
CSRF.setMetaTags();
// Application logo
$rootScope.logo = logoFile.custom_asset;
$rootScope.logoBlack = logoBlackFile.custom_asset;
$rootScope.spacesModule = (spacesModulePromise.setting.value === 'true');
$rootScope.plansModule = (plansModulePromise.setting.value === 'true');
}]
})
.state('app.public', {
@ -512,7 +514,7 @@ angular.module('application.router', ['ui.router'])
// pricing
.state('app.public.plans', {
url: '/plans',
abstract: Fablab.withoutPlans,
abstract: !Fablab.plansModule,
views: {
'main@': {
templateUrl: '<%= asset_path "plans/index.html.erb" %>',
@ -1028,7 +1030,7 @@ angular.module('application.router', ['ui.router'])
'space_explications_alert', 'booking_window_start', 'booking_window_end', 'events_in_calendar', \
'booking_move_enable', 'booking_move_delay', 'booking_cancel_enable', \
'booking_cancel_delay', 'main_color', 'secondary_color', 'spaces_module', \
'fablab_name', 'name_genre', 'reminder_enable', \
'fablab_name', 'name_genre', 'reminder_enable', 'plans_module', \
'reminder_delay', 'visibility_yearly', 'visibility_others', \
'display_name_enable', 'machines_sort_by', 'fab_analytics', \
'link_name', 'home_content', 'home_css', 'phone_required']` }).$promise;

View File

@ -60,7 +60,7 @@
</form>
</uib-tab>
<uib-tab heading="{{ 'app.admin.members_edit.subscription' | translate }}" ng-if="!fablabWithoutPlans">
<uib-tab heading="{{ 'app.admin.members_edit.subscription' | translate }}" ng-if="plansModule">
<section class="panel panel-default bg-light m-lg">

View File

@ -25,7 +25,7 @@
<a class="btn btn-default" ng-href="api/members/export_members.xlsx" target="export-frame" ng-click="alertExport('members')">
<i class="fa fa-file-excel-o"></i> {{ 'app.admin.members.members' | translate }}
</a>
<a class="btn btn-default" ng-href="api/members/export_subscriptions.xlsx" target="export-frame" ng-if="!fablabWithoutPlans" ng-click="alertExport('subscriptions')">
<a class="btn btn-default" ng-href="api/members/export_subscriptions.xlsx" target="export-frame" ng-if="plansModule" ng-click="alertExport('subscriptions')">
<i class="fa fa-file-excel-o"></i> {{ 'app.admin.members.subscriptions' | translate }}
</a>
<a class="btn btn-default" ng-href="api/members/export_reservations.xlsx" target="export-frame" ng-click="alertExport('reservations')">

View File

@ -1,9 +1,8 @@
<h2 translate>{{ 'app.admin.pricing.list_of_the_subscription_plans' }}</h2>
<div ng-show="fablabWithoutPlans" class="alert alert-warning m-t">
{{ 'app.admin.pricing.beware_the_subscriptions_are_disabled_on_this_application' | translate }}
{{ 'app.admin.pricing.you_can_create_some_but_they_wont_be_available_until_the_project_is_redeployed_by_the_server_manager' | translate }}
<br>{{ 'app.admin.pricing.for_safety_reasons_please_dont_create_subscriptions_if_you_dont_want_intend_to_use_them_later' | translate }}
<div ng-hide="plansModule"
class="alert alert-warning m-t"
ng-bind-html="'app.admin.pricing.disabled_plans_info_html' | translate">
</div>
<div class="m-t-lg">

View File

@ -364,5 +364,15 @@
yes-label="app.shared.buttons.yes"
no-label="app.shared.buttons.no"></boolean-setting>
</div>
<div class="row">
<h3 class="m-l" translate>{{ 'app.admin.settings.plans' }}</h3>
<p class="alert alert-warning m-h-md" ng-bind-html="'app.admin.settings.plans_info_html' | translate"></p>
<boolean-setting name="plans_module"
settings="allSettings"
label="app.admin.settings.enable_plans"
classes="m-l"
yes-label="app.shared.buttons.yes"
no-label="app.shared.buttons.no"></boolean-setting>
</div>
</div>
</div>

View File

@ -102,7 +102,7 @@
</form>
<uib-tabset justified="true">
<uib-tab ng-repeat="stat in statistics" heading="{{stat.label}}" select="setActiveTab(stat)" ng-if="stat.graph && !(stat.es_type_key == 'subscription' && fablabWithoutPlans)" class="row">
<uib-tab ng-repeat="stat in statistics" heading="{{stat.label}}" select="setActiveTab(stat)" ng-if="stat.graph && !(stat.es_type_key == 'subscription' && plansModule)" class="row">
<div ng-if="stat.graph.chart_type == 'discreteBarChart'">
<div id="rankingFilters">

View File

@ -34,7 +34,7 @@
<button class="btn btn-success m-t" ng-click="selectGroup()">Changer mon groupe</button>
</div>
</div>
<div ng-hide="fablabWithoutPlans">
<div ng-show="plansModule">
<h3 class="text-u-c" translate>{{ 'app.logged.dashboard.settings.subscription' }}</h3>
<div ng-show="user.subscribed_plan">
<uib-alert type="warning">

View File

@ -19,7 +19,7 @@
<div class="row no-gutter machine-reserve">
<div class="col-sm-12 col-md-12 col-lg-9">
<div ui-calendar="calendarConfig" ng-model="eventSources" calendar="calendar" class="wrapper-lg" ng-show="!plansAreShown"></div>
<ng-include ng-if="!fablabWithoutPlans" src="'<%= asset_path "plans/_plan.html" %>'"></ng-include>
<ng-include ng-if="plansModule" src="'<%= asset_path "plans/_plan.html" %>'"></ng-include>
</div>

View File

@ -52,7 +52,7 @@
<coupon show="isSlotsValid() && (!modePlans || selectedPlan)" coupon="coupon.applied" total="totalNoCoupon" user-id="{{user.id}}"></coupon>
<div ng-hide="fablabWithoutPlans">
<div ng-show="plansModule">
<div ng-if="isSlotsValid() && !user.subscribed_plan" ng-show="!modePlans">
<p class="font-sbold text-base l-h-2x" translate>{{ 'app.shared.cart.to_benefit_from_attractive_prices' }}</p>
<div><button class="btn btn-warning-full rounded btn-block text-xs" ng-click="showPlans()" translate>{{ 'app.shared.cart.view_our_subscriptions' }}</button></div>

View File

@ -17,7 +17,7 @@
<div class="row no-gutter training-reserve">
<div class="col-sm-12 col-md-12 col-lg-9">
<div ui-calendar="calendarConfig" ng-model="eventSources" calendar="calendar" class="wrapper-lg" ng-show="!plansAreShown"></div>
<ng-include ng-if="!fablabWithoutPlans" src="'<%= asset_path "plans/_plan.html" %>'"></ng-include>
<ng-include ng-if="plansModule" src="'<%= asset_path "plans/_plan.html" %>'"></ng-include>
</div>

View File

@ -27,7 +27,7 @@
<div class="row no-gutter training-reserve">
<div class="col-sm-12 col-md-12 col-lg-9">
<div ui-calendar="calendarConfig" ng-model="eventSources" calendar="calendar" class="wrapper-lg" ng-show="!plansAreShown"></div>
<ng-include ng-if="!fablabWithoutPlans" src="'<%= asset_path "plans/_plan.html" %>'"></ng-include>
<ng-include ng-if="plansModule" src="'<%= asset_path "plans/_plan.html" %>'"></ng-include>
</div>

View File

@ -2,8 +2,6 @@
# API Controller for resources of type Availability
class API::AvailabilitiesController < API::ApiController
include FablabConfiguration
before_action :authenticate_user!, except: [:public]
before_action :set_availability, only: %i[show update reservations lock]
before_action :define_max_visibility, only: %i[machine trainings spaces]

View File

@ -1,5 +0,0 @@
module FablabConfiguration
def fablab_plans_deactivated?
Rails.application.secrets.fablab_without_plans
end
end

View File

@ -81,7 +81,8 @@ class Setting < ApplicationRecord
book_overlapping_slots
slot_duration
events_in_calendar
spaces_module] }
spaces_module
plans_module] }
def value
last_value = history_values.order(HistoryValue.arel_table['created_at'].desc).first
last_value&.value

View File

@ -2,9 +2,8 @@
# Check the access policies for API::SubscriptionsController
class SubscriptionPolicy < ApplicationPolicy
include FablabConfiguration
def create?
!fablab_plans_deactivated? && (user.admin? || (user.manager? && record.user_id != user.id) || record.price.zero?)
Setting.get('plans_module') && (user.admin? || (user.manager? && record.user_id != user.id) || record.price.zero?)
end
def show?

View File

@ -39,7 +39,7 @@ class HealthService
admins: User.admins.count,
availabilities: last_week_availabilities,
reservations: last_week_new_reservations,
plans: !Rails.application.secrets.fablab_without_plans,
plans: Settings.get('plans_module'),
spaces: Setting.get('spaces_module'),
online_payment: !Rails.application.secrets.fablab_without_online_payments,
invoices: !Rails.application.secrets.fablab_without_invoices,

View File

@ -23,7 +23,7 @@
<script type="text/javascript">
var Fablab = Fablab || {};
Fablab.withoutPlans = ('<%= Rails.application.secrets.fablab_without_plans %>' === 'true');
Fablab.plansModule = ('<%= Setting.get('plans_module') %>' === 'true');
Fablab.spacesModule = ('<%= Setting.get('spaces_module') %>' === 'true');
Fablab.withoutOnlinePayment = ('<%= Rails.application.secrets.fablab_without_online_payments %>' === 'true');
Fablab.withoutInvoices = ('<%= Rails.application.secrets.fablab_without_invoices %>' === 'true');

View File

@ -270,6 +270,7 @@ en:
subscriptions: "Subscriptions"
trainings: "Trainings"
list_of_the_subscription_plans: "List of the subscription plans"
disabled_plans_info_html: "<p><strong>Warning:</strong> the subscriptions are disabled on this application.</p><p>You can still create some, but they won't be available until the activation of the plans module, from the « Customization » section.</p>"
beware_the_subscriptions_are_disabled_on_this_application: "Beware, the subscriptions are disabled on this application."
you_can_create_some_but_they_wont_be_available_until_the_project_is_redeployed_by_the_server_manager: "You can create some but they won't be available until the project is redeployed by the server manager."
for_safety_reasons_please_dont_create_subscriptions_if_you_dont_want_intend_to_use_them_later: "For safety reasons, please don't create subscriptions if you don't intend to use them later."
@ -1045,6 +1046,10 @@ en:
spaces_info_html: "<p>A space can be, for example, a woodshop or a meeting room. Their particularity is that they can be booked by several people at the same time.</p><p><strong>Warning:</strong> It is not recommended to disable spaces if at least one space reservation was made on the system.</p>"
enable_spaces: "Enable the spaces"
spaces_module: "spaces module"
plans: "Plans"
plans_info_html: "<p>Subscriptions provide a way to segment your prices and provide benefits to regular users.</p><p><strong>Warning:</strong> It is not recommended to disable plans if at least one subscription is active on the system.</p>"
enable_plans: "Enable the plans"
plans_module: "plans module"
sort_by:
default: "Default"
name: "Name"

View File

@ -270,9 +270,7 @@ fr:
subscriptions: "Abonnements"
trainings: "Formations"
list_of_the_subscription_plans: "Liste des formules d'abonnements"
beware_the_subscriptions_are_disabled_on_this_application: "Attention, les abonnements sont désactivés sur cette application."
you_can_create_some_but_they_wont_be_available_until_the_project_is_redeployed_by_the_server_manager: "Vous pouvez tout de même en créer mais ils ne seront disponibles qu'après un redéploiement du projet par le responsable du serveur."
for_safety_reasons_please_dont_create_subscriptions_if_you_dont_want_intend_to_use_them_later: "Pour des raisons de sécurité, veuillez ne pas créer d'abonnements si vous ne comptez pas les utiliser par la suite."
disabled_plans_info_html: "<p><strong>Attention :</strong> les abonnements sont désactivés sur cette application.</p><p>Vous pouvez tout de même en créer mais ils ne seront disponibles qu'après l'activation du module abonnements depuis la section « Personnalisation ».</p>"
add_a_new_subscription_plan: "Ajouter une nouvelle formule d'abonnement"
type: "Type"
partner: "Partenaire"
@ -1045,6 +1043,10 @@ fr:
spaces_info_html: "<p>Un espace peut-être, par exemple, un atelier bois ou une salle de réunion. Leur particularité est qu'ils peuvent être réservés par plusieurs personnes en même temps.</p><p><strong>Attention :</strong> Il n'est pas recommandé de désactiver les espaces si au moins une réservation est en cours sur un espace.</p>"
enable_spaces: "Activer les espaces"
spaces_module: "module espace"
plans: "Abonnements"
plans_info_html: "<p>Les abonnements offrent un moyen de segmenter vos tarifs et d'accorder des avantages aux utilisateurs réguliers.</p><p><strong>Attention :</strong> Il n'est pas recommandé de désactiver les abonnements si au moins un abonnement est en cours.</p>"
enable_plans: "Activer les abonnements"
plans_module: "module abonnements"
sort_by:
default: "Défaut"
name: "Nom"

View File

@ -16,7 +16,6 @@ development:
stripe_publishable_key: <%= ENV["STRIPE_PUBLISHABLE_KEY"] %>
stripe_currency: <%= ENV["STRIPE_CURRENCY"] %>
disqus_shortname: <%= ENV["DISQUS_SHORTNAME"] %>
fablab_without_plans: <%= ENV["FABLAB_WITHOUT_PLANS"] %>
fablab_without_online_payments: <%= ENV["FABLAB_WITHOUT_ONLINE_PAYMENT"] %>
fablab_without_invoices: <%= ENV["FABLAB_WITHOUT_INVOICES"] %>
fablab_without_wallet: <%= ENV["FABLAB_WITHOUT_WALLET"] %>
@ -59,7 +58,6 @@ test:
stripe_publishable_key: <%= ENV["STRIPE_PUBLISHABLE_KEY"] %>
stripe_currency: usd
disqus_shortname: fablab-sleede
fablab_without_plans: false
fablab_without_online_payments: false
fablab_without_invoices: false
fablab_without_wallet: false
@ -102,7 +100,6 @@ staging:
stripe_publishable_key: <%= ENV["STRIPE_PUBLISHABLE_KEY"] %>
stripe_currency: <%= ENV["STRIPE_CURRENCY"] %>
disqus_shortname: <%= ENV["DISQUS_SHORTNAME"] %>
fablab_without_plans: <%= ENV["FABLAB_WITHOUT_PLANS"] %>
fablab_without_online_payments: <%= ENV["FABLAB_WITHOUT_ONLINE_PAYMENT"] %>
fablab_without_invoices: <%= ENV["FABLAB_WITHOUT_INVOICES"] %>
fablab_without_wallet: <%= ENV["FABLAB_WITHOUT_WALLET"] %>
@ -156,7 +153,6 @@ production:
stripe_publishable_key: <%= ENV["STRIPE_PUBLISHABLE_KEY"] %>
stripe_currency: <%= ENV["STRIPE_CURRENCY"] %>
disqus_shortname: <%= ENV["DISQUS_SHORTNAME"] %>
fablab_without_plans: <%= ENV["FABLAB_WITHOUT_PLANS"] %>
fablab_without_online_payments: <%= ENV["FABLAB_WITHOUT_ONLINE_PAYMENT"] %>
fablab_without_invoices: <%= ENV["FABLAB_WITHOUT_INVOICES"] %>
fablab_without_wallet: <%= ENV["FABLAB_WITHOUT_WALLET"] %>

View File

@ -81,12 +81,6 @@ So set this setting carefully before starting the application for the first time
When payments are done on the platform, an invoice will be generated as a PDF file.
The PDF file name will be of the form "(INVOICE_PREFIX) - (invoice ID) _ (invoice date) .pdf".
<a name="FABLAB_WITHOUT_PLANS"></a>
FABLAB_WITHOUT_PLANS
If set to 'true', the subscription plans will be fully disabled and invisible in the application.
It is not recommended to disable plans if at least one subscription was took on the platform.
<a name="FABLAB_WITHOUT_ONLINE_PAYMENT"></a>
FABLAB_WITHOUT_ONLINE_PAYMENT

View File

@ -16,7 +16,6 @@ STRIPE_CURRENCY=eur
INVOICE_PREFIX=Demo-FabLab_facture
# FabLab optional modules
FABLAB_WITHOUT_PLANS=false
FABLAB_WITHOUT_ONLINE_PAYMENT=false
FABLAB_WITHOUT_INVOICES=false
PHONE_REQUIRED=true

View File

@ -111,7 +111,8 @@ namespace :fablab do
%w[_ BOOK_SLOT_AT_SAME_TIME book_overlapping_slots true],
%w[_ SLOT_DURATION slot_duration 60],
%w[_ EVENTS_IN_CALENDAR events_in_calendar false],
%w[! FABLAB_WITHOUT_SPACES spaces_module true]
%w[! FABLAB_WITHOUT_SPACES spaces_module true],
%w[! FABLAB_WITHOUT_PLANS plans_module false]
]
mapping.each do |m|

View File

@ -9,7 +9,6 @@ STRIPE_PUBLISHABLE_KEY=
STRIPE_CURRENCY=eur
INVOICE_PREFIX=Demo-FabLab_facture
FABLAB_WITHOUT_PLANS=false
FABLAB_WITHOUT_ONLINE_PAYMENT=false
FABLAB_WITHOUT_INVOICES=false
PHONE_REQUIRED=false

View File

@ -234,7 +234,7 @@ configure_env_file()
local doc variables secret
doc=$(\curl -sSL https://raw.githubusercontent.com/sleede/fab-manager/master/doc/environment.md)
variables=(STRIPE_API_KEY STRIPE_PUBLISHABLE_KEY STRIPE_CURRENCY INVOICE_PREFIX FABLAB_WITHOUT_PLANS FABLAB_WITHOUT_ONLINE_PAYMENT FABLAB_WITHOUT_INVOICES FABLAB_WITHOUT_WALLET \
variables=(STRIPE_API_KEY STRIPE_PUBLISHABLE_KEY STRIPE_CURRENCY INVOICE_PREFIX FABLAB_WITHOUT_ONLINE_PAYMENT FABLAB_WITHOUT_INVOICES FABLAB_WITHOUT_WALLET \
USER_CONFIRMATION_NEEDED_TO_SIGN_IN DEFAULT_MAIL_FROM DELIVERY_METHOD DEFAULT_HOST DEFAULT_PROTOCOL SMTP_ADDRESS SMTP_PORT SMTP_USER_NAME SMTP_PASSWORD SMTP_AUTHENTICATION \
SMTP_ENABLE_STARTTLS_AUTO SMTP_OPENSSL_VERIFY_MODE SMTP_TLS RECAPTCHA_SITE_KEY RECAPTCHA_SECRET_KEY DISQUS_SHORTNAME TWITTER_NAME \
FACEBOOK_APP_ID LOG_LEVEL ALLOWED_EXTENSIONS ALLOWED_MIME_TYPES MAX_IMAGE_SIZE MAX_CAO_SIZE MAX_IMPORT_SIZE DISK_SPACE_MB_ALERT FEATURE_TOUR_DISPLAY \