mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-02-20 14:54:15 +01:00
(feat) ability to disable the store
This commit is contained in:
parent
afc391f73e
commit
d6fbd90c7c
@ -34,3 +34,5 @@ Style/AndOr:
|
||||
EnforcedStyle: conditionals
|
||||
Style/FormatString:
|
||||
EnforcedStyle: sprintf
|
||||
Style/FormatStringToken:
|
||||
EnforcedStyle: template
|
||||
|
@ -1,6 +1,8 @@
|
||||
# Changelog Fab-manager
|
||||
|
||||
- Script to download translations from Crowdin
|
||||
- Fablab's store module
|
||||
- [TODO DEPLOY] `rails db:seed`
|
||||
|
||||
## v5.4.17 2022 September 06
|
||||
|
||||
|
@ -53,7 +53,7 @@ Application.Controllers.controller('MainNavController', ['$scope', 'settingsProm
|
||||
linkIcon: 'tags',
|
||||
class: 'reserve-event-link'
|
||||
},
|
||||
{
|
||||
$scope.$root.modules.store && {
|
||||
state: 'app.public.store',
|
||||
linkText: 'app.public.common.fablab_store',
|
||||
linkIcon: 'cart-plus',
|
||||
@ -106,7 +106,7 @@ Application.Controllers.controller('MainNavController', ['$scope', 'settingsProm
|
||||
linkIcon: 'tags',
|
||||
authorizedRoles: ['admin', 'manager']
|
||||
},
|
||||
{
|
||||
$scope.$root.modules.store && {
|
||||
state: 'app.admin.store.products',
|
||||
linkText: 'app.public.common.manage_the_store',
|
||||
linkIcon: 'cart-plus',
|
||||
|
@ -129,7 +129,8 @@ export const modulesSettings = [
|
||||
'machines_module',
|
||||
'online_payment_module',
|
||||
'public_agenda_module',
|
||||
'invoicing_module'
|
||||
'invoicing_module',
|
||||
'store_module'
|
||||
] as const;
|
||||
|
||||
export const stripeSettings = [
|
||||
|
@ -27,7 +27,7 @@ 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; }],
|
||||
modulesPromise: ['Setting', function (Setting) { return Setting.query({ names: "['machines_module', 'spaces_module', 'plans_module', 'invoicing_module', 'wallet_module', 'statistics_module', 'trainings_module', 'public_agenda_module']" }).$promise; }],
|
||||
modulesPromise: ['Setting', function (Setting) { return Setting.query({ names: "['machines_module', 'spaces_module', 'plans_module', 'invoicing_module', 'wallet_module', 'statistics_module', 'trainings_module', 'public_agenda_module', 'store_module']" }).$promise; }],
|
||||
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['public_registrations']" }).$promise; }]
|
||||
},
|
||||
onEnter: ['$rootScope', 'logoFile', 'logoBlackFile', 'modulesPromise', 'CSRF', function ($rootScope, logoFile, logoBlackFile, modulesPromise, CSRF) {
|
||||
@ -41,6 +41,7 @@ angular.module('application.router', ['ui.router'])
|
||||
spaces: (modulesPromise.spaces_module === 'true'),
|
||||
plans: (modulesPromise.plans_module === 'true'),
|
||||
trainings: (modulesPromise.trainings_module === 'true'),
|
||||
store: (modulesPromise.store_module === 'true'),
|
||||
invoicing: (modulesPromise.invoicing_module === 'true'),
|
||||
wallet: (modulesPromise.wallet_module === 'true'),
|
||||
publicAgenda: (modulesPromise.public_agenda_module === 'true'),
|
||||
@ -346,6 +347,7 @@ angular.module('application.router', ['ui.router'])
|
||||
// machines
|
||||
.state('app.public.machines_list', {
|
||||
url: '/machines',
|
||||
abstract: !Fablab.machinesModule,
|
||||
views: {
|
||||
'main@': {
|
||||
templateUrl: '/machines/index.html',
|
||||
@ -359,6 +361,7 @@ angular.module('application.router', ['ui.router'])
|
||||
})
|
||||
.state('app.admin.machines_new', {
|
||||
url: '/machines/new',
|
||||
abstract: !Fablab.machinesModule,
|
||||
views: {
|
||||
'main@': {
|
||||
templateUrl: '/machines/new.html',
|
||||
@ -368,6 +371,7 @@ angular.module('application.router', ['ui.router'])
|
||||
})
|
||||
.state('app.public.machines_show', {
|
||||
url: '/machines/:id',
|
||||
abstract: !Fablab.machinesModule,
|
||||
views: {
|
||||
'main@': {
|
||||
templateUrl: '/machines/show.html',
|
||||
@ -380,6 +384,7 @@ angular.module('application.router', ['ui.router'])
|
||||
})
|
||||
.state('app.logged.machines_reserve', {
|
||||
url: '/machines/:id/reserve',
|
||||
abstract: !Fablab.machinesModule,
|
||||
views: {
|
||||
'main@': {
|
||||
templateUrl: '/machines/reserve.html',
|
||||
@ -401,6 +406,7 @@ angular.module('application.router', ['ui.router'])
|
||||
})
|
||||
.state('app.admin.machines_edit', {
|
||||
url: '/machines/:id/edit',
|
||||
abstract: !Fablab.machinesModule,
|
||||
views: {
|
||||
'main@': {
|
||||
templateUrl: '/machines/edit.html',
|
||||
@ -621,6 +627,7 @@ angular.module('application.router', ['ui.router'])
|
||||
// store
|
||||
.state('app.public.store', {
|
||||
url: '/store/:categoryTypeUrl/:category?{machines:string}{keywords:string}{is_active:string}{page:string}{sort:string}',
|
||||
abstract: !Fablab.storeModule,
|
||||
views: {
|
||||
'main@': {
|
||||
templateUrl: '/store/index.html',
|
||||
@ -641,6 +648,7 @@ angular.module('application.router', ['ui.router'])
|
||||
// show product
|
||||
.state('app.public.product_show', {
|
||||
url: '/store/p/:slug',
|
||||
abstract: !Fablab.storeModule,
|
||||
views: {
|
||||
'main@': {
|
||||
templateUrl: '/products/show.html',
|
||||
@ -652,6 +660,7 @@ angular.module('application.router', ['ui.router'])
|
||||
// cart
|
||||
.state('app.public.store_cart', {
|
||||
url: '/store/cart',
|
||||
abstract: !Fablab.storeModule,
|
||||
views: {
|
||||
'main@': {
|
||||
templateUrl: '/cart/index.html',
|
||||
@ -934,6 +943,7 @@ angular.module('application.router', ['ui.router'])
|
||||
// show order
|
||||
.state('app.admin.order_show', {
|
||||
url: '/admin/store/orders/:id',
|
||||
abstract: !Fablab.storeModule,
|
||||
views: {
|
||||
'main@': {
|
||||
templateUrl: '/admin/orders/show.html',
|
||||
@ -1164,7 +1174,8 @@ angular.module('application.router', ['ui.router'])
|
||||
"'link_name', 'home_content', 'home_css', 'phone_required', 'upcoming_events_shown', 'public_agenda_module'," +
|
||||
"'renew_pack_threshold', 'pack_only_for_subscription', 'overlapping_categories', 'public_registrations'," +
|
||||
"'extended_prices_in_same_day', 'recaptcha_site_key', 'recaptcha_secret_key', 'user_validation_required', " +
|
||||
"'user_validation_required_list', 'machines_module', 'user_change_group', 'show_username_in_admin_list']"
|
||||
"'user_validation_required_list', 'machines_module', 'user_change_group', 'show_username_in_admin_list', " +
|
||||
"'store_module']"
|
||||
}).$promise;
|
||||
}],
|
||||
privacyDraftsPromise: ['Setting', function (Setting) { return Setting.get({ name: 'privacy_draft', history: true }).$promise; }],
|
||||
@ -1182,6 +1193,7 @@ angular.module('application.router', ['ui.router'])
|
||||
|
||||
.state('app.admin.store.settings', {
|
||||
url: '/settings',
|
||||
abstract: !Fablab.storeModule,
|
||||
views: {
|
||||
'main@': {
|
||||
templateUrl: '/admin/store/index.html',
|
||||
@ -1192,6 +1204,7 @@ angular.module('application.router', ['ui.router'])
|
||||
|
||||
.state('app.admin.store.products', {
|
||||
url: '/products?{categories:string}{machines:string}{keywords:string}{stock_type:string}{stock_from:string}{stock_to:string}{is_active:string}{page:string}{sort:string}',
|
||||
abstract: !Fablab.storeModule,
|
||||
views: {
|
||||
'main@': {
|
||||
templateUrl: '/admin/store/index.html',
|
||||
@ -1213,6 +1226,7 @@ angular.module('application.router', ['ui.router'])
|
||||
|
||||
.state('app.admin.store.products_new', {
|
||||
url: '/products/new',
|
||||
abstract: !Fablab.storeModule,
|
||||
views: {
|
||||
'main@': {
|
||||
templateUrl: '/admin/store/product_new.html',
|
||||
@ -1223,6 +1237,7 @@ angular.module('application.router', ['ui.router'])
|
||||
|
||||
.state('app.admin.store.products_edit', {
|
||||
url: '/products/:id/edit',
|
||||
abstract: !Fablab.storeModule,
|
||||
views: {
|
||||
'main@': {
|
||||
templateUrl: '/admin/store/product_edit.html',
|
||||
@ -1233,6 +1248,7 @@ angular.module('application.router', ['ui.router'])
|
||||
|
||||
.state('app.admin.store.categories', {
|
||||
url: '/categories',
|
||||
abstract: !Fablab.storeModule,
|
||||
views: {
|
||||
'main@': {
|
||||
templateUrl: '/admin/store/index.html',
|
||||
@ -1243,6 +1259,7 @@ angular.module('application.router', ['ui.router'])
|
||||
|
||||
.state('app.admin.store.orders', {
|
||||
url: '/orders',
|
||||
abstract: !Fablab.storeModule,
|
||||
views: {
|
||||
'main@': {
|
||||
templateUrl: '/admin/store/index.html',
|
||||
|
@ -452,6 +452,15 @@
|
||||
on-error="onError"
|
||||
class-name="'m-l'"></boolean-setting>
|
||||
</div>
|
||||
<div class="row">
|
||||
<h3 class="m-l" translate>{{ 'app.admin.settings.store' }}</h3>
|
||||
<p class="alert alert-warning m-h-md" ng-bind-html="'app.admin.settings.store_info_html' | translate"></p>
|
||||
<boolean-setting name="'store_module'"
|
||||
label="'app.admin.settings.enable_store' | translate"
|
||||
on-success="onSuccess"
|
||||
on-error="onError"
|
||||
class-name="'m-l'"></boolean-setting>
|
||||
</div>
|
||||
<div class="row">
|
||||
<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>
|
||||
|
@ -1,11 +1,12 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Setting is a configuration element of the platform. Only administrators are allowed to modify Settings
|
||||
# For some settings, changing them will involve some callback actions (like rebuilding the stylesheets if the theme color Setting is changed).
|
||||
# For some settings, changing them will involve some callback actions (like rebuilding the stylesheets
|
||||
# if the theme color Setting has changed).
|
||||
# A full history of the previous values is kept in database with the date and the author of the change
|
||||
# after_update callback is handled by SettingService
|
||||
class Setting < ApplicationRecord
|
||||
has_many :history_values
|
||||
has_many :history_values, dependent: :destroy
|
||||
# The following list contains all the settings that can be customized from the Fab-manager's UI.
|
||||
# A few of them that are system settings, that should not be updated manually (uuid, origin...).
|
||||
validates :name, inclusion:
|
||||
@ -151,7 +152,8 @@ class Setting < ApplicationRecord
|
||||
user_change_group
|
||||
user_validation_required
|
||||
user_validation_required_list
|
||||
show_username_in_admin_list] }
|
||||
show_username_in_admin_list
|
||||
store_module] }
|
||||
# WARNING: when adding a new key, you may also want to add it in:
|
||||
# - config/locales/en.yml#settings
|
||||
# - app/frontend/src/javascript/models/setting.ts#SettingName
|
||||
@ -188,6 +190,7 @@ class Setting < ApplicationRecord
|
||||
previous_value&.created_at
|
||||
end
|
||||
|
||||
# @deprecated, prefer Setting.set() instead
|
||||
def value=(val)
|
||||
admin = User.admins.first
|
||||
save && history_values.create(invoicing_profile: admin.invoicing_profile, value: val)
|
||||
@ -223,6 +226,6 @@ class Setting < ApplicationRecord
|
||||
# Check if the given setting was set
|
||||
##
|
||||
def self.set?(name)
|
||||
find_by(name: name)&.value.nil? ? false : true
|
||||
!find_by(name: name)&.value.nil?
|
||||
end
|
||||
end
|
||||
|
@ -42,7 +42,7 @@ class SettingPolicy < ApplicationPolicy
|
||||
payment_gateway payzen_endpoint payzen_public_key public_agenda_module renew_pack_threshold statistics_module
|
||||
pack_only_for_subscription overlapping_categories public_registrations facebook twitter viadeo linkedin instagram
|
||||
youtube vimeo dailymotion github echosciences pinterest lastfm flickr machines_module user_change_group
|
||||
user_validation_required user_validation_required_list]
|
||||
user_validation_required user_validation_required_list store_module]
|
||||
end
|
||||
|
||||
##
|
||||
@ -50,7 +50,7 @@ class SettingPolicy < ApplicationPolicy
|
||||
# This blacklist is automatically generated from the public_whitelist above.
|
||||
##
|
||||
def self.public_blacklist
|
||||
Setting.validators.detect { |v| v.class == ActiveModel::Validations::InclusionValidator && v.attributes.include?(:name) }
|
||||
Setting.validators.detect { |v| v.instance_of?(ActiveModel::Validations::InclusionValidator) && v.attributes.include?(:name) }
|
||||
.options[:in] - SettingPolicy.public_whitelist
|
||||
end
|
||||
end
|
||||
|
@ -36,6 +36,7 @@
|
||||
Fablab.plansModule = ('<%= Setting.get('plans_module') %>' === 'true');
|
||||
Fablab.spacesModule = ('<%= Setting.get('spaces_module') %>' === 'true');
|
||||
Fablab.trainingsModule = ('<%= Setting.get('trainings_module') %>' === 'true');
|
||||
Fablab.storeModule = ('<%= Setting.get('store_module') %>' === 'true');
|
||||
Fablab.walletModule = ('<%= Setting.get('wallet_module') %>' === 'true');
|
||||
Fablab.publicAgendaModule = ('<%= Setting.get('public_agenda_module') %>' === 'true');
|
||||
Fablab.statisticsModule = ('<%= Setting.get('statistics_module') %>' === 'true');
|
||||
|
@ -1427,6 +1427,10 @@ en:
|
||||
trainings_info_html: "<p>Trainings are fully integrated Fab-manager'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"
|
||||
store: "Store"
|
||||
store_info_html: "You can enable the store module that provides an easy way to <strong>sell various products and consumables</strong> to your members. This module also allows you to <strong>manage stocks</strong> and track orders."
|
||||
enable_store: "Enable the store"
|
||||
store_module: "store module"
|
||||
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>"
|
||||
enable_invoicing: "Enable invoicing"
|
||||
|
@ -600,3 +600,4 @@ en:
|
||||
machines_module: "Machines module"
|
||||
user_change_group: "Allow users to change their group"
|
||||
show_username_in_admin_list: "Show the username in the admin's members list"
|
||||
store_module: "Store module"
|
||||
|
244
db/seeds.rb
244
db/seeds.rb
@ -1,3 +1,8 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# This file fills the database with some initial data.
|
||||
# Some of them are just some placeholders to prevent having an empty palce when starting fab-manager first.
|
||||
# Other data are required default values, for various settings.
|
||||
|
||||
if StatisticIndex.count.zero?
|
||||
StatisticIndex.create!([
|
||||
@ -86,7 +91,7 @@ Group.create! name: I18n.t('group.admins'), slug: 'admins' unless Group.find_by(
|
||||
|
||||
# Create the default admin if none exists yet
|
||||
if Role.where(name: 'admin').joins(:users).count.zero?
|
||||
admin = User.new(username: 'admin', email: ENV['ADMIN_EMAIL'], password: ENV['ADMIN_PASSWORD'],
|
||||
admin = User.new(username: 'admin', email: ENV.fetch('ADMIN_EMAIL'), password: ENV.fetch('ADMIN_PASSWORD'),
|
||||
password_confirmation: Rails.application.secrets.admin_password, group_id: Group.find_by(slug: 'admins').id,
|
||||
profile_attributes: { first_name: 'admin', last_name: 'admin', phone: '0123456789' },
|
||||
statistic_profile_attributes: { gender: true, birthday: Date.current })
|
||||
@ -111,27 +116,48 @@ end
|
||||
|
||||
if Licence.count.zero?
|
||||
Licence.create!([
|
||||
{ name: 'Attribution (BY)', description: 'Le titulaire des droits autorise toute exploitation de l’œuvre, y compris à' \
|
||||
' des fins commerciales, ainsi que la création d’œuvres dérivées, dont la distribution est également autorisé sans ' \
|
||||
'restriction, à condition de l’attribuer à son l’auteur en citant son nom. Cette licence est recommandée pour la ' \
|
||||
'diffusion et l’utilisation maximale des œuvres.' },
|
||||
{ name: 'Attribution + Pas de modification (BY ND)', description: 'Le titulaire des droits autorise toute utilisation' \
|
||||
' de l’œuvre originale (y compris à des fins commerciales), mais n’autorise pas la création d’œuvres dérivées.' },
|
||||
{ name: "Attribution + Pas d'Utilisation Commerciale + Pas de Modification (BY NC ND)", description: 'Le titulaire ' \
|
||||
'des droits autorise l’utilisation de l’œuvre originale à des fins non commerciales, mais n’autorise pas la ' \
|
||||
'création d’œuvres dérivés.' },
|
||||
{ name: "Attribution + Pas d'Utilisation Commerciale (BY NC)", description: 'Le titulaire des droits autorise ' \
|
||||
'l’exploitation de l’œuvre, ainsi que la création d’œuvres dérivées, à condition qu’il ne s’agisse pas d’une ' \
|
||||
'utilisation commerciale (les utilisations commerciales restant soumises à son autorisation).' },
|
||||
{ name: "Attribution + Pas d'Utilisation Commerciale + Partage dans les mêmes conditions (BY NC SA)", description:
|
||||
'Le titulaire des droits autorise l’exploitation de l’œuvre originale à des fins non commerciales, ainsi que la ' \
|
||||
'création d’œuvres dérivées, à condition qu’elles soient distribuées sous une licence identique à celle qui régit ' \
|
||||
'l’œuvre originale.' },
|
||||
{ name: 'Attribution + Partage dans les mêmes conditions (BY SA)', description: 'Le titulaire des droits autorise ' \
|
||||
'toute utilisation de l’œuvre originale (y compris à des fins commerciales) ainsi que la création d’œuvres dérivées' \
|
||||
', à condition qu’elles soient distribuées sous une licence identique à celle qui régit l’œuvre originale. Cette' \
|
||||
'licence est souvent comparée aux licences « copyleft » des logiciels libres. C’est la licence utilisée par ' \
|
||||
'Wikipedia.' }
|
||||
{
|
||||
name: 'Attribution (BY)',
|
||||
description:
|
||||
'Le titulaire des droits autorise toute exploitation de l’œuvre, y compris à des ' \
|
||||
'fins commerciales, ainsi que la création d’œuvres dérivées, dont la distribution est également autorisé sans ' \
|
||||
'restriction, à condition de l’attribuer à son l’auteur en citant son nom. Cette licence est recommandée pour la ' \
|
||||
'diffusion et l’utilisation maximale des œuvres.'
|
||||
},
|
||||
{
|
||||
name: 'Attribution + Pas de modification (BY ND)',
|
||||
description:
|
||||
'Le titulaire des droits autorise toute utilisation de l’œuvre originale (y compris à des fins commerciales), ' \
|
||||
'mais n’autorise pas la création d’œuvres dérivées.'
|
||||
},
|
||||
{
|
||||
name: "Attribution + Pas d'Utilisation Commerciale + Pas de Modification (BY NC ND)",
|
||||
description:
|
||||
'Le titulaire des droits autorise l’utilisation de l’œuvre originale à des fins non commerciales, ' \
|
||||
'mais n’autorise pas la création d’œuvres dérivés.'
|
||||
},
|
||||
{
|
||||
name: "Attribution + Pas d'Utilisation Commerciale (BY NC)",
|
||||
description:
|
||||
'Le titulaire des droits autorise l’exploitation de l’œuvre, ainsi que la création d’œuvres dérivées, ' \
|
||||
'à condition qu’il ne s’agisse pas d’une utilisation commerciale (les utilisations commerciales ' \
|
||||
'restant soumises à son autorisation).'
|
||||
},
|
||||
{
|
||||
name: "Attribution + Pas d'Utilisation Commerciale + Partage dans les mêmes conditions (BY NC SA)",
|
||||
description:
|
||||
'Le titulaire des droits autorise l’exploitation de l’œuvre originale à des fins non commerciales, ainsi que la ' \
|
||||
'création d’œuvres dérivées, à condition qu’elles soient distribuées sous une licence identique à celle qui ' \
|
||||
'régit l’œuvre originale.'
|
||||
},
|
||||
{
|
||||
name: 'Attribution + Partage dans les mêmes conditions (BY SA)',
|
||||
description:
|
||||
'Le titulaire des droits autorise toute utilisation de l’œuvre originale (y compris à des fins commerciales) ' \
|
||||
'ainsi que la création d’œuvres dérivées, à condition qu’elles soient distribuées sous une licence identique ' \
|
||||
'à celle qui régit l’œuvre originale. Cette licence est souvent comparée aux licences « copyleft » des logiciels ' \
|
||||
'libres. C’est la licence utilisée par Wikipedia.'
|
||||
}
|
||||
])
|
||||
end
|
||||
|
||||
@ -149,75 +175,117 @@ end
|
||||
|
||||
if Training.count.zero?
|
||||
Training.create!([
|
||||
{ name: 'Formation Imprimante 3D', description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do ' \
|
||||
'eiusmod tempor incididunt ut labore et dolore magna aliqua.' },
|
||||
{ name: 'Formation Laser / Vinyle', description: 'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris' \
|
||||
' nisi ut aliquip ex ea commodo consequat.' },
|
||||
{ name: 'Formation Petite fraiseuse numerique', description: 'Duis aute irure dolor in reprehenderit in voluptate ' \
|
||||
'velit esse cillum dolore eu fugiat nulla pariatur.' },
|
||||
{ name: 'Formation Shopbot Grande Fraiseuse', description: 'Excepteur sint occaecat cupidatat non proident, sunt in ' \
|
||||
'culpa qui officia deserunt mollit anim id est laborum.' },
|
||||
{ name: 'Formation logiciel 2D', description: 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ' \
|
||||
'accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi ' \
|
||||
'architecto beatae vitae dicta sunt explicabo.' }
|
||||
{
|
||||
name: 'Formation Imprimante 3D',
|
||||
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do ' \
|
||||
'eiusmod tempor incididunt ut labore et dolore magna aliqua.'
|
||||
},
|
||||
{
|
||||
name: 'Formation Laser / Vinyle',
|
||||
description: 'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris ' \
|
||||
'nisi ut aliquip ex ea commodo consequat.'
|
||||
},
|
||||
{
|
||||
name: 'Formation Petite fraiseuse numerique',
|
||||
description: 'Duis aute irure dolor in reprehenderit in voluptate ' \
|
||||
'velit esse cillum dolore eu fugiat nulla pariatur.'
|
||||
},
|
||||
{
|
||||
name: 'Formation Shopbot Grande Fraiseuse',
|
||||
description: 'Excepteur sint occaecat cupidatat non proident, sunt in ' \
|
||||
'culpa qui officia deserunt mollit anim id est laborum.'
|
||||
},
|
||||
{
|
||||
name: 'Formation logiciel 2D',
|
||||
description: 'Sed ut perspiciatis unde omnis iste natus error sit voluptatem ' \
|
||||
'accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis ' \
|
||||
'et quasi architecto beatae vitae dicta sunt explicabo.'
|
||||
}
|
||||
])
|
||||
|
||||
TrainingsPricing.all.each do |p|
|
||||
p.update_columns(amount: (rand * 50 + 5).floor * 100)
|
||||
p.update(amount: ((rand * 50) + 5).floor * 100)
|
||||
end
|
||||
end
|
||||
|
||||
if Machine.count.zero?
|
||||
Machine.create!([
|
||||
{ name: 'Découpeuse laser', description: "Préparation à l'utilisation de l'EPILOG Legend 36EXT\r\nInformations" \
|
||||
" générales \r\n Pour la découpe, il suffit d'apporter votre fichier vectorisé type illustrator, svg ou dxf" \
|
||||
" avec des \"lignes de coupe\" d'une épaisseur inférieur à 0,01 mm et la machine s'occupera du reste!\r\n La " \
|
||||
'gravure est basée sur le spectre noir et blanc. Les nuances sont obtenues par différentes profondeurs de gravure ' \
|
||||
"correspondant aux niveaux de gris de votre image. Il suffit pour cela d'apporter une image scannée ou un fichier " \
|
||||
"photo en noir et blanc pour pouvoir reproduire celle-ci sur votre support! \r\nQuels types de matériaux pouvons " \
|
||||
"nous graver/découper?\r\n Du bois au tissu, du plexiglass au cuir, cette machine permet de découper et graver " \
|
||||
"la plupart des matériaux sauf les métaux. La gravure est néanmoins possible sur les métaux recouverts d'une couche" \
|
||||
" de peinture ou les aluminiums anodisés. \r\n Concernant l'épaisseur des matériaux découpés, il est " \
|
||||
"préférable de ne pas dépasser 5 mm pour le bois et 6 mm pour le plexiglass.\r\n", spec: "Puissance: 40W\r\nSurface" \
|
||||
" de travail: 914x609 mm \r\nEpaisseur maximale de la matière: 305mm\r\nSource laser: tube laser type CO2\r\n" \
|
||||
'Contrôles de vitesse et de puissance: ces deux paramètres sont ajustables en fonction du matériau (de 1% à 100%) .' \
|
||||
"\r\n", slug: 'decoupeuse-laser' },
|
||||
{ name: 'Découpeuse vinyle', description: "Préparation à l'utilisation de la Roland CAMM-1 GX24\r\nInformations " \
|
||||
"générales \r\n Envie de réaliser un tee shirt personnalisé ? Un sticker à l'effigie votre groupe " \
|
||||
"préféré ? Un masque pour la réalisation d'un circuit imprimé? Pour cela, il suffit simplement de venir avec votre" \
|
||||
" fichier vectorisé (ne pas oublier de vectoriser les textes) type illustrator svg ou dxf.\r\n \r\nMatériaux " \
|
||||
"utilisés:\r\n Cette machine permet de découper principalement du vinyle,vinyle réfléchissant, flex.\r\n",
|
||||
{
|
||||
name: 'Découpeuse laser',
|
||||
description:
|
||||
"Préparation à l'utilisation de l'EPILOG Legend 36EXT\r\nInformations générales \r\n " \
|
||||
"Pour la découpe, il suffit d'apporter votre fichier vectorisé type illustrator, svg ou dxf avec des " \
|
||||
"\"lignes de coupe\" d'une épaisseur inférieur à 0,01 mm et la machine s'occupera du reste!\r\n La gravure " \
|
||||
'est basée sur le spectre noir et blanc. Les nuances sont obtenues par différentes profondeurs de gravure ' \
|
||||
"correspondant aux niveaux de gris de votre image. Il suffit pour cela d'apporter une image scannée ou un " \
|
||||
"fichier photo en noir et blanc pour pouvoir reproduire celle-ci sur votre support! \r\nQuels types de " \
|
||||
"matériaux pouvons nous graver/découper?\r\n Du bois au tissu, du plexiglass au cuir, cette machine " \
|
||||
'permet de découper et graver la plupart des matériaux sauf les métaux. La gravure est néanmoins possible ' \
|
||||
"sur les métaux recouverts d'une couche de peinture ou les aluminiums anodisés. \r\n " \
|
||||
"Concernant l'épaisseur des matériaux découpés, il est préférable de ne pas dépasser 5 mm pour le bois " \
|
||||
"et 6 mm pour le plexiglass.\r\n",
|
||||
spec:
|
||||
"Puissance: 40W\r\nSurface de travail: 914x609 mm \r\n" \
|
||||
"Epaisseur maximale de la matière: 305mm\r\nSource laser: tube laser type CO2\r\nContrôles de vitesse " \
|
||||
"et de puissance: ces deux paramètres sont ajustables en fonction du matériau (de 1% à 100%).\r\n",
|
||||
slug: 'decoupeuse-laser'
|
||||
},
|
||||
{
|
||||
name: 'Découpeuse vinyle',
|
||||
description:
|
||||
"Préparation à l'utilisation de la Roland CAMM-1 GX24\r\nInformations générales \r\n " \
|
||||
"Envie de réaliser un tee shirt personnalisé ? Un sticker à l'effigie votre groupe préféré ? " \
|
||||
"Un masque pour la réalisation d'un circuit imprimé? Pour cela, il suffit simplement de venir avec votre " \
|
||||
"fichier vectorisé (ne pas oublier de vectoriser les textes) type illustrator svg ou dxf.\r\n \r\nMatériaux " \
|
||||
"utilisés:\r\n Cette machine permet de découper principalement du vinyle,vinyle réfléchissant, flex.\r\n",
|
||||
spec: "Largeurs de support acceptées: de 50 mm à 700 mm\r\nVitesse de découpe: 50 cm/sec\r\nRésolution mécanique: " \
|
||||
"0,0125 mm/pas\r\n", slug: 'decoupeuse-vinyle' },
|
||||
{ name: 'Shopbot / Grande fraiseuse', description: "La fraiseuse numérique ShopBot PRS standard\r\nInformations " \
|
||||
"générales\r\nCette machine est un fraiseuse 3 axes idéale pour l'usinage de pièces de grandes dimensions. De la " \
|
||||
"réalisation d'une chaise ou d'un meuble jusqu'à la construction d'une maison ou d'un assemblage immense, le " \
|
||||
"ShopBot ouvre de nombreuses portes à votre imagination! \r\nMatériaux usinables\r\nLes principaux matériaux " \
|
||||
"usinables sont le bois, le plastique, le laiton et bien d'autres.\r\nCette machine n'usine pas les métaux.\r\n",
|
||||
"0,0125 mm/pas\r\n",
|
||||
slug: 'decoupeuse-vinyle'
|
||||
},
|
||||
{
|
||||
name: 'Shopbot / Grande fraiseuse',
|
||||
description:
|
||||
"La fraiseuse numérique ShopBot PRS standard\r\nInformations " \
|
||||
"générales\r\nCette machine est un fraiseuse 3 axes idéale pour l'usinage de pièces de grandes dimensions. De la " \
|
||||
"réalisation d'une chaise ou d'un meuble jusqu'à la construction d'une maison ou d'un assemblage immense, le " \
|
||||
"ShopBot ouvre de nombreuses portes à votre imagination! \r\nMatériaux usinables\r\nLes principaux matériaux " \
|
||||
"usinables sont le bois, le plastique, le laiton et bien d'autres.\r\nCette machine n'usine pas les métaux.\r\n",
|
||||
spec: "Surface maximale de travail: 2440x1220x150 (Z) mm\r\nLogiciel utilisé: Partworks 2D & 3D\r\nRésolution " \
|
||||
"mécanique: 0,015 mm\r\nPrécision de la position: +/- 0,127mm\r\nFormats acceptés: DXF, STL \r\n",
|
||||
slug: 'shopbot-grande-fraiseuse' },
|
||||
{ name: 'Imprimante 3D', description: "L'utimaker est une imprimante 3D low cost utilisant une technologie FFF " \
|
||||
"(Fused Filament Fabrication) avec extrusion thermoplastique.\r\nC'est une machine idéale pour réaliser rapidement " \
|
||||
"des prototypes 3D dans des couleurs différentes.\r\n", spec: "Surface maximale de travail: 210x210x220mm \r\n" \
|
||||
"Résolution méchanique: 0,02 mm \r\nPrécision de position: +/- 0,05 \r\nLogiciel utilisé: Cura\r\nFormats de " \
|
||||
"fichier acceptés: STL \r\nMatériaux utilisés: PLA (en stock).", slug: 'imprimante-3d' },
|
||||
{ name: 'Petite Fraiseuse', description: "La fraiseuse numérique Roland Modela MDX-20\r\nInformations générales" \
|
||||
"\r\nCette machine est utilisée pour l'usinage et le scannage 3D de précision. Elle permet principalement d'usiner" \
|
||||
' des circuits imprimés et des moules de petite taille. Le faible diamètre des fraises utilisées (Ø 0,3 mm à Ø 6mm' \
|
||||
") induit que certains temps d'usinages peuvent êtres long (> 12h), c'est pourquoi cette fraiseuse peut être " \
|
||||
"laissée en autonomie toute une nuit afin d'obtenir le plus précis des usinages au FabLab.\r\nMatériaux usinables:" \
|
||||
"\r\nLes principaux matériaux usinables sont le bois, plâtre, résine, cire usinable, cuivre.\r\n",
|
||||
"mécanique: 0,015 mm\r\nPrécision de la position: +/- 0,127mm\r\nFormats acceptés: DXF, STL \r\n",
|
||||
slug: 'shopbot-grande-fraiseuse'
|
||||
},
|
||||
{
|
||||
name: 'Imprimante 3D',
|
||||
description:
|
||||
"L'utimaker est une imprimante 3D low cost utilisant une technologie FFF " \
|
||||
"(Fused Filament Fabrication) avec extrusion thermoplastique.\r\nC'est une machine idéale pour réaliser " \
|
||||
"rapidement des prototypes 3D dans des couleurs différentes.\r\n",
|
||||
spec: "Surface maximale de travail: 210x210x220mm \r\n" \
|
||||
"Résolution méchanique: 0,02 mm \r\nPrécision de position: +/- 0,05 \r\nLogiciel utilisé: Cura\r\nFormats de " \
|
||||
"fichier acceptés: STL \r\nMatériaux utilisés: PLA (en stock).",
|
||||
slug: 'imprimante-3d'
|
||||
},
|
||||
{
|
||||
name: 'Petite Fraiseuse',
|
||||
description:
|
||||
"La fraiseuse numérique Roland Modela MDX-20\r\nInformations générales\r\nCette machine est utilisée " \
|
||||
"pour l'usinage et le scannage 3D de précision. Elle permet principalement d'usiner des circuits imprimés " \
|
||||
'et des moules de petite taille. Le faible diamètre des fraises utilisées (Ø 0,3 mm à Ø 6mm) induit que ' \
|
||||
"certains temps d'usinages peuvent êtres long (> 12h), c'est pourquoi cette fraiseuse peut être laissée en " \
|
||||
"autonomie toute une nuit afin d'obtenir le plus précis des usinages au FabLab.\r\nMatériaux usinables:" \
|
||||
"\r\nLes principaux matériaux usinables sont le bois, plâtre, résine, cire usinable, cuivre.\r\n",
|
||||
spec: "Taille du plateau X/Y : 220 mm x 160 mm\r\nVolume maximal de travail: 203,2 mm (X), 152,4 mm (Y), 60,5 mm " \
|
||||
"(Z)\r\nPrécision usinage: 0,00625 mm\r\nPrécision scannage: réglable de 0,05 à 5 mm (axes X,Y) et 0,025 mm (axe Z)" \
|
||||
"\r\nVitesse d'analyse (scannage): 4-15 mm/sec\r\n \r\n \r\nLogiciel utilisé pour le fraisage: Roland Modela player" \
|
||||
" 4 \r\nLogiciel utilisé pour l'usinage de circuits imprimés: Cad.py (linux)\r\nFormats acceptés: STL,PNG 3D\r\n" \
|
||||
"Format d'exportation des données scannées: DXF, VRML, STL, 3DMF, IGES, Grayscale, Point Group et BMP\r\n",
|
||||
slug: 'petite-fraiseuse' }
|
||||
"(Z)\r\nPrécision usinage: 0,00625 mm\r\nPrécision scannage: réglable de 0,05 à 5 mm (axes X,Y) et 0,025 mm " \
|
||||
"(axe Z)\r\nVitesse d'analyse (scannage): 4-15 mm/sec\r\n \r\n \r\nLogiciel utilisé pour le fraisage: " \
|
||||
"Roland Modela player 4 \r\nLogiciel utilisé pour l'usinage de circuits imprimés: Cad.py (linux)\r\n" \
|
||||
"Formats acceptés: STL,PNG 3D\r\nFormat d'exportation des données scannées: DXF, VRML, STL, 3DMF, IGES, " \
|
||||
"Grayscale, Point Group et BMP\r\n",
|
||||
slug: 'petite-fraiseuse'
|
||||
}
|
||||
])
|
||||
|
||||
Price.all.each do |p|
|
||||
p.update_columns(amount: (rand * 50 + 5).floor * 100)
|
||||
p.update(amount: ((rand * 50) + 5).floor * 100)
|
||||
end
|
||||
end
|
||||
|
||||
@ -273,19 +341,19 @@ Setting.set('twitter_name', 'Fab_Manager') unless Setting.find_by(name: 'twitter
|
||||
|
||||
unless Setting.find_by(name: 'machine_explications_alert').try(:value)
|
||||
setting = Setting.find_or_initialize_by(name: 'machine_explications_alert')
|
||||
setting.value = 'Tout achat de créneau machine est définitif. Aucune' \
|
||||
' annulation ne pourra être effectuée, néanmoins au plus tard 24h avant le créneau fixé, vous pouvez en' \
|
||||
" modifier la date et l'horaire à votre convenance et en fonction du calendrier proposé. Passé ce délais," \
|
||||
' aucun changement ne pourra être effectué.'
|
||||
setting.value = 'Tout achat de créneau machine est définitif. Aucune ' \
|
||||
'annulation ne pourra être effectuée, néanmoins au plus tard 24h avant le créneau fixé, vous pouvez en ' \
|
||||
"modifier la date et l'horaire à votre convenance et en fonction du calendrier proposé. Passé ce délais, " \
|
||||
'aucun changement ne pourra être effectué.'
|
||||
setting.save
|
||||
end
|
||||
|
||||
unless Setting.find_by(name: 'training_explications_alert').try(:value)
|
||||
setting = Setting.find_or_initialize_by(name: 'training_explications_alert')
|
||||
setting.value = 'Toute réservation de formation est définitive.' \
|
||||
' Aucune annulation ne pourra être effectuée, néanmoins au plus tard 24h avant le créneau fixé, vous pouvez' \
|
||||
" en modifier la date et l'horaire à votre convenance et en fonction du calendrier proposé. Passé ce délais," \
|
||||
' aucun changement ne pourra être effectué.'
|
||||
setting.value = 'Toute réservation de formation est définitive. ' \
|
||||
'Aucune annulation ne pourra être effectuée, néanmoins au plus tard 24h avant le créneau fixé, vous pouvez ' \
|
||||
"en modifier la date et l'horaire à votre convenance et en fonction du calendrier proposé. Passé ce délais, " \
|
||||
'aucun changement ne pourra être effectué.'
|
||||
setting.save
|
||||
end
|
||||
|
||||
@ -633,8 +701,8 @@ Stylesheet.build_home!
|
||||
|
||||
unless Setting.find_by(name: 'training_information_message').try(:value)
|
||||
setting = Setting.find_or_initialize_by(name: 'training_information_message')
|
||||
setting.value = "Avant de réserver une formation, nous vous conseillons de consulter nos offres d'abonnement qui" \
|
||||
' proposent des conditions avantageuses sur le prix des formations et les créneaux machines.'
|
||||
setting.value = "Avant de réserver une formation, nous vous conseillons de consulter nos offres d'abonnement qui " \
|
||||
'proposent des conditions avantageuses sur le prix des formations et les créneaux machines.'
|
||||
setting.save
|
||||
end
|
||||
|
||||
@ -919,6 +987,8 @@ Setting.set('extended_prices_in_same_day', false) unless Setting.find_by(name: '
|
||||
|
||||
Setting.set('show_username_in_admin_list', false) unless Setting.find_by(name: 'show_username_in_admin_list').try(:value)
|
||||
|
||||
Setting.set('store_module', false) unless Setting.find_by(name: 'store_module').try(:value)
|
||||
|
||||
if StatisticCustomAggregation.count.zero?
|
||||
# available reservations hours for machines
|
||||
machine_hours = StatisticType.find_by(key: 'hour', statistic_index_id: 2)
|
||||
|
Loading…
x
Reference in New Issue
Block a user