mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-02-07 01:54:16 +01:00
Ability to disable the trainings module
This commit is contained in:
parent
f50f5a4058
commit
9d747db095
@ -1,12 +1,14 @@
|
|||||||
# Changelog Fab-manager
|
# Changelog Fab-manager
|
||||||
|
|
||||||
## Next release
|
## Next release
|
||||||
|
- Ability to disable the trainings module
|
||||||
- Prevent showing error message when testing for old versions during upgrade
|
- Prevent showing error message when testing for old versions during upgrade
|
||||||
- In the email notification, sent to admins on account creation, show the group of the user
|
- In the email notification, sent to admins on account creation, show the group of the user
|
||||||
- More explanations in the setup script
|
- More explanations in the setup script
|
||||||
- Send pre-compressed assets to the browsers instead of the regular ones
|
- Send pre-compressed assets to the browsers instead of the regular ones
|
||||||
- Fix a bug: subscriptions tab is selected by default in statistics, even if the module is disabled
|
- Fix a bug: subscriptions tab is selected by default in statistics, even if the module is disabled
|
||||||
- [TODO DEPLOY] `\curl -sSL https://raw.githubusercontent.com/sleede/fab-manager/master/scripts/nginx-packs-directive.sh | bash`
|
- [TODO DEPLOY] `\curl -sSL https://raw.githubusercontent.com/sleede/fab-manager/master/scripts/nginx-packs-directive.sh | bash`
|
||||||
|
- [TODO DEPLOY] `rails db:seed`
|
||||||
|
|
||||||
## v4.7.5 2021 March 08
|
## v4.7.5 2021 March 08
|
||||||
- Fix a bug: unable to compile the assets during the upgrade, if the env file has some whitespaces around the equal sign
|
- Fix a bug: unable to compile the assets during the upgrade, if the env file has some whitespaces around the equal sign
|
||||||
|
@ -124,7 +124,8 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
|
|||||||
*/
|
*/
|
||||||
$scope.hiddenTab = function (tab) {
|
$scope.hiddenTab = function (tab) {
|
||||||
if (tab.graph) {
|
if (tab.graph) {
|
||||||
return !((tab.es_type_key === 'subscription') && !$rootScope.modules.plans);
|
return !((tab.es_type_key === 'subscription' && !$rootScope.modules.plans) ||
|
||||||
|
(tab.es_type_key === 'training' && !$rootScope.modules.trainings));
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
@ -111,7 +111,7 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
|
|||||||
* @returns {float}
|
* @returns {float}
|
||||||
*/
|
*/
|
||||||
$scope.findTrainingsPricing = function (trainingsPricings, trainingId, groupId) {
|
$scope.findTrainingsPricing = function (trainingsPricings, trainingId, groupId) {
|
||||||
for (let trainingsPricing of Array.from(trainingsPricings)) {
|
for (const trainingsPricing of Array.from(trainingsPricings)) {
|
||||||
if ((trainingsPricing.training_id === trainingId) && (trainingsPricing.group_id === groupId)) {
|
if ((trainingsPricing.training_id === trainingId) && (trainingsPricing.group_id === groupId)) {
|
||||||
return trainingsPricing;
|
return trainingsPricing;
|
||||||
}
|
}
|
||||||
@ -138,7 +138,7 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
|
|||||||
* @returns {Object} Plan, inherits from $resource
|
* @returns {Object} Plan, inherits from $resource
|
||||||
*/
|
*/
|
||||||
$scope.getPlanFromId = function (id) {
|
$scope.getPlanFromId = function (id) {
|
||||||
for (let plan of Array.from($scope.plans)) {
|
for (const plan of Array.from($scope.plans)) {
|
||||||
if (plan.id === parseInt(id)) {
|
if (plan.id === parseInt(id)) {
|
||||||
return plan;
|
return plan;
|
||||||
}
|
}
|
||||||
@ -151,7 +151,7 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
|
|||||||
* @returns {Object} Group, inherits from $resource
|
* @returns {Object} Group, inherits from $resource
|
||||||
*/
|
*/
|
||||||
$scope.getGroupFromId = function (groups, id) {
|
$scope.getGroupFromId = function (groups, id) {
|
||||||
for (let group of Array.from(groups)) {
|
for (const group of Array.from(groups)) {
|
||||||
if (group.id === parseInt(id)) {
|
if (group.id === parseInt(id)) {
|
||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
@ -313,7 +313,7 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
|
|||||||
* @param [id] {number} credit id for edition, create a new credit object if not provided
|
* @param [id] {number} credit id for edition, create a new credit object if not provided
|
||||||
*/
|
*/
|
||||||
$scope.saveMachineCredit = function (data, id) {
|
$scope.saveMachineCredit = function (data, id) {
|
||||||
for (let mc of Array.from($scope.machineCredits)) {
|
for (const mc of Array.from($scope.machineCredits)) {
|
||||||
if ((mc.plan_id === data.plan_id) && (mc.creditable_id === data.creditable_id) && ((id === null) || (mc.id !== id))) {
|
if ((mc.plan_id === data.plan_id) && (mc.creditable_id === data.creditable_id) && ((id === null) || (mc.id !== id))) {
|
||||||
growl.error(_t('app.admin.pricing.error_a_credit_linking_this_machine_with_that_subscription_already_exists'));
|
growl.error(_t('app.admin.pricing.error_a_credit_linking_this_machine_with_that_subscription_already_exists'));
|
||||||
if (!id) {
|
if (!id) {
|
||||||
@ -383,7 +383,7 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
|
|||||||
* @param [id] {number} credit id for edition, create a new credit object if not provided
|
* @param [id] {number} credit id for edition, create a new credit object if not provided
|
||||||
*/
|
*/
|
||||||
$scope.saveSpaceCredit = function (data, id) {
|
$scope.saveSpaceCredit = function (data, id) {
|
||||||
for (let sc of Array.from($scope.spaceCredits)) {
|
for (const sc of Array.from($scope.spaceCredits)) {
|
||||||
if ((sc.plan_id === data.plan_id) && (sc.creditable_id === data.creditable_id) && ((id === null) || (sc.id !== id))) {
|
if ((sc.plan_id === data.plan_id) && (sc.creditable_id === data.creditable_id) && ((id === null) || (sc.id !== id))) {
|
||||||
growl.error(_t('app.admin.pricing.error_a_credit_linking_this_space_with_that_subscription_already_exists'));
|
growl.error(_t('app.admin.pricing.error_a_credit_linking_this_space_with_that_subscription_already_exists'));
|
||||||
if (!id) {
|
if (!id) {
|
||||||
@ -459,7 +459,7 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
|
|||||||
* Retrieve a price from prices array by a machineId and a groupId
|
* Retrieve a price from prices array by a machineId and a groupId
|
||||||
*/
|
*/
|
||||||
$scope.findPriceBy = function (prices, machineId, groupId) {
|
$scope.findPriceBy = function (prices, machineId, groupId) {
|
||||||
for (let price of Array.from(prices)) {
|
for (const price of Array.from(prices)) {
|
||||||
if ((price.priceable_id === machineId) && (price.group_id === groupId)) {
|
if ((price.priceable_id === machineId) && (price.group_id === groupId)) {
|
||||||
return price;
|
return price;
|
||||||
}
|
}
|
||||||
@ -603,7 +603,7 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
|
|||||||
/**
|
/**
|
||||||
* Load the next 10 coupons
|
* Load the next 10 coupons
|
||||||
*/
|
*/
|
||||||
$scope.loadMore = function() {
|
$scope.loadMore = function () {
|
||||||
$scope.couponsPage++;
|
$scope.couponsPage++;
|
||||||
Coupon.query({ page: $scope.couponsPage, filter: $scope.filter.coupon }, function (data) {
|
Coupon.query({ page: $scope.couponsPage, filter: $scope.filter.coupon }, function (data) {
|
||||||
$scope.coupons = $scope.coupons.concat(data);
|
$scope.coupons = $scope.coupons.concat(data);
|
||||||
@ -613,19 +613,19 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
|
|||||||
/**
|
/**
|
||||||
* Reset the list of coupons according to the newly selected filter
|
* Reset the list of coupons according to the newly selected filter
|
||||||
*/
|
*/
|
||||||
$scope.updateCouponFilter = function() {
|
$scope.updateCouponFilter = function () {
|
||||||
$scope.couponsPage = 1;
|
$scope.couponsPage = 1;
|
||||||
Coupon.query({ page: $scope.couponsPage, filter: $scope.filter.coupon }, function (data) {
|
Coupon.query({ page: $scope.couponsPage, filter: $scope.filter.coupon }, function (data) {
|
||||||
$scope.coupons = data;
|
$scope.coupons = data;
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the exemple price based on the configuration of the default slot duration.
|
* Return the exemple price based on the configuration of the default slot duration.
|
||||||
* @param type {string} 'hourly_rate' | *
|
* @param type {string} 'hourly_rate' | *
|
||||||
* @returns {number} price for "SLOT_DURATION" minutes.
|
* @returns {number} price for "SLOT_DURATION" minutes.
|
||||||
*/
|
*/
|
||||||
$scope.examplePrice = function(type) {
|
$scope.examplePrice = function (type) {
|
||||||
const hourlyRate = 10;
|
const hourlyRate = 10;
|
||||||
|
|
||||||
if (type === 'hourly_rate') {
|
if (type === 'hourly_rate') {
|
||||||
@ -634,7 +634,7 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
|
|||||||
|
|
||||||
const price = (hourlyRate / 60) * $scope.slotDuration;
|
const price = (hourlyRate / 60) * $scope.slotDuration;
|
||||||
return $filter('currency')(price);
|
return $filter('currency')(price);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setup the feature-tour for the admin/pricing page.
|
* Setup the feature-tour for the admin/pricing page.
|
||||||
@ -660,14 +660,16 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
|
|||||||
content: _t('app.admin.tour.pricing.new_plan.content'),
|
content: _t('app.admin.tour.pricing.new_plan.content'),
|
||||||
placement: 'bottom'
|
placement: 'bottom'
|
||||||
});
|
});
|
||||||
uitour.createStep({
|
if ($scope.$root.modules.trainings) {
|
||||||
selector: '.plans-pricing .trainings-tab',
|
uitour.createStep({
|
||||||
stepId: 'trainings',
|
selector: '.plans-pricing .trainings-tab',
|
||||||
order: 2,
|
stepId: 'trainings',
|
||||||
title: _t('app.admin.tour.pricing.trainings.title'),
|
order: 2,
|
||||||
content: _t('app.admin.tour.pricing.trainings.content'),
|
title: _t('app.admin.tour.pricing.trainings.title'),
|
||||||
placement: 'bottom'
|
content: _t('app.admin.tour.pricing.trainings.content'),
|
||||||
});
|
placement: 'bottom'
|
||||||
|
});
|
||||||
|
}
|
||||||
uitour.createStep({
|
uitour.createStep({
|
||||||
selector: '.plans-pricing .machines-tab',
|
selector: '.plans-pricing .machines-tab',
|
||||||
stepId: 'machines',
|
stepId: 'machines',
|
||||||
@ -733,7 +735,7 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
|
|||||||
if (settingsPromise.feature_tour_display !== 'manual' && $scope.currentUser.profile.tours.indexOf('pricing') < 0) {
|
if (settingsPromise.feature_tour_display !== 'manual' && $scope.currentUser.profile.tours.indexOf('pricing') < 0) {
|
||||||
uitour.start();
|
uitour.start();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
/* PRIVATE SCOPE */
|
/* PRIVATE SCOPE */
|
||||||
|
|
||||||
@ -746,7 +748,7 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
|
|||||||
// adds empty array for plan which hasn't any credits yet
|
// adds empty array for plan which hasn't any credits yet
|
||||||
return (function () {
|
return (function () {
|
||||||
const result = [];
|
const result = [];
|
||||||
for (let plan of Array.from($scope.plans)) {
|
for (const plan of Array.from($scope.plans)) {
|
||||||
if ($scope.trainingCreditsGroups[plan.id] == null) {
|
if ($scope.trainingCreditsGroups[plan.id] == null) {
|
||||||
result.push($scope.trainingCreditsGroups[plan.id] = []);
|
result.push($scope.trainingCreditsGroups[plan.id] = []);
|
||||||
} else {
|
} else {
|
||||||
@ -763,7 +765,7 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
|
|||||||
* @param id {number}
|
* @param id {number}
|
||||||
* @returns {number} item index in the provided array
|
* @returns {number} item index in the provided array
|
||||||
*/
|
*/
|
||||||
var findItemIdxById = function (items, id) {
|
const findItemIdxById = function (items, id) {
|
||||||
return (items.map(function (item) { return item.id; })).indexOf(id);
|
return (items.map(function (item) { return item.id; })).indexOf(id);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -771,7 +773,7 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
|
|||||||
* Group the given credits array into a map associating the plan ID with its associated trainings/machines
|
* Group the given credits array into a map associating the plan ID with its associated trainings/machines
|
||||||
* @return {Object} the association map
|
* @return {Object} the association map
|
||||||
*/
|
*/
|
||||||
var groupCreditsByPlan = function (credits) {
|
const groupCreditsByPlan = function (credits) {
|
||||||
const creditsMap = {};
|
const creditsMap = {};
|
||||||
angular.forEach(credits, function (c) {
|
angular.forEach(credits, function (c) {
|
||||||
if (!creditsMap[c.plan_id]) {
|
if (!creditsMap[c.plan_id]) {
|
||||||
@ -787,11 +789,11 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
|
|||||||
* @param trainingId {number|string} training ID
|
* @param trainingId {number|string} training ID
|
||||||
* @param planId {number|string} plan ID
|
* @param planId {number|string} plan ID
|
||||||
*/
|
*/
|
||||||
var findTrainingCredit = function (trainingId, planId) {
|
const findTrainingCredit = function (trainingId, planId) {
|
||||||
trainingId = parseInt(trainingId);
|
trainingId = parseInt(trainingId);
|
||||||
planId = parseInt(planId);
|
planId = parseInt(planId);
|
||||||
|
|
||||||
for (let credit of Array.from($scope.trainingCredits)) {
|
for (const credit of Array.from($scope.trainingCredits)) {
|
||||||
if ((credit.plan_id === planId) && (credit.creditable_id === trainingId)) {
|
if ((credit.plan_id === planId) && (credit.creditable_id === trainingId)) {
|
||||||
return credit;
|
return credit;
|
||||||
}
|
}
|
||||||
@ -803,8 +805,8 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
|
|||||||
* @param id {number} training ID
|
* @param id {number} training ID
|
||||||
* @returns {Object} Training inherited from $resource
|
* @returns {Object} Training inherited from $resource
|
||||||
*/
|
*/
|
||||||
var getTrainingFromId = function (id) {
|
const getTrainingFromId = function (id) {
|
||||||
for (let training of Array.from($scope.trainings)) {
|
for (const training of Array.from($scope.trainings)) {
|
||||||
if (training.id === parseInt(id)) {
|
if (training.id === parseInt(id)) {
|
||||||
return training;
|
return training;
|
||||||
}
|
}
|
||||||
|
@ -184,9 +184,10 @@ Application.Controllers.controller('StatisticsController', ['$scope', '$state',
|
|||||||
*/
|
*/
|
||||||
$scope.hiddenTab = function (tab) {
|
$scope.hiddenTab = function (tab) {
|
||||||
if (tab.table) {
|
if (tab.table) {
|
||||||
if ((tab.es_type_key === 'subscription') && !$rootScope.modules.plans) {
|
return ((tab.es_type_key === 'subscription' && !$rootScope.modules.plans) ||
|
||||||
return true;
|
(tab.es_type_key === 'training' && !$rootScope.modules.trainings) ||
|
||||||
} else return (tab.es_type_key === 'space') && !$rootScope.modules.spaces;
|
(tab.es_type_key === 'space' && !$rootScope.modules.spaces)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -35,12 +35,6 @@ Application.Controllers.controller('MainNavController', ['$scope', function ($sc
|
|||||||
linkIcon: 'cogs',
|
linkIcon: 'cogs',
|
||||||
class: 'reserve-machine-link'
|
class: 'reserve-machine-link'
|
||||||
},
|
},
|
||||||
{
|
|
||||||
state: 'app.public.trainings_list',
|
|
||||||
linkText: 'app.public.common.trainings_registrations',
|
|
||||||
linkIcon: 'graduation-cap',
|
|
||||||
class: 'reserve-training-link'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
state: 'app.public.events_list',
|
state: 'app.public.events_list',
|
||||||
linkText: 'app.public.common.events_registrations',
|
linkText: 'app.public.common.events_registrations',
|
||||||
@ -67,6 +61,15 @@ Application.Controllers.controller('MainNavController', ['$scope', function ($sc
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($scope.$root.modules.trainings) {
|
||||||
|
$scope.navLinks.splice(4, 0, {
|
||||||
|
state: 'app.public.trainings_list',
|
||||||
|
linkText: 'app.public.common.trainings_registrations',
|
||||||
|
linkIcon: 'graduation-cap',
|
||||||
|
class: 'reserve-training-link'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if ($scope.$root.modules.spaces) {
|
if ($scope.$root.modules.spaces) {
|
||||||
$scope.navLinks.splice(4, 0, {
|
$scope.navLinks.splice(4, 0, {
|
||||||
state: 'app.public.spaces_list',
|
state: 'app.public.spaces_list',
|
||||||
@ -90,12 +93,6 @@ Application.Controllers.controller('MainNavController', ['$scope', function ($sc
|
|||||||
linkIcon: 'cogs',
|
linkIcon: 'cogs',
|
||||||
authorizedRoles: ['admin', 'manager']
|
authorizedRoles: ['admin', 'manager']
|
||||||
},
|
},
|
||||||
{
|
|
||||||
state: 'app.admin.trainings',
|
|
||||||
linkText: 'app.public.common.trainings_monitoring',
|
|
||||||
linkIcon: 'graduation-cap',
|
|
||||||
authorizedRoles: ['admin', 'manager']
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
state: 'app.admin.events',
|
state: 'app.admin.events',
|
||||||
linkText: 'app.public.common.manage_the_events',
|
linkText: 'app.public.common.manage_the_events',
|
||||||
@ -147,6 +144,15 @@ Application.Controllers.controller('MainNavController', ['$scope', function ($sc
|
|||||||
|
|
||||||
$scope.adminNavLinks = adminNavLinks;
|
$scope.adminNavLinks = adminNavLinks;
|
||||||
|
|
||||||
|
if ($scope.$root.modules.trainings) {
|
||||||
|
$scope.adminNavLinks.splice(3, 0, {
|
||||||
|
state: 'app.admin.trainings',
|
||||||
|
linkText: 'app.public.common.trainings_monitoring',
|
||||||
|
linkIcon: 'graduation-cap',
|
||||||
|
authorizedRoles: ['admin', 'manager']
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if ($scope.$root.modules.spaces) {
|
if ($scope.$root.modules.spaces) {
|
||||||
$scope.adminNavLinks.splice(3, 0, {
|
$scope.adminNavLinks.splice(3, 0, {
|
||||||
state: 'app.public.spaces_list',
|
state: 'app.public.spaces_list',
|
||||||
|
@ -37,7 +37,7 @@ angular.module('application.router', ['ui.router'])
|
|||||||
logoFile: ['CustomAsset', function (CustomAsset) { return CustomAsset.get({ name: 'logo-file' }).$promise; }],
|
logoFile: ['CustomAsset', function (CustomAsset) { return CustomAsset.get({ name: 'logo-file' }).$promise; }],
|
||||||
logoBlackFile: ['CustomAsset', function (CustomAsset) { return CustomAsset.get({ name: 'logo-black-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; }],
|
sharedTranslations: ['Translations', function (Translations) { return Translations.query(['app.shared', 'app.public.common']).$promise; }],
|
||||||
modulesPromise: ['Setting', function (Setting) { return Setting.query({ names: "['spaces_module', 'plans_module', 'invoicing_module', 'wallet_module', 'statistics_module']" }).$promise; }]
|
modulesPromise: ['Setting', function (Setting) { return Setting.query({ names: "['spaces_module', 'plans_module', 'invoicing_module', 'wallet_module', 'statistics_module', 'trainings_module']" }).$promise; }]
|
||||||
},
|
},
|
||||||
onEnter: ['$rootScope', 'logoFile', 'logoBlackFile', 'modulesPromise', 'CSRF', function ($rootScope, logoFile, logoBlackFile, modulesPromise, CSRF) {
|
onEnter: ['$rootScope', 'logoFile', 'logoBlackFile', 'modulesPromise', 'CSRF', function ($rootScope, logoFile, logoBlackFile, modulesPromise, CSRF) {
|
||||||
// Retrieve Anti-CSRF tokens from cookies
|
// Retrieve Anti-CSRF tokens from cookies
|
||||||
@ -48,6 +48,7 @@ angular.module('application.router', ['ui.router'])
|
|||||||
$rootScope.modules = {
|
$rootScope.modules = {
|
||||||
spaces: (modulesPromise.spaces_module === 'true'),
|
spaces: (modulesPromise.spaces_module === 'true'),
|
||||||
plans: (modulesPromise.plans_module === 'true'),
|
plans: (modulesPromise.plans_module === 'true'),
|
||||||
|
trainings: (modulesPromise.trainings_module === 'true'),
|
||||||
invoicing: (modulesPromise.invoicing_module === 'true'),
|
invoicing: (modulesPromise.invoicing_module === 'true'),
|
||||||
wallet: (modulesPromise.wallet_module === 'true'),
|
wallet: (modulesPromise.wallet_module === 'true'),
|
||||||
statistics: (modulesPromise.statistics_module === 'true')
|
statistics: (modulesPromise.statistics_module === 'true')
|
||||||
@ -458,6 +459,7 @@ angular.module('application.router', ['ui.router'])
|
|||||||
// trainings
|
// trainings
|
||||||
.state('app.public.trainings_list', {
|
.state('app.public.trainings_list', {
|
||||||
url: '/trainings',
|
url: '/trainings',
|
||||||
|
abstract: !Fablab.trainingsModule,
|
||||||
views: {
|
views: {
|
||||||
'main@': {
|
'main@': {
|
||||||
templateUrl: '/trainings/index.html',
|
templateUrl: '/trainings/index.html',
|
||||||
@ -470,6 +472,7 @@ angular.module('application.router', ['ui.router'])
|
|||||||
})
|
})
|
||||||
.state('app.public.training_show', {
|
.state('app.public.training_show', {
|
||||||
url: '/trainings/:id',
|
url: '/trainings/:id',
|
||||||
|
abstract: !Fablab.trainingsModule,
|
||||||
views: {
|
views: {
|
||||||
'main@': {
|
'main@': {
|
||||||
templateUrl: '/trainings/show.html',
|
templateUrl: '/trainings/show.html',
|
||||||
@ -482,6 +485,7 @@ angular.module('application.router', ['ui.router'])
|
|||||||
})
|
})
|
||||||
.state('app.logged.trainings_reserve', {
|
.state('app.logged.trainings_reserve', {
|
||||||
url: '/trainings/:id/reserve',
|
url: '/trainings/:id/reserve',
|
||||||
|
abstract: !Fablab.trainingsModule,
|
||||||
views: {
|
views: {
|
||||||
'main@': {
|
'main@': {
|
||||||
templateUrl: '/trainings/reserve.html',
|
templateUrl: '/trainings/reserve.html',
|
||||||
@ -652,6 +656,7 @@ angular.module('application.router', ['ui.router'])
|
|||||||
// trainings
|
// trainings
|
||||||
.state('app.admin.trainings', {
|
.state('app.admin.trainings', {
|
||||||
url: '/admin/trainings',
|
url: '/admin/trainings',
|
||||||
|
abstract: !Fablab.trainingsModule,
|
||||||
views: {
|
views: {
|
||||||
'main@': {
|
'main@': {
|
||||||
templateUrl: '/admin/trainings/index.html',
|
templateUrl: '/admin/trainings/index.html',
|
||||||
@ -666,6 +671,7 @@ angular.module('application.router', ['ui.router'])
|
|||||||
})
|
})
|
||||||
.state('app.admin.trainings_new', {
|
.state('app.admin.trainings_new', {
|
||||||
url: '/admin/trainings/new',
|
url: '/admin/trainings/new',
|
||||||
|
abstract: !Fablab.trainingsModule,
|
||||||
views: {
|
views: {
|
||||||
'main@': {
|
'main@': {
|
||||||
templateUrl: '/admin/trainings/new.html',
|
templateUrl: '/admin/trainings/new.html',
|
||||||
@ -678,6 +684,7 @@ angular.module('application.router', ['ui.router'])
|
|||||||
})
|
})
|
||||||
.state('app.admin.trainings_edit', {
|
.state('app.admin.trainings_edit', {
|
||||||
url: '/admin/trainings/:id/edit',
|
url: '/admin/trainings/:id/edit',
|
||||||
|
abstract: !Fablab.trainingsModule,
|
||||||
views: {
|
views: {
|
||||||
'main@': {
|
'main@': {
|
||||||
templateUrl: '/admin/trainings/edit.html',
|
templateUrl: '/admin/trainings/edit.html',
|
||||||
@ -1054,7 +1061,7 @@ angular.module('application.router', ['ui.router'])
|
|||||||
"'booking_move_enable', 'booking_move_delay', 'booking_cancel_enable', 'feature_tour_display', " +
|
"'booking_move_enable', 'booking_move_delay', 'booking_cancel_enable', 'feature_tour_display', " +
|
||||||
"'booking_cancel_delay', 'main_color', 'secondary_color', 'spaces_module', 'twitter_analytics', " +
|
"'booking_cancel_delay', 'main_color', 'secondary_color', 'spaces_module', 'twitter_analytics', " +
|
||||||
"'fablab_name', 'name_genre', 'reminder_enable', 'plans_module', 'confirmation_required', " +
|
"'fablab_name', 'name_genre', 'reminder_enable', 'plans_module', 'confirmation_required', " +
|
||||||
"'reminder_delay', 'visibility_yearly', 'visibility_others', 'wallet_module', " +
|
"'reminder_delay', 'visibility_yearly', 'visibility_others', 'wallet_module', 'trainings_module', " +
|
||||||
"'display_name_enable', 'machines_sort_by', 'fab_analytics', 'statistics_module', " +
|
"'display_name_enable', 'machines_sort_by', 'fab_analytics', 'statistics_module', " +
|
||||||
"'link_name', 'home_content', 'home_css', 'phone_required', 'upcoming_events_shown']"
|
"'link_name', 'home_content', 'home_css', 'phone_required', 'upcoming_events_shown']"
|
||||||
}).$promise;
|
}).$promise;
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<div class="modal-body" ng-show="step === 1">
|
<div class="modal-body" ng-show="step === 1">
|
||||||
<label class="m-t-sm" translate>{{ 'app.admin.calendar.what_kind_of_slot_do_you_want_to_create' }}</label>
|
<label class="m-t-sm" translate>{{ 'app.admin.calendar.what_kind_of_slot_do_you_want_to_create' }}</label>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="radio">
|
<div class="radio" ng-show="$root.modules.trainings">
|
||||||
<label>
|
<label>
|
||||||
<input type="radio" id="training" name="available_type" value="training" ng-model="availability.available_type">
|
<input type="radio" id="training" name="available_type" value="training" ng-model="availability.available_type">
|
||||||
<span translate>{{ 'app.admin.calendar.training' }}</span>
|
<span translate>{{ 'app.admin.calendar.training' }}</span>
|
||||||
|
@ -98,7 +98,7 @@
|
|||||||
</section>
|
</section>
|
||||||
</uib-tab>
|
</uib-tab>
|
||||||
|
|
||||||
<uib-tab heading="{{ 'app.admin.members_edit.trainings' | translate }}">
|
<uib-tab heading="{{ 'app.admin.members_edit.trainings' | translate }}" ng-show="$root.modules.trainings">
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<div class="widget panel b-a m-t-lg">
|
<div class="widget panel b-a m-t-lg">
|
||||||
<div class="panel-heading b-b ">
|
<div class="panel-heading b-b ">
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
<ng-include src="'/admin/pricing/subscriptions.html'"></ng-include>
|
<ng-include src="'/admin/pricing/subscriptions.html'"></ng-include>
|
||||||
</uib-tab>
|
</uib-tab>
|
||||||
|
|
||||||
<uib-tab heading="{{ 'app.admin.pricing.trainings' | translate }}" index="1" class="trainings-tab">
|
<uib-tab heading="{{ 'app.admin.pricing.trainings' | translate }}" ng-show="$root.modules.trainings" index="1" class="trainings-tab">
|
||||||
<ng-include src="'/admin/pricing/trainings.html'"></ng-include>
|
<ng-include src="'/admin/pricing/trainings.html'"></ng-include>
|
||||||
</uib-tab>
|
</uib-tab>
|
||||||
|
|
||||||
|
@ -457,6 +457,14 @@
|
|||||||
label="app.admin.settings.enable_plans"
|
label="app.admin.settings.enable_plans"
|
||||||
classes="m-l"></boolean-setting>
|
classes="m-l"></boolean-setting>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<h3 class="m-l" translate>{{ 'app.admin.settings.trainings' }}</h3>
|
||||||
|
<p class="alert alert-warning m-h-md" ng-bind-html="'app.admin.settings.trainings_info_html' | translate"></p>
|
||||||
|
<boolean-setting name="trainings_module"
|
||||||
|
settings="allSettings"
|
||||||
|
label="app.admin.settings.enable_trainings"
|
||||||
|
classes="m-l"></boolean-setting>
|
||||||
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<h3 class="m-l" translate>{{ 'app.admin.settings.invoicing' }}</h3>
|
<h3 class="m-l" translate>{{ 'app.admin.settings.invoicing' }}</h3>
|
||||||
<p class="alert alert-warning m-h-md" ng-bind-html="'app.admin.settings.invoicing_info_html' | translate"></p>
|
<p class="alert alert-warning m-h-md" ng-bind-html="'app.admin.settings.invoicing_info_html' | translate"></p>
|
||||||
|
@ -107,7 +107,8 @@ class Setting < ApplicationRecord
|
|||||||
wallet_module
|
wallet_module
|
||||||
statistics_module
|
statistics_module
|
||||||
upcoming_events_shown
|
upcoming_events_shown
|
||||||
payment_schedule_prefix] }
|
payment_schedule_prefix
|
||||||
|
trainings_module] }
|
||||||
# WARNING: when adding a new key, you may also want to add it in app/policies/setting_policy.rb#public_whitelist
|
# WARNING: when adding a new key, you may also want to add it in app/policies/setting_policy.rb#public_whitelist
|
||||||
|
|
||||||
def value
|
def value
|
||||||
|
@ -38,7 +38,7 @@ class SettingPolicy < ApplicationPolicy
|
|||||||
fablab_name name_genre event_explications_alert space_explications_alert link_name home_content phone_required
|
fablab_name name_genre event_explications_alert space_explications_alert link_name home_content phone_required
|
||||||
tracking_id book_overlapping_slots slot_duration events_in_calendar spaces_module plans_module invoicing_module
|
tracking_id book_overlapping_slots slot_duration events_in_calendar spaces_module plans_module invoicing_module
|
||||||
recaptcha_site_key feature_tour_display disqus_shortname allowed_cad_extensions openlab_app_id openlab_default
|
recaptcha_site_key feature_tour_display disqus_shortname allowed_cad_extensions openlab_app_id openlab_default
|
||||||
online_payment_module stripe_public_key confirmation_required wallet_module]
|
online_payment_module stripe_public_key confirmation_required wallet_module trainings_module]
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
Fablab.plansModule = ('<%= Setting.get('plans_module') %>' === 'true');
|
Fablab.plansModule = ('<%= Setting.get('plans_module') %>' === 'true');
|
||||||
Fablab.spacesModule = ('<%= Setting.get('spaces_module') %>' === 'true');
|
Fablab.spacesModule = ('<%= Setting.get('spaces_module') %>' === 'true');
|
||||||
|
Fablab.trainingsModule = ('<%= Setting.get('trainings_module') %>' === 'true');
|
||||||
Fablab.walletModule = ('<%= Setting.get('wallet_module') %>' === 'true');
|
Fablab.walletModule = ('<%= Setting.get('wallet_module') %>' === 'true');
|
||||||
Fablab.statisticsModule = ('<%= Setting.get('statistics_module') %>' === 'true');
|
Fablab.statisticsModule = ('<%= Setting.get('statistics_module') %>' === 'true');
|
||||||
Fablab.defaultHost = "<%= Rails.application.secrets.default_host %>";
|
Fablab.defaultHost = "<%= Rails.application.secrets.default_host %>";
|
||||||
|
@ -1097,6 +1097,10 @@ en:
|
|||||||
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>"
|
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"
|
enable_plans: "Enable the plans"
|
||||||
plans_module: "plans module"
|
plans_module: "plans module"
|
||||||
|
trainings: "Trainings"
|
||||||
|
trainings_info_html: "<p>Trainings are fully integrated into the Fab-manger's agenda. If enabled, your members will be able to book and pay trainings.</p><p>Trainings provides a way to prevent members to book some machines, if they do have not taken the prerequisite course.</p>"
|
||||||
|
enable_trainings: "Enable the trainings"
|
||||||
|
trainings_module: "trainings module"
|
||||||
invoicing: "Invoicing"
|
invoicing: "Invoicing"
|
||||||
invoicing_info_html: "<p>You can fully disable the invoicing module.</p><p>This is useful if you have your own invoicing system, and you don't want Fab-manager generates and sends invoices to the members.</p><p><strong>Warning:</strong> even if you disable the invoicing module, you must to configure the VAT to prevent errors in accounting and prices. Do it from the « Invoices > Invoicing settings » section.</p>"
|
invoicing_info_html: "<p>You can fully disable the invoicing module.</p><p>This is useful if you have your own invoicing system, and you don't want Fab-manager generates and sends invoices to the members.</p><p><strong>Warning:</strong> even if you disable the invoicing module, you must to configure the VAT to prevent errors in accounting and prices. Do it from the « Invoices > Invoicing settings » section.</p>"
|
||||||
enable_invoicing: "Enable invoicing"
|
enable_invoicing: "Enable invoicing"
|
||||||
|
@ -1097,6 +1097,10 @@ fr:
|
|||||||
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>"
|
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"
|
enable_plans: "Activer les abonnements"
|
||||||
plans_module: "module abonnements"
|
plans_module: "module abonnements"
|
||||||
|
trainings: "Formations"
|
||||||
|
trainings_info_html: "<p>Les formations sont pleinement intégrées dans l'agenda de Fab-manger. Si elles sont activées, vos membres pourrons réserver et payer des formations.</p><p>Les formations fournissent une solution pour éviter que des membres réservent des machines, sans avoir suivi la formation préalable.</p>"
|
||||||
|
enable_trainings: "Activer les formations"
|
||||||
|
trainings_module: "module formations"
|
||||||
invoicing: "Facturation"
|
invoicing: "Facturation"
|
||||||
invoicing_info_html: "<p>Vous pouvez complètement désactiver le module de facturation.</p><p>Cela est utile si vous possédez votre propre système de facturation, et que vous ne souhaitez pas que Fab-manager génère et envoie des factures aux membres.</p><p><strong>Attention :</strong> même si vous désactivez le module de facturation, vous devez configurer la TVA pour éviter des erreurs de prix et de comptabilité. Faites le depuis la section « Factures > Paramètres de facturation ».</p>"
|
invoicing_info_html: "<p>Vous pouvez complètement désactiver le module de facturation.</p><p>Cela est utile si vous possédez votre propre système de facturation, et que vous ne souhaitez pas que Fab-manager génère et envoie des factures aux membres.</p><p><strong>Attention :</strong> même si vous désactivez le module de facturation, vous devez configurer la TVA pour éviter des erreurs de prix et de comptabilité. Faites le depuis la section « Factures > Paramètres de facturation ».</p>"
|
||||||
enable_invoicing: "Activer la facturation"
|
enable_invoicing: "Activer la facturation"
|
||||||
|
@ -893,6 +893,8 @@ Setting.set('statistics_module', true) unless Setting.find_by(name: 'statistics_
|
|||||||
|
|
||||||
Setting.set('upcoming_events_shown', 'until_start') unless Setting.find_by(name: 'upcoming_events_shown').try(:value)
|
Setting.set('upcoming_events_shown', 'until_start') unless Setting.find_by(name: 'upcoming_events_shown').try(:value)
|
||||||
|
|
||||||
|
Setting.set('trainings_module', true) unless Setting.find_by(name: 'trainings_module').try(:value)
|
||||||
|
|
||||||
if StatisticCustomAggregation.count.zero?
|
if StatisticCustomAggregation.count.zero?
|
||||||
# available reservations hours for machines
|
# available reservations hours for machines
|
||||||
machine_hours = StatisticType.find_by(key: 'hour', statistic_index_id: 2)
|
machine_hours = StatisticType.find_by(key: 'hour', statistic_index_id: 2)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user